diff options
-rw-r--r-- | epan/dissectors/packet-ipmi-app.c | 1493 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-bridge.c | 149 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-chassis.c | 1064 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-picmg.c | 2315 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-pps.c | 104 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-se.c | 3665 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-session.c | 333 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-storage.c | 1117 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-transport.c | 3197 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi-update.c | 53 | ||||
-rw-r--r-- | epan/dissectors/packet-ipmi.h | 186 |
11 files changed, 13676 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ipmi-app.c b/epan/dissectors/packet-ipmi-app.c new file mode 100644 index 0000000000..589b36bb32 --- /dev/null +++ b/epan/dissectors/packet-ipmi-app.c @@ -0,0 +1,1493 @@ +/* packet-ipmi-app.c + * Sub-dissectors for IPMI messages (netFn=Application) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <string.h> + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static gint ett_ipmi_app_01_byte2 = -1; +static gint ett_ipmi_app_01_byte3 = -1; +static gint ett_ipmi_app_01_byte6 = -1; + +static gint ett_ipmi_app_04_byte2 = -1; + +static gint ett_ipmi_app_06_syspwr = -1; +static gint ett_ipmi_app_06_devpwr = -1; + +static gint ett_ipmi_app_07_syspwr = -1; +static gint ett_ipmi_app_07_devpwr = -1; + +static gint ett_ipmi_app_24_timer_use = -1; +static gint ett_ipmi_app_24_timer_action = -1; +static gint ett_ipmi_app_24_expiration_flags = -1; + +static gint ett_ipmi_app_25_timer_use = -1; +static gint ett_ipmi_app_25_timer_action = -1; +static gint ett_ipmi_app_25_expiration_flags = -1; + +static gint ett_ipmi_app_2e_byte1 = -1; +static gint ett_ipmi_app_2f_byte1 = -1; +static gint ett_ipmi_app_30_byte1 = -1; +static gint ett_ipmi_app_31_byte1 = -1; +static gint ett_ipmi_app_32_rq_byte1 = -1; +static gint ett_ipmi_app_32_rq_byte2 = -1; +static gint ett_ipmi_app_32_rs_byte1 = -1; +static gint ett_ipmi_app_32_rs_byte2 = -1; +static gint ett_ipmi_app_34_byte1 = -1; +static gint ett_ipmi_app_34_msg = -1; + +static gint ett_ipmi_app_38_rq_byte1 = -1; +static gint ett_ipmi_app_38_rq_byte2 = -1; +static gint ett_ipmi_app_38_rs_byte1 = -1; +static gint ett_ipmi_app_38_rs_byte2 = -1; +static gint ett_ipmi_app_38_rs_byte3 = -1; +static gint ett_ipmi_app_38_rs_byte4 = -1; + +static gint ett_ipmi_app_39_byte1 = -1; + +static gint ett_ipmi_app_3a_rq_byte1 = -1; +static gint ett_ipmi_app_3a_rq_byte2 = -1; +static gint ett_ipmi_app_3a_rs_byte1 = -1; +static gint ett_ipmi_app_3a_rs_byte10 = -1; + +static gint ett_ipmi_app_3b_rq_byte1 = -1; +static gint ett_ipmi_app_3b_rs_byte1 = -1; + +static gint hf_ipmi_app_01_dev_id = -1; +static gint hf_ipmi_app_01_dev_prov_sdr = -1; +static gint hf_ipmi_app_01_dev_rev = -1; +static gint hf_ipmi_app_01_dev_avail = -1; +static gint hf_ipmi_app_01_fw_rev_maj = -1; +static gint hf_ipmi_app_01_fw_rev_min = -1; +static gint hf_ipmi_app_01_ipmi_version = -1; +static gint hf_ipmi_app_01_ipmi_ads_chassis = -1; +static gint hf_ipmi_app_01_ipmi_ads_bridge = -1; +static gint hf_ipmi_app_01_ipmi_ads_ipmb_ev_gen = -1; +static gint hf_ipmi_app_01_ipmi_ads_ipmb_ev_recv = -1; +static gint hf_ipmi_app_01_ipmi_ads_fru = -1; +static gint hf_ipmi_app_01_ipmi_ads_sel = -1; +static gint hf_ipmi_app_01_ipmi_ads_sdr = -1; +static gint hf_ipmi_app_01_ipmi_ads_sensor = -1; +static gint hf_ipmi_app_01_manufacturer = -1; +static gint hf_ipmi_app_01_product = -1; +static gint hf_ipmi_app_01_fw_aux = -1; + +static gint hf_ipmi_app_04_result = -1; +static gint hf_ipmi_app_04_fail = -1; +static gint hf_ipmi_app_04_fail_sel = -1; +static gint hf_ipmi_app_04_fail_sdr = -1; +static gint hf_ipmi_app_04_fail_bmc_fru = -1; +static gint hf_ipmi_app_04_fail_ipmb_sig = -1; +static gint hf_ipmi_app_04_fail_sdr_empty = -1; +static gint hf_ipmi_app_04_fail_iua = -1; +static gint hf_ipmi_app_04_fail_bb_fw = -1; +static gint hf_ipmi_app_04_fail_oper_fw = -1; + +static gint hf_ipmi_app_05_devspec = -1; + +static gint hf_ipmi_app_06_syspwr_set = -1; +static gint hf_ipmi_app_06_syspwr_enum = -1; +static gint hf_ipmi_app_06_devpwr_set = -1; +static gint hf_ipmi_app_06_devpwr_enum = -1; + +static gint hf_ipmi_app_07_syspwr_enum = -1; +static gint hf_ipmi_app_07_devpwr_enum = -1; + +static gint hf_ipmi_app_08_guid = -1; + +static gint hf_ipmi_app_24_timer_use_dont_log = -1; +static gint hf_ipmi_app_24_timer_use_dont_stop = -1; +static gint hf_ipmi_app_24_timer_use_timer_use = -1; +static gint hf_ipmi_app_24_timer_action_interrupt = -1; +static gint hf_ipmi_app_24_timer_action_timeout_action = -1; +static gint hf_ipmi_app_24_pretimeout = -1; +static gint hf_ipmi_app_24_expiration_flags_oem = -1; +static gint hf_ipmi_app_24_expiration_flags_smsos = -1; +static gint hf_ipmi_app_24_expiration_flags_osload = -1; +static gint hf_ipmi_app_24_expiration_flags_biospost = -1; +static gint hf_ipmi_app_24_expiration_flags_biosfrb2 = -1; +static gint hf_ipmi_app_24_initial_countdown = -1; + +static gint hf_ipmi_app_25_timer_use_dont_log = -1; +static gint hf_ipmi_app_25_timer_use_started = -1; +static gint hf_ipmi_app_25_timer_use_timer_use = -1; +static gint hf_ipmi_app_25_timer_action_interrupt = -1; +static gint hf_ipmi_app_25_timer_action_timeout_action = -1; +static gint hf_ipmi_app_25_pretimeout = -1; +static gint hf_ipmi_app_25_expiration_flags_oem = -1; +static gint hf_ipmi_app_25_expiration_flags_smsos = -1; +static gint hf_ipmi_app_25_expiration_flags_osload = -1; +static gint hf_ipmi_app_25_expiration_flags_biospost = -1; +static gint hf_ipmi_app_25_expiration_flags_biosfrb2 = -1; +static gint hf_ipmi_app_25_initial_countdown = -1; +static gint hf_ipmi_app_25_present_countdown = -1; + +static gint hf_ipmi_app_2e_byte1_oem2 = -1; +static gint hf_ipmi_app_2e_byte1_oem1 = -1; +static gint hf_ipmi_app_2e_byte1_oem0 = -1; +static gint hf_ipmi_app_2e_byte1_sel = -1; +static gint hf_ipmi_app_2e_byte1_emb = -1; +static gint hf_ipmi_app_2e_byte1_emb_full_intr = -1; +static gint hf_ipmi_app_2e_byte1_rmq_intr = -1; + +static gint hf_ipmi_app_2f_byte1_oem2 = -1; +static gint hf_ipmi_app_2f_byte1_oem1 = -1; +static gint hf_ipmi_app_2f_byte1_oem0 = -1; +static gint hf_ipmi_app_2f_byte1_sel = -1; +static gint hf_ipmi_app_2f_byte1_emb = -1; +static gint hf_ipmi_app_2f_byte1_emb_full_intr = -1; +static gint hf_ipmi_app_2f_byte1_rmq_intr = -1; + +static gint hf_ipmi_app_30_byte1_oem2 = -1; +static gint hf_ipmi_app_30_byte1_oem1 = -1; +static gint hf_ipmi_app_30_byte1_oem0 = -1; +static gint hf_ipmi_app_30_byte1_wd_pretimeout = -1; +static gint hf_ipmi_app_30_byte1_emb = -1; +static gint hf_ipmi_app_30_byte1_rmq = -1; + +static gint hf_ipmi_app_31_byte1_oem2 = -1; +static gint hf_ipmi_app_31_byte1_oem1 = -1; +static gint hf_ipmi_app_31_byte1_oem0 = -1; +static gint hf_ipmi_app_31_byte1_wd_pretimeout = -1; +static gint hf_ipmi_app_31_byte1_emb = -1; +static gint hf_ipmi_app_31_byte1_rmq = -1; + +static gint hf_ipmi_app_32_rq_chno = -1; +static gint hf_ipmi_app_32_rq_state = -1; +static gint hf_ipmi_app_32_rs_chno = -1; +static gint hf_ipmi_app_32_rs_state = -1; + +static gint hf_ipmi_app_34_track = -1; +static gint hf_ipmi_app_34_encrypt = -1; +static gint hf_ipmi_app_34_auth = -1; +static gint hf_ipmi_app_34_chan = -1; + +static gint hf_ipmi_app_38_rq_ipmi20 = -1; +static gint hf_ipmi_app_38_rq_chan = -1; +static gint hf_ipmi_app_38_rq_priv = -1; +static gint hf_ipmi_app_38_rs_chan = -1; +static gint hf_ipmi_app_38_rs_ipmi20 = -1; +static gint hf_ipmi_app_38_rs_auth_oem = -1; +static gint hf_ipmi_app_38_rs_auth_straight = -1; +static gint hf_ipmi_app_38_rs_auth_md5 = -1; +static gint hf_ipmi_app_38_rs_auth_md2 = -1; +static gint hf_ipmi_app_38_rs_auth_none = -1; +static gint hf_ipmi_app_38_rs_kg = -1; +static gint hf_ipmi_app_38_rs_permsg = -1; +static gint hf_ipmi_app_38_rs_userauth = -1; +static gint hf_ipmi_app_38_rs_user_nonnull = -1; +static gint hf_ipmi_app_38_rs_user_null = -1; +static gint hf_ipmi_app_38_rs_user_anon = -1; +static gint hf_ipmi_app_38_rs_ipmi20_conn = -1; +static gint hf_ipmi_app_38_rs_ipmi15_conn = -1; +static gint hf_ipmi_app_38_rs_oem_iana = -1; +static gint hf_ipmi_app_38_rs_oem_aux = -1; + +static gint hf_ipmi_app_39_authtype = -1; +static gint hf_ipmi_app_39_user = -1; +static gint hf_ipmi_app_39_temp_session = -1; +static gint hf_ipmi_app_39_challenge = -1; + +static gint hf_ipmi_app_3a_authtype = -1; +static gint hf_ipmi_app_3a_privlevel = -1; +static gint hf_ipmi_app_3a_authcode = -1; +static gint hf_ipmi_app_3a_outbound_seq = -1; +static gint hf_ipmi_app_3a_authtype_session = -1; +static gint hf_ipmi_app_3a_session_id = -1; +static gint hf_ipmi_app_3a_inbound_seq = -1; +static gint hf_ipmi_app_3a_maxpriv_session = -1; + +static gint hf_ipmi_app_3b_req_priv = -1; +static gint hf_ipmi_app_3b_new_priv = -1; + +static gint hf_ipmi_app_3c_session_id = -1; +static gint hf_ipmi_app_3c_session_handle = -1; + +static const struct true_false_string tfs_01_dev_avail = { + "Device firmware, SDR Repository update or self-initialization in progress", + "Normal operation" +}; + +static const value_string vals_04_result[] = { + { 0x55, "No error. All Self Tests Passed" }, + { 0x56, "Self Test function not implemented in this controller" }, + { 0x57, "Corrupted or inaccesible data or devices" }, + { 0x58, "Fatal hardware error" }, + { 0xff, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_04_fail_unknown = { + "Test failed", + "Unknown" +}; + +static const struct true_false_string tfs_06_pwr = { + "Set", + "Do not change" +}; + +static const value_string vals_06_syspwr[] = { + { 0x00, "Set S0 / G0" }, + { 0x01, "Set S1" }, + { 0x02, "Set S2" }, + { 0x03, "Set S3" }, + { 0x04, "Set S4" }, + { 0x05, "Set S5 / G2" }, + { 0x06, "Set S4/S5" }, + { 0x07, "Set G3" }, + { 0x08, "Sleeping" }, + { 0x09, "G1 sleping" }, + { 0x0a, "Set override" }, + { 0x20, "Set Legacy On" }, + { 0x21, "Set Legacy Off" }, + { 0x2a, "Set unknown" }, + { 0x7f, "No change" }, + { 0, NULL } +}; + +static const value_string vals_06_devpwr[] = { + { 0x00, "Set D0" }, + { 0x01, "Set D1" }, + { 0x02, "Set D2" }, + { 0x03, "Set D3" }, + { 0x2a, "Set unknown" }, + { 0x7f, "No change" }, + { 0, NULL } +}; + +static const value_string vals_07_syspwr[] = { + { 0x00, "S0 / G0" }, + { 0x01, "S1" }, + { 0x02, "S2" }, + { 0x03, "S3" }, + { 0x04, "S4" }, + { 0x05, "S5 / G2" }, + { 0x06, "S4/S5" }, + { 0x07, "G3" }, + { 0x08, "Sleeping" }, + { 0x09, "G1 sleping" }, + { 0x0a, "Override" }, + { 0x20, "Legacy On" }, + { 0x21, "Legacy Off" }, + { 0x2a, "unknown" }, + { 0, NULL } +}; + +static const value_string vals_07_devpwr[] = { + { 0x00, "D0" }, + { 0x01, "D1" }, + { 0x02, "D2" }, + { 0x03, "D3" }, + { 0x2a, "unknown" }, + { 0, NULL } +}; + +static const value_string vals_24_timer_use[] = { + { 0x00, "reserved" }, + { 0x01, "BIOS FRB2" }, + { 0x02, "BIOS/POST" }, + { 0x03, "OS Load" }, + { 0x04, "SMS/OS" }, + { 0x05, "OEM" }, + { 0x06, "reserved" }, + { 0x07, "reserved" }, + + { 0, NULL } +}; + +static const value_string vals_24_timer_action_interrupt[] = { + { 0x00, "none" }, + { 0x01, "SMI" }, + { 0x02, "NMI / Diagnostic interrupt" }, + { 0x03, "Messaging interrupt" }, + { 0x04, "reserved" }, + { 0x05, "reserved" }, + { 0x06, "reserved" }, + { 0x07, "reserved" }, + + { 0, NULL } +}; + +static const value_string vals_24_timer_action_timeout[] = { + { 0x00, "no action" }, + { 0x01, "Hard Reset" }, + { 0x02, "Power Down" }, + { 0x03, "Power Cycle" }, + { 0x04, "reserved" }, + { 0x05, "reserved" }, + { 0x06, "reserved" }, + { 0x07, "reserved" }, + + { 0, NULL } +}; + +static const struct true_false_string tfs_24_exp_flags = { + "clear timer use expiration bit", + "leave alone" +}; + +static const struct true_false_string tfs_2e_enable = { "Enable", "Disable" }; +static const struct true_false_string tfs_2f_enabled = { "Enabled", "Disabled" }; + +static const struct true_false_string tfs_30_clear = { + "clear", + "leave alone" +}; + +static const value_string vals_32_state[] = { + { 0x00, "Disable channel" }, + { 0x01, "Enable channel" }, + { 0x02, "Get channel enable/disable state" }, + { 0x03, "Reserved" }, + + { 0, NULL } +}; + +static const struct true_false_string tfs_32_state = { + "Channel enabled", + "Channel disabled" +}; + +static const value_string vals_34_track[] = { + { 0x00, "No tracking" }, + { 0x01, "Track Request" }, + { 0x02, "Send Raw" }, + { 0, NULL } +}; + +static const value_string vals_38_ipmi20[] = { + { 0x00, "Backward compatible with IPMI 1.5" }, + { 0x01, "IPMI v2.0+ extended data" }, + { 0, NULL } +}; + +static const value_string vals_XX_priv[] = { + { 0x00, "None / No change" }, + { 0x01, "Callback" }, + { 0x02, "User" }, + { 0x03, "Operator" }, + { 0x04, "Administrator" }, + { 0x05, "OEM Proprietary" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_38_supp = { "Supported", "Not supported" }; +static const struct true_false_string tfs_38_kg = { "Set to non-zero", "Set to default (0)" }; + +static const value_string vals_XX_auth[] = { + { 0x00, "None" }, + { 0x01, "MD2" }, + { 0x02, "MD5" }, + { 0x04, "straight password" }, + { 0x05, "OEM" }, + { 0, NULL } +}; + + +/* Get Device ID. + */ +static void +rs01(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_app_01_dev_prov_sdr, &hf_ipmi_app_01_dev_rev, NULL }; + static const gint *byte3[] = { &hf_ipmi_app_01_dev_avail, &hf_ipmi_app_01_fw_rev_maj, NULL }; + static const gint *byte6[] = { &hf_ipmi_app_01_ipmi_ads_chassis, &hf_ipmi_app_01_ipmi_ads_bridge, + &hf_ipmi_app_01_ipmi_ads_ipmb_ev_gen, &hf_ipmi_app_01_ipmi_ads_ipmb_ev_recv, + &hf_ipmi_app_01_ipmi_ads_fru, &hf_ipmi_app_01_ipmi_ads_sel, &hf_ipmi_app_01_ipmi_ads_sdr, + &hf_ipmi_app_01_ipmi_ads_sensor, NULL }; + size_t len; + + len = tvb_length(tvb); + + proto_tree_add_item(tree, hf_ipmi_app_01_dev_id, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_01_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_app_01_byte3, byte3, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_01_fw_rev_min, tvb, 3, 1, TRUE); + + proto_tree_add_item(tree, hf_ipmi_app_01_ipmi_version, tvb, 4, 1, TRUE); + + proto_tree_add_bitmask_text(tree, tvb, 5, 1, "Additional device support: ", "None", + ett_ipmi_app_01_byte6, byte6, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_01_manufacturer, tvb, 6, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_01_product, tvb, 9, 2, TRUE); + if (len > 11) { + /* IPMI states that Aux Revision should be displayed in MSB order */ + proto_tree_add_item(tree, hf_ipmi_app_01_fw_aux, tvb, 11, 4, FALSE); + } +} + +/* Get Self Test Results. + */ +static void +rs04(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_app_04_fail_sel, &hf_ipmi_app_04_fail_sdr, + &hf_ipmi_app_04_fail_bmc_fru, &hf_ipmi_app_04_fail_ipmb_sig, &hf_ipmi_app_04_fail_sdr_empty, + &hf_ipmi_app_04_fail_iua, &hf_ipmi_app_04_fail_bb_fw, &hf_ipmi_app_04_fail_oper_fw, NULL }; + int res, fail; + + res = tvb_get_guint8(tvb, 0); + fail = tvb_get_guint8(tvb, 1); + + proto_tree_add_uint_format(tree, hf_ipmi_app_04_result, tvb, 0, 1, + res, "Self test result: %s (0x%02x)", + val_to_str(res, vals_04_result, "Device-specific internal failure"), + res); + + if (res == 0x55 || res == 0x56 || res == 0xff) { + proto_tree_add_uint_format_value(tree, hf_ipmi_app_04_fail, tvb, 1, 1, + fail, "0x%02x (must be 0x00)", + fail); + return; + } + + if (res != 0x57) { + proto_tree_add_uint_format_value(tree, hf_ipmi_app_04_fail, tvb, 1, 1, + fail, "0x%02x (device-specific)", + fail); + return; + } + + proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_app_04_fail, ett_ipmi_app_04_byte2, byte2, TRUE); +} + +/* Manufacturing Test On. + */ +static void +rq05(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_app_05_devspec, tvb, 0, tvb_length(tvb), TRUE); +} + +/* Set ACPI Power State. + */ +static void +rq06(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_06_syspwr_set, &hf_ipmi_app_06_syspwr_enum, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_06_devpwr_set, &hf_ipmi_app_06_devpwr_enum, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "ACPI System Power State: ", NULL, + ett_ipmi_app_06_syspwr, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "ACPI Device Power State: ", NULL, + ett_ipmi_app_06_devpwr, byte2, TRUE, 0); +} + +/* Get ACPI Power State. + */ +static void +rs07(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_07_syspwr_enum, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_07_devpwr_enum, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "ACPI System Power State: ", NULL, + ett_ipmi_app_07_syspwr, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "ACPI Device Power State: ", NULL, + ett_ipmi_app_07_devpwr, byte2, TRUE, 0); +} + +/* Get Device GUID. + */ +static void +rs08(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_guid(tree, hf_ipmi_app_08_guid, tvb, 0); +} + +/* Reset Watchdog Timer. + */ +static const value_string cc22[] = { + { 0x80, "Attempt to start un-initialized watchdog" }, + { 0, NULL } +}; + +/* Set Watchdog Timer. + */ +static void +rq24(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_24_timer_use_dont_log, + &hf_ipmi_app_24_timer_use_dont_stop, &hf_ipmi_app_24_timer_use_timer_use, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_24_timer_action_interrupt, + &hf_ipmi_app_24_timer_action_timeout_action, NULL }; + static const gint *byte4[] = { &hf_ipmi_app_24_expiration_flags_oem, + &hf_ipmi_app_24_expiration_flags_smsos, &hf_ipmi_app_24_expiration_flags_osload, + &hf_ipmi_app_24_expiration_flags_biospost, &hf_ipmi_app_24_expiration_flags_biosfrb2, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Timer Use: ", NULL, ett_ipmi_app_24_timer_use, + byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_24_timer_action, + byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_24_pretimeout, tvb, 2, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Timer Use Expiration flags clear: ", "None", + ett_ipmi_app_24_expiration_flags, byte4, TRUE, BMT_NO_TFS); + proto_tree_add_item(tree, hf_ipmi_app_24_initial_countdown, tvb, 4, 2, TRUE); +} + +/* Get Watchdog Timer. + */ +static void +rs25(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_25_timer_use_dont_log, + &hf_ipmi_app_25_timer_use_started, &hf_ipmi_app_25_timer_use_timer_use, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_25_timer_action_interrupt, + &hf_ipmi_app_25_timer_action_timeout_action, NULL }; + static const gint *byte4[] = { &hf_ipmi_app_25_expiration_flags_oem, &hf_ipmi_app_25_expiration_flags_smsos, + &hf_ipmi_app_25_expiration_flags_osload, &hf_ipmi_app_25_expiration_flags_biospost, + &hf_ipmi_app_25_expiration_flags_biosfrb2, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Timer Use: ", NULL, ett_ipmi_app_25_timer_use, + byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_25_timer_action, + byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_25_pretimeout, tvb, 2, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Timer Use Expiration flags: ", "None", + ett_ipmi_app_25_expiration_flags, byte4, TRUE, BMT_NO_TFS); + proto_tree_add_item(tree, hf_ipmi_app_25_initial_countdown, tvb, 4, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_25_present_countdown, tvb, 6, 2, TRUE); +} + +/* Set BMC Global Enables. + */ +static void +rq2e(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_2e_byte1_oem2, &hf_ipmi_app_2e_byte1_oem1, + &hf_ipmi_app_2e_byte1_oem0, &hf_ipmi_app_2e_byte1_sel, &hf_ipmi_app_2e_byte1_emb, + &hf_ipmi_app_2e_byte1_emb_full_intr, &hf_ipmi_app_2e_byte1_rmq_intr, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Enables: ", "None", ett_ipmi_app_2e_byte1, + byte1, TRUE, BMT_NO_TFS); +} + +/* Get BMC Global Enables. + */ +static void +rs2f(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_2f_byte1_oem2, &hf_ipmi_app_2f_byte1_oem1, + &hf_ipmi_app_2f_byte1_oem0, &hf_ipmi_app_2f_byte1_sel, &hf_ipmi_app_2f_byte1_emb, + &hf_ipmi_app_2f_byte1_emb_full_intr, &hf_ipmi_app_2f_byte1_rmq_intr, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Enables: ", "None", ett_ipmi_app_2f_byte1, + byte1, TRUE, BMT_NO_TFS); +} + +/* Clear Message Flags. + */ +static void +rq30(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_30_byte1_oem2, &hf_ipmi_app_30_byte1_oem1, + &hf_ipmi_app_30_byte1_oem0, &hf_ipmi_app_30_byte1_wd_pretimeout, + &hf_ipmi_app_30_byte1_emb, &hf_ipmi_app_30_byte1_rmq, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Clear Message Flags: ", "None", + ett_ipmi_app_30_byte1, byte1, TRUE, BMT_NO_TFS); +} + +/* Get Message Flags. + */ +static void +rs31(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_31_byte1_oem2, &hf_ipmi_app_31_byte1_oem1, + &hf_ipmi_app_31_byte1_oem0, &hf_ipmi_app_31_byte1_wd_pretimeout, + &hf_ipmi_app_31_byte1_emb, &hf_ipmi_app_31_byte1_rmq, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Flags: ", "None", + ett_ipmi_app_31_byte1, byte1, TRUE, BMT_NO_TFS); +} + +/* Enable Message Channel Receive. + */ +static void +rq32(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_32_rq_chno, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_32_rq_state, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_app_32_rq_byte1, + byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_32_rq_byte2, + byte2, TRUE, 0); +} + +static void +rs32(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_32_rs_chno, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_32_rs_state, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_app_32_rs_byte1, + byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_32_rs_byte2, + byte2, TRUE, 0); +} + +/* Get Message + */ +static const value_string cc33[] = { + { 0x80, "Data not available (queue/buffer empty)" }, + { 0, NULL } +}; + +/* Send Message + */ +static void +rq34(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_34_track, &hf_ipmi_app_34_encrypt, + &hf_ipmi_app_34_auth, &hf_ipmi_app_34_chan, NULL }; + ipmi_dissect_format_t dfmt; + proto_tree *s_tree; + proto_item *ti; + tvbuff_t *next; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_34_byte1, byte1, TRUE, 0); + + next = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + ti = proto_tree_add_text(tree, next, 0, tvb_length(next), "Message"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_app_34_msg); + + memset(&dfmt, 0, sizeof(dfmt)); + dfmt.flags = ipmi_guess_dissect_flags(next); + dfmt.arg = ipmi_current_hdr; + dfmt.getmoreheaders = ipmi_sendmsg_getheaders; + dfmt.whichresponse = ipmi_sendmsg_whichresponse; + dfmt.otheridx = ipmi_sendmsg_otheridx; + ipmi_do_dissect(next, s_tree, &dfmt); + proto_item_set_text(ti, "%s", dfmt.info); +} + +static void +rs34(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_dissect_format_t dfmt; + proto_tree *s_tree; + proto_item *ti; + + ti = proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "Message"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_app_34_msg); + + if (tvb_length(tvb)) { + memset(&dfmt, 0, sizeof(dfmt)); + dfmt.flags = ipmi_guess_dissect_flags(tvb); + ipmi_do_dissect(tvb, s_tree, &dfmt); + proto_item_set_text(ti, "%s", dfmt.info); + } +} + +static const value_string cc34[] = { + { 0x80, "Invalid Session Handle" }, + { 0x81, "Lost Arbitration" }, + { 0x82, "Bus Error" }, + { 0x83, "NAK on Write" }, + { 0, NULL } +}; + +/* Read Event Message Buffer + */ +static const value_string cc35[] = { + { 0x80, "Data not available (queue/buffer empty)" }, + { 0, NULL } +}; + +/* Get Channel Authentication Capabilities + */ +static void +rq38(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_38_rq_ipmi20, &hf_ipmi_app_38_rq_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_38_rq_priv, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_app_38_rq_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_38_rq_byte2, byte2, TRUE, 0); +} + +static void +rs38(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_38_rs_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_38_rs_ipmi20, &hf_ipmi_app_38_rs_auth_oem, + &hf_ipmi_app_38_rs_auth_straight, &hf_ipmi_app_38_rs_auth_md5, &hf_ipmi_app_38_rs_auth_md2, + &hf_ipmi_app_38_rs_auth_none, NULL }; + static const gint *byte3[] = { &hf_ipmi_app_38_rs_kg, &hf_ipmi_app_38_rs_permsg, &hf_ipmi_app_38_rs_userauth, + &hf_ipmi_app_38_rs_user_nonnull, &hf_ipmi_app_38_rs_user_null, &hf_ipmi_app_38_rs_user_anon, NULL }; + static const gint *byte4[] = { &hf_ipmi_app_38_rs_ipmi20_conn, &hf_ipmi_app_38_rs_ipmi15_conn, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_app_38_rs_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_38_rs_byte2, byte2, TRUE, BMT_NO_FALSE); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_app_38_rs_byte3, byte3, TRUE, BMT_NO_FALSE); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Supported connections: ", "None", + ett_ipmi_app_38_rs_byte4, byte4, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_38_rs_oem_iana, tvb, 4, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_38_rs_oem_aux, tvb, 7, 1, TRUE); +} + +/* Get Session Challenge + */ +static void +rq39(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_39_authtype, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_39_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_39_user, tvb, 1, 16, TRUE); +} + +static void +rs39(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_app_39_temp_session, tvb, 0, 4, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_39_challenge, tvb, 4, 16, TRUE); +} + +static const value_string cc39[] = { + { 0x81, "Invalid user name" }, + { 0x82, "Null user name (User 1) not enabled" }, + { 0, NULL } +}; + +/* Activate Session + */ +static void +rq3a(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_3a_authtype, NULL }; + static const gint *byte2[] = { &hf_ipmi_app_3a_privlevel, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_3a_rq_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_app_3a_rq_byte2, byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_3a_authcode, tvb, 2, 16, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_3a_outbound_seq, tvb, 18, 4, TRUE); +} + +static void +rs3a(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_3a_authtype_session, NULL }; + static const gint *byte10[] = { &hf_ipmi_app_3a_maxpriv_session, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_3a_rs_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_app_3a_session_id, tvb, 1, 4, TRUE); + proto_tree_add_item(tree, hf_ipmi_app_3a_inbound_seq, tvb, 5, 4, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 9, 1, NULL, NULL, + ett_ipmi_app_3a_rs_byte10, byte10, TRUE, 0); +} + +static const value_string cc3a[] = { + { 0x81, "No session slot available" }, + { 0x82, "No slot available for given user" }, + { 0x83, "No slot available to support user due to maximum privilege capability" }, + { 0x84, "Session sequence number out-of-range" }, + { 0x85, "Invalid session ID in request" }, + { 0x86, "Requested maximum privilege level exceeds user and/or channel privilege limit" }, + { 0, NULL } +}; + +/* Set Session Privilege Level + */ +static void +rq3b(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_3b_req_priv, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_3b_rq_byte1, byte1, TRUE, 0); +} + +static void +rs3b(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_app_3b_new_priv, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_app_3b_rs_byte1, byte1, TRUE, 0); +} + +static const value_string cc3b[] = { + { 0x80, "Requested level not available for this user" }, + { 0x81, "Requested level exceeds Channel and/or User Privilege Limit" }, + { 0x82, "Cannot disable User Level authentication" }, + { 0, NULL } +}; + +/* Close Session + */ +static void +rq3c(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_app_3c_session_id, tvb, 0, 4, TRUE); + if (tvb_length(tvb) > 4) { + proto_tree_add_item(tree, hf_ipmi_app_3c_session_handle, tvb, 4, 1, TRUE); + } +} + +static const value_string cc3c[] = { + { 0x87, "Invalid Session ID in request" }, + { 0x88, "Invalid Session Handle in request" }, + { 0, NULL } +}; + +static const value_string cc40[] = { + { 0x82, "Set not supported on selected channel" }, + { 0x83, "Access mode not supported" }, + { 0, NULL } +}; + +static const value_string cc41[] = { + { 0x82, "Command not supported for selected channel" }, + { 0, NULL } +}; + +static const value_string cc47[] = { + { 0x80, "Password test failed: password data does not match stored value" }, + { 0x81, "Password test failed: wrong password size was used" }, + { 0, NULL } +}; + +static const value_string cc48[] = { + { 0x80, "Payload already active on another session" }, + { 0x81, "Payload type is disabled" }, + { 0x82, "Payload activation limit reached" }, + { 0x83, "Cannot activate payload with encryption" }, + { 0x84, "Cannot activate payload without encryption" }, + { 0, NULL } +}; + +static const value_string cc49[] = { + { 0x80, "Payload already deactivated" }, + { 0x81, "Payload type is disabled" }, + { 0, NULL } +}; + +static const value_string cc4f[] = { + { 0x80, "Payload type not available on given channel" }, + { 0, NULL } +}; + +static const value_string cc50[] = { + { 0x80, "OEM Payload IANA and/or Payload ID not supported" }, + { 0, NULL } +}; + +static const value_string cc52[] = { + { 0x81, "Lost Arbitration" }, + { 0x82, "Bus Error" }, + { 0x83, "NAK on Write" }, + { 0x84, "Truncated Read" }, + { 0, NULL } +}; + +static const value_string cc55[] = { + { 0x80, "Operation not supported for given payload type" }, + { 0x81, "Operation not allowed under present configuration" }, + { 0x82, "Encryption not available for session that payload type is active under" }, + { 0x83, "Payload instance is not presently active" }, + { 0, NULL } +}; + +static const value_string cc56[] = { + { 0x80, "Cannot perform set/confirm, key is locked" }, + { 0x81, "Insufficient key bytes" }, + { 0x82, "Too many key bytes" }, + { 0x83, "Key value does not meet criteria for specified type" }, + { 0x84, "KR is not used" }, + { 0, NULL } +}; + +static const value_string cc58[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the set-in-progress when not in set-complete state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0, NULL } +}; + +static const value_string cc59[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +static const value_string cc60[] = { + { 0x80, "Attempt to enable unsupported/unconfigurable command" }, + { 0, NULL } +}; + +static const value_string cc62[] = { + { 0x80, "Attempt to enable unsupported/unconfigurable sub-function" }, + { 0, NULL } +}; + +static ipmi_cmd_t cmd_app[] = { + /* IPM Device Global Commands */ + { 0x01, NULL, rs01, NULL, NULL, "Get Device ID", CMD_MAYBROADCAST }, + { 0x02, NULL, NULL, NULL, NULL, "Cold Reset", 0 }, + { 0x03, NULL, NULL, NULL, NULL, "Warm Reset", 0 }, + { 0x04, NULL, rs04, NULL, NULL, "Get Self Test Results", 0 }, + { 0x05, rq05, NULL, NULL, NULL, "Manufacturing Test On", 0 }, + { 0x06, rq06, NULL, NULL, NULL, "Set ACPI Power State", 0 }, + { 0x07, NULL, rs07, NULL, NULL, "Get ACPI Power State", 0 }, + { 0x08, NULL, rs08, NULL, NULL, "Get Device GUID", 0 }, + { 0x09, IPMI_TBD, NULL, NULL, "Get NetFn Support", 0 }, + { 0x0a, IPMI_TBD, NULL, NULL, "Get Command Support", 0 }, + { 0x0b, IPMI_TBD, NULL, NULL, "Get Command Sub-function Support", 0 }, + { 0x0c, IPMI_TBD, NULL, NULL, "Get Configurable Commands", 0 }, + { 0x0d, IPMI_TBD, NULL, NULL, "Get Configurable Command Sub-functions", 0 }, + + /* BMC Watchdog Timer Commands */ + { 0x22, NULL, NULL, cc22, NULL, "Reset Watchdog Timer", 0 }, + { 0x24, rq24, NULL, NULL, NULL, "Set Watchdog Timer", 0 }, + { 0x25, NULL, rs25, NULL, NULL, "Get Watchdog Timer", 0 }, + + /* BMC Device and Messaging Commands */ + { 0x2e, rq2e, NULL, NULL, NULL, "Set BMC Global Enables", 0 }, + { 0x2f, NULL, rs2f, NULL, NULL, "Get BMC Global Enables", 0 }, + { 0x30, rq30, NULL, NULL, NULL, "Clear Message Flags", 0 }, + { 0x31, NULL, rs31, NULL, NULL, "Get Message Flags", 0 }, + { 0x32, rq32, rs32, NULL, NULL, "Enable Message Channel Receive", 0 }, + { 0x33, IPMI_TBD, cc33, NULL, "Get Message", 0 }, + { 0x34, rq34, rs34, cc34, NULL, "Send Message", CMD_CALLRQ }, + { 0x35, IPMI_TBD, cc35, NULL, "Read Event Message Buffer", 0 }, + { 0x36, IPMI_TBD, NULL, NULL, "Get BT Interface Capabilities", 0 }, + { 0x37, IPMI_TBD, NULL, NULL, "Get System GUID", 0 }, + { 0x38, rq38, rs38, NULL, NULL, "Get Channel Authentication Capabilities", 0 }, + { 0x39, rq39, rs39, cc39, NULL, "Get Session Challenge", 0 }, + { 0x3a, rq3a, rs3a, cc3a, NULL, "Activate Session", 0 }, + { 0x3b, rq3b, rs3b, cc3b, NULL, "Set Session Privilege Level", 0 }, + { 0x3c, rq3c, NULL, cc3c, NULL, "Close Session", 0 }, + { 0x3d, IPMI_TBD, NULL, NULL, "Get Session Info", 0 }, + { 0x3f, IPMI_TBD, NULL, NULL, "Get AuthCode", 0 }, + { 0x40, IPMI_TBD, cc40, NULL, "Set Channel Access", 0 }, + { 0x41, IPMI_TBD, cc41, NULL, "Get Channel Access", 0 }, + { 0x42, IPMI_TBD, NULL, NULL, "Get Channel Info", 0 }, + { 0x43, IPMI_TBD, NULL, NULL, "Set User Access", 0 }, + { 0x44, IPMI_TBD, NULL, NULL, "Get User Access", 0 }, + { 0x45, IPMI_TBD, NULL, NULL, "Set User Name", 0 }, + { 0x46, IPMI_TBD, NULL, NULL, "Get User Name", 0 }, + { 0x47, IPMI_TBD, cc47, NULL, "Set User Password", 0 }, + { 0x48, IPMI_TBD, cc48, NULL, "Activate Payload", 0 }, + { 0x49, IPMI_TBD, cc49, NULL, "Deactivate Payload", 0 }, + { 0x4a, IPMI_TBD, NULL, NULL, "Get Payload Activation Status", 0 }, + { 0x4b, IPMI_TBD, NULL, NULL, "Get Payload Instance Info", 0 }, + { 0x4c, IPMI_TBD, NULL, NULL, "Set User Payload Access", 0 }, + { 0x4d, IPMI_TBD, NULL, NULL, "Get User Payload Access", 0 }, + { 0x4e, IPMI_TBD, NULL, NULL, "Get Channel Payload Support", 0 }, + { 0x4f, IPMI_TBD, cc4f, NULL, "Get Channel Payload Version", 0 }, + { 0x50, IPMI_TBD, cc50, NULL, "Get Channel OEM Payload Info", 0 }, + { 0x52, IPMI_TBD, cc52, NULL, "Master Write-Read", 0 }, + { 0x54, IPMI_TBD, NULL, NULL, "Get Channel Cipher Suites", 0 }, + { 0x55, IPMI_TBD, cc55, NULL, "Suspend/Resume Payload Encryption", 0 }, + { 0x56, IPMI_TBD, cc56, NULL, "Set Channel Security Keys", 0 }, + { 0x57, IPMI_TBD, NULL, NULL, "Get System Interface Capabilities", 0 }, + { 0x58, IPMI_TBD, cc58, NULL, "Set System Info Parameters", 0 }, + { 0x59, IPMI_TBD, cc59, NULL, "Get System Info Parameters", 0 }, + + /* Device "Global" commands, continued */ + { 0x60, IPMI_TBD, cc60, NULL, "Set Command Enables", 0 }, + { 0x61, IPMI_TBD, NULL, NULL, "Get Command Enables", 0 }, + { 0x62, IPMI_TBD, cc62, NULL, "Set Command Sub-function Enables", 0 }, + { 0x63, IPMI_TBD, NULL, NULL, "Get Command Sub-function Enables", 0 }, + { 0x64, IPMI_TBD, NULL, NULL, "Get OEM NetFn IANA Support", 0 }, +}; + +void +ipmi_register_app(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_app_01_dev_id, + { "Device ID", + "ipmi.app00.dev.id", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_01_dev_prov_sdr, + { "Device provides Device SDRs", + "ipmi.app00.dev.provides_dev_sdr", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_app_01_dev_rev, + { "Device Revision (binary encoded)", + "ipmi.app00.dev.rev", FT_UINT8, BASE_HEX, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_app_01_dev_avail, + { "Device availability", + "ipmi.app01.dev.avail", FT_BOOLEAN, 8, TFS(&tfs_01_dev_avail), 0x80, "", HFILL }}, + { &hf_ipmi_app_01_fw_rev_maj, + { "Major Firmware Revision (binary encoded)", + "ipmi.app01.fw.major", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_app_01_fw_rev_min, + { "Minor Firmware Revision (BCD encoded)", + "ipmi.app01.fw.minor", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_version, + { "IPMI version", + "ipmi.app01.ipmi.version", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_chassis, + { "Chassis", + "ipmi.app01.ads.chassis", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_bridge, + { "Bridge", + "ipmi.app01.ads.bridge", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_ipmb_ev_gen, + { "Event Generator", + "ipmi.app01.ads.ipmb_ev_gen", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_ipmb_ev_recv, + { "Event Receiver", + "ipmi.app01.ads.ipmb_ev_recv", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_fru, + { "FRU Inventory", + "ipmi.app01.ads.fru", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_sel, + { "SEL", + "ipmi.app01.ads.sel", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_sdr, + { "SDR Repository", + "ipmi.app01.ads.sdr", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_app_01_ipmi_ads_sensor, + { "Sensor", + "ipmi.app01.ads.sensor", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_app_01_manufacturer, + { "Manufacturer ID", + "ipmi.app01.manufacturer", FT_UINT24, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_01_product, + { "Product ID", + "ipmi.app01.product", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_01_fw_aux, + { "Auxillary Firmware Revision Information", + "ipmi.app01.fw.aux", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_04_result, + { "Self test result", + "ipmi.app04.self_test_result", FT_UINT8, BASE_HEX, vals_04_result, 0, "", HFILL }}, + { &hf_ipmi_app_04_fail, + { "Self-test error bitfield", + "ipmi.app04.fail", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_04_fail_sel, + { "Cannot access SEL device", + "ipmi.app04.fail.sel", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x80, "", HFILL }}, + { &hf_ipmi_app_04_fail_sdr, + { "Cannot access SDR Repository", + "ipmi.app04.fail.sdr", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x40, "", HFILL }}, + { &hf_ipmi_app_04_fail_bmc_fru, + { "Cannot access BMC FRU device", + "ipmi.app04.fail.bmc_fru", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x20, "", HFILL }}, + { &hf_ipmi_app_04_fail_ipmb_sig, + { "IPMB signal lines do not respond", + "ipmi.app04.fail.ipmb_sig", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x10, "", HFILL }}, + { &hf_ipmi_app_04_fail_sdr_empty, + { "SDR Repository is empty", + "ipmi.app04.fail.sdr_empty", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x08, "", HFILL }}, + { &hf_ipmi_app_04_fail_iua, + { "Internal Use Area of BMC FRU corrupted", + "ipmi.app04.fail.iua", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x04, "", HFILL }}, + { &hf_ipmi_app_04_fail_bb_fw, + { "Controller update boot block firmware corrupted", + "ipmi.app04.fail.bb_fw", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x02, "", HFILL }}, + { &hf_ipmi_app_04_fail_oper_fw, + { "Controller operational firmware corrupted", + "ipmi.app04.fail.oper_fw", FT_BOOLEAN, 8, TFS(&tfs_04_fail_unknown), 0x01, "", HFILL }}, + + { &hf_ipmi_app_05_devspec, + { "Device-specific parameters", + "ipmi.app05.devspec", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_06_syspwr_set, + { "System Power State", + "ipmi.app06.syspwr.set", FT_BOOLEAN, 8, TFS(&tfs_06_pwr), 0x80, "", HFILL }}, + { &hf_ipmi_app_06_syspwr_enum, + { "System Power State enumeration", + "ipmi.app06.syspwr.enum", FT_UINT8, BASE_HEX, vals_06_syspwr, 0x7f, "", HFILL }}, + { &hf_ipmi_app_06_devpwr_set, + { "Device Power State", + "ipmi.app06.devpwr.set", FT_BOOLEAN, 8, TFS(&tfs_06_pwr), 0x80, "", HFILL }}, + { &hf_ipmi_app_06_devpwr_enum, + { "Device Power State enumeration", + "ipmi.app06.devpwr.enum", FT_UINT8, BASE_HEX, vals_06_devpwr, 0x7f, "", HFILL }}, + + { &hf_ipmi_app_07_syspwr_enum, + { "ACPI System Power State", + "ipmi.app07.syspwr", FT_UINT8, BASE_HEX, vals_07_syspwr, 0x7f, "", HFILL }}, + { &hf_ipmi_app_07_devpwr_enum, + { "ACPI Device Power State", + "ipmi.app07.devpwr", FT_UINT8, BASE_HEX, vals_07_devpwr, 0x7f, "", HFILL }}, + + { &hf_ipmi_app_08_guid, + { "GUID", + "ipmi.app08.guid", FT_GUID, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_24_timer_use_dont_log, + { "Don't log", + "ipmi.app24.timer_use.dont_log", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_app_24_timer_use_dont_stop, + { "Don't stop timer on Set Watchdog command", + "ipmi.app24.timer_use.dont_stop", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_app_24_timer_use_timer_use, + { "Timer use", + "ipmi.app24.timer_use.timer_use", FT_UINT8, BASE_HEX, vals_24_timer_use, 0x07, "", HFILL }}, + { &hf_ipmi_app_24_timer_action_interrupt, + { "Pre-timeout interrupt", + "ipmi.app24.timer_action.interrupt", FT_UINT8, BASE_HEX, vals_24_timer_action_interrupt, 0x70, "", HFILL }}, + { &hf_ipmi_app_24_timer_action_timeout_action, + { "Timeout action", + "ipmi.app24.timer_action.timeout", FT_UINT8, BASE_HEX, vals_24_timer_action_timeout, 0x07, "", HFILL }}, + { &hf_ipmi_app_24_pretimeout, + { "Pre-timeout interval", + "ipmi.app24.pretimeout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_app_24_expiration_flags_oem, + { "OEM", + "ipmi.app24.exp_flags.oem", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x20, "", HFILL }}, + { &hf_ipmi_app_24_expiration_flags_smsos, + { "SMS/OS", + "ipmi.app24.exp_flags.sms_os", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x10, "", HFILL }}, + { &hf_ipmi_app_24_expiration_flags_osload, + { "OS Load", + "ipmi.app24.exp_flags.osload", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x08, "", HFILL }}, + { &hf_ipmi_app_24_expiration_flags_biospost, + { "BIOS/POST", + "ipmi.app24.exp_flags.biospost", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x04, "", HFILL }}, + { &hf_ipmi_app_24_expiration_flags_biosfrb2, + { "BIOS FRB2", + "ipmi.app24.exp_flags.biosfrb2", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x02, "", HFILL }}, + { &hf_ipmi_app_24_initial_countdown, + { "Initial countdown value (100ms/count)", + "ipmi.app24.initial_countdown", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_25_timer_use_dont_log, + { "Don't log", + "ipmi.app25.timer_use.dont_log", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_app_25_timer_use_started, + { "Started", + "ipmi.app25.timer_use.started", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_app_25_timer_use_timer_use, + { "Timer user", + "ipmi.app25.timer_use.timer_use", FT_UINT8, BASE_HEX, vals_24_timer_use, 0x07, "", HFILL }}, + { &hf_ipmi_app_25_timer_action_interrupt, + { "Pre-timeout interrupt", + "ipmi.app25.timer_action.interrupt", FT_UINT8, BASE_HEX, vals_24_timer_action_interrupt, 0x70, "", HFILL }}, + { &hf_ipmi_app_25_timer_action_timeout_action, + { "Timeout action", + "ipmi.app25.timer_action.timeout", FT_UINT8, BASE_HEX, vals_24_timer_action_timeout, 0x07, "", HFILL }}, + { &hf_ipmi_app_25_pretimeout, + { "Pre-timeout interval", + "ipmi.app25.pretimeout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_app_25_expiration_flags_oem, + { "OEM", + "ipmi.app25.exp_flags.oem", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x20, "", HFILL }}, + { &hf_ipmi_app_25_expiration_flags_smsos, + { "SMS/OS", + "ipmi.app25.exp_flags.sms_os", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x10, "", HFILL }}, + { &hf_ipmi_app_25_expiration_flags_osload, + { "OS Load", + "ipmi.app25.exp_flags.osload", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x08, "", HFILL }}, + { &hf_ipmi_app_25_expiration_flags_biospost, + { "BIOS/POST", + "ipmi.app25.exp_flags.biospost", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x04, "", HFILL }}, + { &hf_ipmi_app_25_expiration_flags_biosfrb2, + { "BIOS FRB2", + "ipmi.app25.exp_flags.biosfrb2", FT_BOOLEAN, 8, TFS(&tfs_24_exp_flags), 0x02, "", HFILL }}, + { &hf_ipmi_app_25_initial_countdown, + { "Initial countdown value (100ms/count)", + "ipmi.app25.initial_countdown", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_25_present_countdown, + { "Present countdown value (100ms/count)", + "ipmi.app25.initial_countdown", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_2e_byte1_oem2, + { "OEM 2", + "ipmi.app2e.bmc_global_enables.oem2", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x80, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_oem1, + { "OEM 1", + "ipmi.app2e.bmc_global_enables.oem1", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x40, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_oem0, + { "OEM 0", + "ipmi.app2e.bmc_global_enables.oem0", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x20, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_sel, + { "System Event Logging", + "ipmi.app2e.bmc_global_enables.sel", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x08, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_emb, + { "Event Message Buffer", + "ipmi.app2e.bmc_global_enables.emb", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x04, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_emb_full_intr, + { "Event Message Buffer Full Interrupt", + "ipmi.app2e.bmc_global_enables.emb_full_intr", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x02, "", HFILL }}, + { &hf_ipmi_app_2e_byte1_rmq_intr, + { "Receive Message Queue Interrupt", + "ipmi.app2e.bmc_global_enables.rmq_intr", FT_BOOLEAN, 8, TFS(&tfs_2e_enable), 0x01, "", HFILL }}, + + { &hf_ipmi_app_2f_byte1_oem2, + { "OEM 2", + "ipmi.app2f.bmc_global_enables.oem2", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x80, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_oem1, + { "OEM 1", + "ipmi.app2f.bmc_global_enables.oem1", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x40, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_oem0, + { "OEM 0", + "ipmi.app2f.bmc_global_enables.oem0", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x20, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_sel, + { "System Event Logging", + "ipmi.app2f.bmc_global_enables.sel", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x08, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_emb, + { "Event Message Buffer", + "ipmi.app2f.bmc_global_enables.emb", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x04, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_emb_full_intr, + { "Event Message Buffer Full Interrupt", + "ipmi.app2f.bmc_global_enables.emb_full_intr", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x02, "", HFILL }}, + { &hf_ipmi_app_2f_byte1_rmq_intr, + { "Receive Message Queue Interrupt", + "ipmi.app2f.bmc_global_enables.rmq_intr", FT_BOOLEAN, 8, TFS(&tfs_2f_enabled), 0x01, "", HFILL }}, + + { &hf_ipmi_app_30_byte1_oem2, + { "OEM 2", + "ipmi.app30.byte1.oem2", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x80, "", HFILL }}, + { &hf_ipmi_app_30_byte1_oem1, + { "OEM 1", + "ipmi.app30.byte1.oem1", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x40, "", HFILL }}, + { &hf_ipmi_app_30_byte1_oem0, + { "OEM 0", + "ipmi.app30.byte1.oem0", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x20, "", HFILL }}, + { &hf_ipmi_app_30_byte1_wd_pretimeout, + { "Watchdog pre-timeout interrupt flag", + "ipmi.app30.byte1.wd_pretimeout", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x08, "", HFILL }}, + { &hf_ipmi_app_30_byte1_emb, + { "Event Message Buffer", + "ipmi.app30.byte1.emb", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x02, "", HFILL }}, + { &hf_ipmi_app_30_byte1_rmq, + { "Receive Message Queue", + "ipmi.app30.byte1.rmq", FT_BOOLEAN, 8, TFS(&tfs_30_clear), 0x01, "", HFILL }}, + + { &hf_ipmi_app_31_byte1_oem2, + { "OEM 2 data available", + "ipmi.app31.byte1.oem2", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_app_31_byte1_oem1, + { "OEM 1 data available", + "ipmi.app31.byte1.oem1", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_app_31_byte1_oem0, + { "OEM 0 data available", + "ipmi.app31.byte1.oem0", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_app_31_byte1_wd_pretimeout, + { "Watchdog pre-timeout interrupt occurred", + "ipmi.app31.byte1.wd_pretimeout", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_app_31_byte1_emb, + { "Event Message Buffer Full", + "ipmi.app31.byte1.emb", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_app_31_byte1_rmq, + { "Receive Message Available", + "ipmi.app31.byte1.rmq", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_app_32_rq_chno, + { "Channel", + "ipmi.app32.rq_chno", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_app_32_rq_state, + { "Channel State", + "ipmi.app32.rq_state", FT_UINT8, BASE_HEX, vals_32_state, 0x03, "", HFILL }}, + { &hf_ipmi_app_32_rs_chno, + { "Channel", + "ipmi.app32.rs_chno", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_app_32_rs_state, + { "Channel State", + "ipmi.app32.rs_state", FT_BOOLEAN, 8, TFS(&tfs_32_state), 0x01, "", HFILL }}, + + { &hf_ipmi_app_34_track, + { "Tracking", + "ipmi.app34.track", FT_UINT8, BASE_HEX, vals_34_track, 0xc0, "", HFILL }}, + { &hf_ipmi_app_34_encrypt, + { "Encryption required", + "ipmi.app34.encrypt", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_app_34_auth, + { "Authentication required", + "ipmi.app34.auth", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_app_34_chan, + { "Channel", + "ipmi.app34.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + + { &hf_ipmi_app_38_rq_ipmi20, + { "Version compatibility", + "ipmi.app38.rq_ipmi20", FT_UINT8, BASE_DEC, &vals_38_ipmi20, 0x80, "", HFILL }}, + { &hf_ipmi_app_38_rq_chan, + { "Channel", + "ipmi.app38.rq_chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_app_38_rq_priv, + { "Requested privilege level", + "ipmi.app38.rq_priv", FT_UINT8, BASE_HEX, vals_XX_priv, 0x0f, "", HFILL }}, + { &hf_ipmi_app_38_rs_chan, + { "Channel", + "ipmi.app38.rs_chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_app_38_rs_ipmi20, + { "Version compatibility", + "ipmi.app38.rs_ipmi20", FT_UINT8, BASE_DEC, vals_38_ipmi20, 0x80, "", HFILL }}, + { &hf_ipmi_app_38_rs_auth_oem, + { "OEM Proprietary authentication", + "ipmi.app38.rs_auth_oem", FT_BOOLEAN, 8, TFS(&tfs_38_supp), 0x20, "", HFILL }}, + { &hf_ipmi_app_38_rs_auth_straight, + { "Straight password/key", + "ipmi.app38.rs_auth_straight", FT_BOOLEAN, 8, TFS(&tfs_38_supp), 0x10, "", HFILL }}, + { &hf_ipmi_app_38_rs_auth_md5, + { "MD5", + "ipmi.app38.rs_auth_md5", FT_BOOLEAN, 8, TFS(&tfs_38_supp), 0x04, "", HFILL }}, + { &hf_ipmi_app_38_rs_auth_md2, + { "MD2", + "ipmi.app38.rs_auth_md2", FT_BOOLEAN, 8, TFS(&tfs_38_supp), 0x02, "", HFILL }}, + { &hf_ipmi_app_38_rs_auth_none, + { "No auth", + "ipmi.app38.rs_auth_none", FT_BOOLEAN, 8, TFS(&tfs_38_supp), 0x01, "", HFILL }}, + { &hf_ipmi_app_38_rs_kg, + { "KG", + "ipmi.app38.rs_kg_status", FT_BOOLEAN, 8, TFS(&tfs_38_kg), 0x20, "", HFILL }}, + { &hf_ipmi_app_38_rs_permsg, + { "Per-message Authentication disabled", + "ipmi.app38.rs_permsg", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_app_38_rs_userauth, + { "User-level Authentication disabled", + "ipmi.app38.rs_userauth", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_app_38_rs_user_nonnull, + { "Non-null usernames enabled", + "ipmi.app38.rs_user_nonnull", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_app_38_rs_user_null, + { "Null usernames enabled", + "ipmi.app38.rs_user_null", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_app_38_rs_user_anon, + { "Anonymous login enabled", + "ipmi.app38.rs_user_anon", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_app_38_rs_ipmi20_conn, + { "IPMI v2.0", + "ipmi.app38.rs_ipmi20_conn", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_app_38_rs_ipmi15_conn, + { "IPMI v1.5", + "ipmi.app38.rs_ipmi15_conn", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_app_38_rs_oem_iana, + { "OEM ID", + "ipmi.app38.rs_oem_iana", FT_UINT24, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_38_rs_oem_aux, + { "OEM Auxillary data", + "ipmi.app38.rs_oem_aux", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_39_authtype, + { "Authentication Type", + "ipmi.app39.authtype", FT_UINT8, BASE_HEX, vals_XX_auth, 0x0f, "", HFILL }}, + { &hf_ipmi_app_39_user, + { "User Name", + "ipmi.app39.user", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_39_temp_session, + { "Temporary Session ID", + "ipmi.app39.temp_session", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_39_challenge, + { "Challenge", + "ipmi.app39.challenge", FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_app_3a_authtype, + { "Authentication Type", + "ipmi.app3a.authtype", FT_UINT8, BASE_HEX, vals_XX_auth, 0x0f, "", HFILL }}, + { &hf_ipmi_app_3a_privlevel, + { "Requested Maximum Privilege Level", + "ipmi.app3a.privlevel", FT_UINT8, BASE_HEX, vals_XX_priv, 0x0f, "", HFILL }}, + { &hf_ipmi_app_3a_authcode, + { "Challenge string/Auth Code", + "ipmi.app3a.authcode", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_3a_outbound_seq, + { "Initial Outbound Sequence Number", + "ipmi.app3a.outbound_seq", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_3a_authtype_session, + { "Authentication Type for session", + "ipmi.app3a.authtype_session", FT_UINT8, BASE_HEX, vals_XX_auth, 0x0f, "", HFILL }}, + { &hf_ipmi_app_3a_session_id, + { "Session ID", + "ipmi.app3a.session_id", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_3a_inbound_seq, + { "Initial Inbound Sequence Number", + "ipmi.app3a.inbound_seq", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_3a_maxpriv_session, + { "Maximum Privilege Level for session", + "ipmi.app3a.maxpriv_session", FT_UINT8, BASE_HEX, vals_XX_priv, 0x0f, "", HFILL }}, + + { &hf_ipmi_app_3b_req_priv, + { "Requested Privilege Level", + "ipmi.app3b.req_priv", FT_UINT8, BASE_HEX, vals_XX_priv, 0x0f, "", HFILL }}, + { &hf_ipmi_app_3b_new_priv, + { "New Privilege Level", + "ipmi.app3b.new_priv", FT_UINT8, BASE_HEX, vals_XX_priv, 0x0f, "", HFILL }}, + + { &hf_ipmi_app_3c_session_id, + { "Session ID", + "ipmi.app3c.session_id", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_app_3c_session_handle, + { "Session handle", + "ipmi.app3c.session_handle", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + }; + static gint *ett[] = { + &ett_ipmi_app_01_byte2, + &ett_ipmi_app_01_byte3, + &ett_ipmi_app_01_byte6, + &ett_ipmi_app_04_byte2, + &ett_ipmi_app_06_syspwr, + &ett_ipmi_app_06_devpwr, + &ett_ipmi_app_07_syspwr, + &ett_ipmi_app_07_devpwr, + &ett_ipmi_app_24_timer_use, + &ett_ipmi_app_24_timer_action, + &ett_ipmi_app_24_expiration_flags, + &ett_ipmi_app_25_timer_use, + &ett_ipmi_app_25_timer_action, + &ett_ipmi_app_25_expiration_flags, + &ett_ipmi_app_2e_byte1, + &ett_ipmi_app_2f_byte1, + &ett_ipmi_app_30_byte1, + &ett_ipmi_app_31_byte1, + &ett_ipmi_app_32_rq_byte1, + &ett_ipmi_app_32_rq_byte2, + &ett_ipmi_app_32_rs_byte1, + &ett_ipmi_app_32_rs_byte2, + &ett_ipmi_app_34_byte1, + &ett_ipmi_app_34_msg, + &ett_ipmi_app_38_rq_byte1, + &ett_ipmi_app_38_rq_byte2, + &ett_ipmi_app_38_rs_byte1, + &ett_ipmi_app_38_rs_byte2, + &ett_ipmi_app_38_rs_byte3, + &ett_ipmi_app_38_rs_byte4, + &ett_ipmi_app_39_byte1, + &ett_ipmi_app_3a_rq_byte1, + &ett_ipmi_app_3a_rq_byte2, + &ett_ipmi_app_3a_rs_byte1, + &ett_ipmi_app_3a_rs_byte10, + &ett_ipmi_app_3b_rq_byte1, + &ett_ipmi_app_3b_rs_byte1, + }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_APP_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_app, array_length(cmd_app)); +} diff --git a/epan/dissectors/packet-ipmi-bridge.c b/epan/dissectors/packet-ipmi-bridge.c new file mode 100644 index 0000000000..0246c412a4 --- /dev/null +++ b/epan/dissectors/packet-ipmi-bridge.c @@ -0,0 +1,149 @@ +/* packet-ipmi-bridge.c + * Sub-dissectors for IPMI messages (netFn=Bridge) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +/* Bridge commands are not implemented (yet) */ + + +static ipmi_cmd_t cmd_bridge[] = { + /* Bridge management commands (ICMB) */ + { 0x00, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge State", 0 }, + { 0x01, IPMI_TBD, NULL, NULL, "[ICMB] Set Bridge State", 0 }, + { 0x02, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Address", 0 }, + { 0x03, IPMI_TBD, NULL, NULL, "[ICMB] Set ICMB Address", 0 }, + { 0x04, IPMI_TBD, NULL, NULL, "[ICMB] Set Bridge Proxy Address", 0 }, + { 0x05, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge Statistics", 0 }, + { 0x06, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Capabilities", 0 }, + { 0x08, IPMI_TBD, NULL, NULL, "[ICMB] Clear Bridge Statistics", 0 }, + { 0x09, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge Proxy Address", 0 }, + { 0x0a, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Connector Info", 0 }, + { 0x0b, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Connection ID", 0 }, + { 0x0c, IPMI_TBD, NULL, NULL, "[ICMB] Send ICMB Connection ID", 0 }, + + /* Discovery Commands (ICMB) */ + { 0x10, IPMI_TBD, NULL, NULL, "[ICMB] Prepare For Discovery", 0 }, + { 0x11, IPMI_TBD, NULL, NULL, "[ICMB] Get Addresses", 0 }, + { 0x12, IPMI_TBD, NULL, NULL, "[ICMB] Set Discovered", 0 }, + { 0x13, IPMI_TBD, NULL, NULL, "[ICMB] Get Chassis Device ID", 0 }, + { 0x14, IPMI_TBD, NULL, NULL, "[ICMB] Set Chassis Device ID", 0 }, + + /* Bridging Commands (ICMB) */ + { 0x20, IPMI_TBD, NULL, NULL, "[ICMB] Bridge Request", 0 }, + { 0x21, IPMI_TBD, NULL, NULL, "[ICMB] Bridge Message", 0 }, + + /* Event Commands (ICMB) */ + { 0x30, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Count", 0 }, + { 0x31, IPMI_TBD, NULL, NULL, "[ICMB] Set Event Destination", 0 }, + { 0x32, IPMI_TBD, NULL, NULL, "[ICMB] Set Event Reception State", 0 }, + { 0x33, IPMI_TBD, NULL, NULL, "[ICMB] Send ICMB Event Message", 0 }, + { 0x34, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Destination", 0 }, + { 0x35, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Reception State", 0 }, + + /* OEM Commands for Bridge NetFn */ + { 0xc0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xc9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xca, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xcb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xcc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xcd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xce, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xcf, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xd9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xda, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xdb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xdc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xdd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xde, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xdf, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xe9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xea, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xeb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xec, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xed, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xee, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xef, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xf9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xfa, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xfb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xfc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xfd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + { 0xfe, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 }, + + /* Other Bridge Commands */ + { 0xff, IPMI_TBD, NULL, NULL, "[ICMB] Error Report", 0 }, +}; + +void +ipmi_register_bridge(gint proto_ipmi _U_) +{ + ipmi_register_netfn_cmdtab(IPMI_BRIDGE_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_bridge, array_length(cmd_bridge)); +} diff --git a/epan/dissectors/packet-ipmi-chassis.c b/epan/dissectors/packet-ipmi-chassis.c new file mode 100644 index 0000000000..86aa876832 --- /dev/null +++ b/epan/dissectors/packet-ipmi-chassis.c @@ -0,0 +1,1064 @@ +/* packet-ipmi-chassis.c + * Sub-dissectors for IPMI messages (netFn=Chassis) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +/* Local variables. + */ +static gint ett_ipmi_chs_bo00_byte1 = -1; +static gint ett_ipmi_chs_bo02_byte1 = -1; +static gint ett_ipmi_chs_bo03_byte1 = -1; +static gint ett_ipmi_chs_bo04_byte2 = -1; +static gint ett_ipmi_chs_bo05_byte1 = -1; +static gint ett_ipmi_chs_bo05_byte2 = -1; +static gint ett_ipmi_chs_bo05_byte3 = -1; +static gint ett_ipmi_chs_bo05_byte4 = -1; +static gint ett_ipmi_chs_bo06_byte1 = -1; + +static gint ett_ipmi_chs_00_capflags = -1; +static gint ett_ipmi_chs_01_pwr_state = -1; +static gint ett_ipmi_chs_01_last_event = -1; +static gint ett_ipmi_chs_01_misc = -1; +static gint ett_ipmi_chs_01_fpb = -1; +static gint ett_ipmi_chs_02_byte1 = -1; +static gint ett_ipmi_chs_04_byte2 = -1; +static gint ett_ipmi_chs_05_flags = -1; +static gint ett_ipmi_chs_06_byte1 = -1; +static gint ett_ipmi_chs_06_policy_support = -1; +static gint ett_ipmi_chs_07_byte1 = -1; +static gint ett_ipmi_chs_08_byte1 = -1; +static gint ett_ipmi_chs_09_rq_byte1 = -1; +static gint ett_ipmi_chs_09_rs_byte1 = -1; +static gint ett_ipmi_chs_09_rs_byte2 = -1; + +static gint hf_ipmi_chs_bo00_sip = -1; +static gint hf_ipmi_chs_bo01_spsel = -1; +static gint hf_ipmi_chs_bo02_request = -1; +static gint hf_ipmi_chs_bo02_discovered = -1; +static gint hf_ipmi_chs_bo03_pef = -1; +static gint hf_ipmi_chs_bo03_cctrl_timeout = -1; +static gint hf_ipmi_chs_bo03_wd_timeout = -1; +static gint hf_ipmi_chs_bo03_softreset = -1; +static gint hf_ipmi_chs_bo03_powerup = -1; +static gint hf_ipmi_chs_bo04_write_mask = -1; +static gint hf_ipmi_chs_bo04_bootinit_ack_oem = -1; +static gint hf_ipmi_chs_bo04_bootinit_ack_sms = -1; +static gint hf_ipmi_chs_bo04_bootinit_ack_os = -1; +static gint hf_ipmi_chs_bo04_bootinit_ack_osloader = -1; +static gint hf_ipmi_chs_bo04_bootinit_ack_bios = -1; +static gint hf_ipmi_chs_bo05_bootflags_valid = -1; +static gint hf_ipmi_chs_bo05_permanent = -1; +static gint hf_ipmi_chs_bo05_boottype = -1; +static gint hf_ipmi_chs_bo05_cmos_clear = -1; +static gint hf_ipmi_chs_bo05_lock_kbd = -1; +static gint hf_ipmi_chs_bo05_bootdev = -1; +static gint hf_ipmi_chs_bo05_screen_blank = -1; +static gint hf_ipmi_chs_bo05_lockout_reset = -1; +static gint hf_ipmi_chs_bo05_lockout_poweroff = -1; +static gint hf_ipmi_chs_bo05_bios_verbosity = -1; +static gint hf_ipmi_chs_bo05_progress_traps = -1; +static gint hf_ipmi_chs_bo05_pwd_bypass = -1; +static gint hf_ipmi_chs_bo05_lock_sleep = -1; +static gint hf_ipmi_chs_bo05_console_redirection = -1; +static gint hf_ipmi_chs_bo05_bios_shared_override = -1; +static gint hf_ipmi_chs_bo05_bios_muxctl_override = -1; +static gint hf_ipmi_chs_bo05_byte5 = -1; +static gint hf_ipmi_chs_bo06_chan_num = -1; +static gint hf_ipmi_chs_bo06_session_id = -1; +static gint hf_ipmi_chs_bo06_bootinfo_timestamp = -1; +static gint hf_ipmi_chs_bo07_block_selector = -1; +static gint hf_ipmi_chs_bo07_block_data = -1; + +static gint hf_ipmi_chs_00_capflags_ppi = -1; +static gint hf_ipmi_chs_00_capflags_di = -1; +static gint hf_ipmi_chs_00_capflags_fpl = -1; +static gint hf_ipmi_chs_00_capflags_is = -1; +static gint hf_ipmi_chs_00_fru_dev_addr = -1; +static gint hf_ipmi_chs_00_sdr_dev_addr = -1; +static gint hf_ipmi_chs_00_sel_dev_addr = -1; +static gint hf_ipmi_chs_00_sm_dev_addr = -1; +static gint hf_ipmi_chs_00_bridge_dev_addr = -1; + +static gint hf_ipmi_chs_01_pwr_state_policy = -1; +static gint hf_ipmi_chs_01_pwr_state_ctl_fault = -1; +static gint hf_ipmi_chs_01_pwr_state_fault = -1; +static gint hf_ipmi_chs_01_pwr_state_ilock = -1; +static gint hf_ipmi_chs_01_pwr_state_overload = -1; +static gint hf_ipmi_chs_01_pwr_state_powered = -1; +static gint hf_ipmi_chs_01_last_event_via_ipmi = -1; +static gint hf_ipmi_chs_01_last_event_down_by_fault = -1; +static gint hf_ipmi_chs_01_last_event_interlock = -1; +static gint hf_ipmi_chs_01_last_event_overload = -1; +static gint hf_ipmi_chs_01_last_event_ac_failed = -1; +static gint hf_ipmi_chs_01_misc_identsupp = -1; +static gint hf_ipmi_chs_01_misc_identstate = -1; +static gint hf_ipmi_chs_01_misc_fan = -1; +static gint hf_ipmi_chs_01_misc_drive = -1; +static gint hf_ipmi_chs_01_misc_fpl_active = -1; +static gint hf_ipmi_chs_01_misc_intrusion = -1; +static gint hf_ipmi_chs_01_fpb_standby_allowed = -1; +static gint hf_ipmi_chs_01_fpb_diagintr_allowed = -1; +static gint hf_ipmi_chs_01_fpb_reset_allowed = -1; +static gint hf_ipmi_chs_01_fpb_poweroff_allowed = -1; +static gint hf_ipmi_chs_01_fpb_standby_disabled = -1; +static gint hf_ipmi_chs_01_fpb_diagintr_disabled = -1; +static gint hf_ipmi_chs_01_fpb_reset_disabled = -1; +static gint hf_ipmi_chs_01_fpb_poweroff_disabled = -1; + +static gint hf_ipmi_chs_02_cctrl = -1; + +static gint hf_ipmi_chs_04_ival = -1; +static gint hf_ipmi_chs_04_perm_on = -1; + +static gint hf_ipmi_chs_05_flags_fpl = -1; +static gint hf_ipmi_chs_05_flags_intrusion = -1; +static gint hf_ipmi_chs_05_fru_dev_addr = -1; +static gint hf_ipmi_chs_05_sdr_dev_addr = -1; +static gint hf_ipmi_chs_05_sel_dev_addr = -1; +static gint hf_ipmi_chs_05_sm_dev_addr = -1; +static gint hf_ipmi_chs_05_bridge_dev_addr = -1; + +static gint hf_ipmi_chs_06_rq_policy = -1; +static gint hf_ipmi_chs_06_rs_policy_support_powerup = -1; +static gint hf_ipmi_chs_06_rs_policy_support_restore = -1; +static gint hf_ipmi_chs_06_rs_policy_support_poweroff = -1; + +static gint hf_ipmi_chs_07_cause = -1; +static gint hf_ipmi_chs_07_chan = -1; + +static gint hf_ipmi_chs_08_valid = -1; +static gint hf_ipmi_chs_08_selector = -1; +static gint hf_ipmi_chs_08_data = -1; + +static gint hf_ipmi_chs_09_rq_param_select = -1; +static gint hf_ipmi_chs_09_rq_set_select = -1; +static gint hf_ipmi_chs_09_rq_block_select = -1; +static gint hf_ipmi_chs_09_rs_param_version = -1; +static gint hf_ipmi_chs_09_rs_valid = -1; +static gint hf_ipmi_chs_09_rs_param_select = -1; +static gint hf_ipmi_chs_09_rs_param_data = -1; + +static gint hf_ipmi_chs_0f_minpercnt = -1; +static gint hf_ipmi_chs_0f_counter = -1; + +static const struct true_false_string tfs_00_provided = { "Provided", "Not Provided" }; + +static const value_string vals_01_pwr_policy[] = { + { 0x00, "chassis stays powered off after AC returns" }, + { 0x01, "after AC returns, power is restored to the state that was in effect when AC was lost" }, + { 0x02, "chassis always powers up after AC returns" }, + { 0x03, "unknown" }, + { 0, NULL } +}; + +static const value_string vals_01_identstate[] = { + { 0x00, "Off" }, + { 0x01, "Temporary (timed) On" }, + { 0x02, "On" }, + { 0, NULL } +}; + +static const value_string vals_02_cctrl[] = { + { 0x00, "Power down" }, + { 0x01, "Power up" }, + { 0x02, "Power cycle" }, + { 0x03, "Hard reset" }, + { 0x04, "Pulse Diagnostic Interrupt" }, + { 0x05, "Initiate a soft-shutdown of OS via ACPI by emulating a fatal overtemperature" }, + { 0, NULL } +}; + +static const value_string vals_06_policy[] = { + { 0x00, "Chassis always stays powered off after AC/mains is applied" }, + { 0x01, "After AC/mains is applied or returns, power is restored to the state that was in effect when AC/mains was removed or lost" }, + { 0x02, "Chassis always powers up after AC/mains is applied or returns" }, + { 0x03, "No change (just get policy support)" }, + { 0x04, "Reserved" }, + { 0x05, "Reserved" }, + { 0x06, "Reserved" }, + { 0x07, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_06_supported = { "Supported", "Not supported" }; + +static const value_string vals_07_cause[] = { + { 0x00, "Unknown" }, + { 0x01, "Chassis Control command" }, + { 0x02, "Reset via pushbutton" }, + { 0x03, "Power-up via pushbutton" }, + { 0x04, "Watchdog expiration" }, + { 0x05, "OEM" }, + { 0x06, "Automatic power-up on AC being applied due to 'always restore' power restore policy" }, + { 0x07, "Automatic power-up on AC being applied due to 'restore previous power state' power restore policy" }, + { 0x08, "Reset via PEF" }, + { 0x09, "Power-cycle via PEF" }, + { 0x0a, "Soft reset" }, + { 0x0b, "Power-up via RTC wakeup" }, + { 0x0c, "Reserved" }, + { 0x0d, "Reserved" }, + { 0x0e, "Reserved" }, + { 0x0f, "Reserved" }, + { 0, NULL } +}; + +static const value_string bo00_sip_vals[] = { + { 0x00, "Set complete" }, + { 0x01, "Set in progress" }, + { 0x02, "Commit write" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_08_valid = { + "Mark parameter invalid/locked", + "Mark parameter valid/unlocked" +}; + +static const struct true_false_string bo03_dontclear_tfs = { + "don't clear", + "clear" +}; + +static const struct true_false_string bo04_bootinit_ack_tfs = { + "has handled boot info", + "hasn't handled boot info" +}; + +static const struct true_false_string bo05_permanent_tfs = { + "options requested to be persistent for all future boots", + "options apply to next boot only" +}; + +static const struct true_false_string bo05_boottype_tfs = { + "Extensible Firmware Interface Boot (EFI)", + "'PC compatible' boot (legacy)" +}; + +static const value_string bo05_bootdev_vals[] = { + { 0x00, "No override" }, + { 0x01, "Force PXE" }, + { 0x02, "Force boot from default Hard-drive" }, + { 0x03, "Force boot from default Hard-drive, request Safe Mode" }, + { 0x04, "Force boot from default Diagnostic Partition" }, + { 0x05, "Force boot from default CD/DVD" }, + { 0x06, "Force boot into BIOS Setup" }, + { 0x07, "Reserved" }, + { 0x08, "Reserved" }, + { 0x09, "Reserved" }, + { 0x0a, "Reserved" }, + { 0x0b, "Reserved" }, + { 0x0c, "Reserved" }, + { 0x0d, "Reserved" }, + { 0x0e, "Reserved" }, + { 0x0f, "Force boot from floppy/primary removable media" }, + { 0, NULL } +}; + +static const value_string bo05_bios_verbosity_vals[] = { + { 0x00, "System default" }, + { 0x01, "Request quiet display" }, + { 0x02, "Request verbose display" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const value_string bo05_console_redir_vals[] = { + { 0x00, "Console redirection occurs per BIOS configuration setting" }, + { 0x01, "Suppress (skip) console redirection" }, + { 0x02, "Request console redirection be enabled" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string bo05_bios_shared_tfs = { + "Request BIOS to temporarily set the access mode for the channel specified in parameter #6 to 'Shared'", + "No request to BIOS to change present access mode setting" +}; + +static const value_string bo05_bios_muxctl_vals[] = { + { 0x00, "BIOS uses recommended setting of the mux at the end of POST" }, + { 0x01, "Requests BIOS to force mux to BMC at conclusion of POST/start of OS boot" }, + { 0x02, "Requests BIOS to force mux to system at conclusion of POST/start of OSboot" }, + { 0x03, "Reserved" }, + { 0x04, "Reserved" }, + { 0x05, "Reserved" }, + { 0x06, "Reserved" }, + { 0x07, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_09_valid = { + "Parameter marked invalid / locked", + "Parameter marked valid / unlocked" +}; + +/* Boot options - common for Get/Set Boot Options commands + */ +static void +bootopt_00(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_bo00_sip, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_chs_bo00_byte1, byte1, + TRUE, 0); +} + +static void +bootopt_01(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_chs_bo01_spsel, tvb, 0, 1, TRUE); +} + +static void +bootopt_02(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_bo02_request, &hf_ipmi_chs_bo02_discovered, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Service partition scan: ", + "Not discovered", ett_ipmi_chs_bo02_byte1, byte1, TRUE, 0); +} + +static void +bootopt_03(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_bo03_pef, &hf_ipmi_chs_bo03_cctrl_timeout, + &hf_ipmi_chs_bo03_wd_timeout, &hf_ipmi_chs_bo03_softreset, &hf_ipmi_chs_bo03_powerup, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "BMC boot flag valid, don't clear on: ", + "None", ett_ipmi_chs_bo03_byte1, byte1, TRUE, BMT_NO_TFS); +} + +static void +bootopt_04(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_chs_bo04_bootinit_ack_oem, &hf_ipmi_chs_bo04_bootinit_ack_sms, + &hf_ipmi_chs_bo04_bootinit_ack_os, &hf_ipmi_chs_bo04_bootinit_ack_osloader, + &hf_ipmi_chs_bo04_bootinit_ack_bios, NULL }; + + proto_tree_add_item(tree, hf_ipmi_chs_bo04_write_mask, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Boot Initiator Acknowledge data: ", + "None", ett_ipmi_chs_bo04_byte2, byte2, TRUE, BMT_NO_TFS); +} + +static void +bootopt_05(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_bo05_bootflags_valid, + &hf_ipmi_chs_bo05_permanent, &hf_ipmi_chs_bo05_boottype, NULL }; + static const int *byte2[] = { &hf_ipmi_chs_bo05_cmos_clear, &hf_ipmi_chs_bo05_lock_kbd, + &hf_ipmi_chs_bo05_bootdev, &hf_ipmi_chs_bo05_screen_blank, &hf_ipmi_chs_bo05_lockout_reset, NULL }; + static const int *byte3[] = { &hf_ipmi_chs_bo05_lockout_poweroff, &hf_ipmi_chs_bo05_bios_verbosity, + &hf_ipmi_chs_bo05_progress_traps, &hf_ipmi_chs_bo05_pwd_bypass, &hf_ipmi_chs_bo05_lock_sleep, + &hf_ipmi_chs_bo05_console_redirection, NULL }; + static const int *byte4[] = { &hf_ipmi_chs_bo05_bios_shared_override, + &hf_ipmi_chs_bo05_bios_muxctl_override, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_chs_bo05_byte1, + byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_chs_bo05_byte2, + byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_chs_bo05_byte3, + byte3, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, NULL, NULL, ett_ipmi_chs_bo05_byte4, + byte4, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_chs_bo05_byte5, tvb, 4, 1, TRUE); +} + +static void +bootopt_06(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_bo06_chan_num, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_chs_bo06_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_chs_bo06_session_id, tvb, 1, 4, TRUE); + ipmi_add_timestamp(tree, hf_ipmi_chs_bo06_bootinfo_timestamp, tvb, 5); +} + +static void +bootopt_07(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_selector, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_data, tvb, 1, tvb_length(tvb) - 1, TRUE); +} + + +static struct { + void (*intrp)(tvbuff_t *tvb, proto_tree *tree); + const char *name; +} boot_options[] = { + { bootopt_00, "Set In Progress" }, + { bootopt_01, "Service Partition Selector" }, + { bootopt_02, "Service Partition Scan" }, + { bootopt_03, "BMC boot flag valid bit clearing" }, + { bootopt_04, "Boot info acknowledge" }, + { bootopt_05, "Boot flags" }, + { bootopt_06, "Boot initiator info" }, + { bootopt_07, "Boot initiator mailbox" } +}; + + +/* Get Chassis Capabilities (response) + */ +static void +rs00(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_00_capflags_ppi, &hf_ipmi_chs_00_capflags_di, + &hf_ipmi_chs_00_capflags_fpl, &hf_ipmi_chs_00_capflags_is, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Capabilities: ", "None", + ett_ipmi_chs_00_capflags, byte1, TRUE, BMT_NO_TFS); + proto_tree_add_item(tree, hf_ipmi_chs_00_fru_dev_addr, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_00_sdr_dev_addr, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_00_sel_dev_addr, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_00_sm_dev_addr, tvb, 4, 1, TRUE); + + if (tvb_length(tvb) >= 5) { + proto_tree_add_item(tree, hf_ipmi_chs_00_bridge_dev_addr, tvb, 5, 1, TRUE); + } +} + +/* Get Chassis Status. + */ +static void +rs01(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_01_pwr_state_policy, + &hf_ipmi_chs_01_pwr_state_ctl_fault, &hf_ipmi_chs_01_pwr_state_fault, + &hf_ipmi_chs_01_pwr_state_ilock, &hf_ipmi_chs_01_pwr_state_overload, + &hf_ipmi_chs_01_pwr_state_powered, NULL }; + static const int *byte2[] = { &hf_ipmi_chs_01_last_event_via_ipmi, + &hf_ipmi_chs_01_last_event_down_by_fault, &hf_ipmi_chs_01_last_event_interlock, + &hf_ipmi_chs_01_last_event_overload, &hf_ipmi_chs_01_last_event_ac_failed, NULL }; + static const int *byte3[] = { &hf_ipmi_chs_01_misc_identsupp, &hf_ipmi_chs_01_misc_identstate, + &hf_ipmi_chs_01_misc_fan, &hf_ipmi_chs_01_misc_drive, &hf_ipmi_chs_01_misc_fpl_active, + &hf_ipmi_chs_01_misc_intrusion, NULL }; + static const int *byte4[] = { &hf_ipmi_chs_01_fpb_standby_allowed, + &hf_ipmi_chs_01_fpb_diagintr_allowed, &hf_ipmi_chs_01_fpb_reset_allowed, + &hf_ipmi_chs_01_fpb_poweroff_allowed, &hf_ipmi_chs_01_fpb_standby_disabled, + &hf_ipmi_chs_01_fpb_diagintr_disabled, &hf_ipmi_chs_01_fpb_reset_disabled, + &hf_ipmi_chs_01_fpb_poweroff_disabled, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Current Power State: ", NULL, + ett_ipmi_chs_01_pwr_state, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Last Power Event: ", NULL, + ett_ipmi_chs_01_last_event, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, "Misc. State: ", NULL, + ett_ipmi_chs_01_misc, byte3, TRUE, 0); + if (tvb_length(tvb) > 3) { + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Front panel buttons capabilities: ", + NULL, ett_ipmi_chs_01_fpb, byte4, TRUE, BMT_NO_TFS); + }; +} + +/* Chassis Control. + */ +static void +rq02(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_02_cctrl, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_chs_02_byte1, byte1, TRUE, 0); +} + +/* Chassis Identify + */ +static void +rq04(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_chs_04_perm_on, NULL }; + + if (tvb_length(tvb) > 0) { + proto_tree_add_item(tree, hf_ipmi_chs_04_ival, tvb, 0, 1, TRUE); + } + + if (tvb_length(tvb) > 1) { + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Flags: ", "None", + ett_ipmi_chs_04_byte2, byte2, TRUE, 0); + } +} + +/* Set Chassis Capabilities. + */ +static void +rq05(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_05_flags_fpl, &hf_ipmi_chs_05_flags_intrusion, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Capabilities: ", "None", + ett_ipmi_chs_05_flags, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_chs_05_fru_dev_addr, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_05_sdr_dev_addr, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_05_sel_dev_addr, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_05_sm_dev_addr, tvb, 4, 1, TRUE); + if (tvb_length(tvb) > 5) { + /* Bridge device address is optional */ + proto_tree_add_item(tree, hf_ipmi_chs_05_bridge_dev_addr, tvb, 5, 1, TRUE); + } +} + +/* Set Power Restore Policy + */ +static void +rq06(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_06_rq_policy, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_chs_06_byte1, byte1, TRUE, 0); +} + +/* Get Power Restore Policy + */ +static void +rs06(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_06_rs_policy_support_powerup, + &hf_ipmi_chs_06_rs_policy_support_restore, &hf_ipmi_chs_06_rs_policy_support_poweroff, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Power Restore Policy support: ", "None", + ett_ipmi_chs_06_policy_support, byte1, TRUE, BMT_NO_TFS); +} + +/* Get System Restart Cause + */ +static void +rs07(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_07_cause, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_chs_07_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_chs_07_chan, tvb, 1, 1, TRUE); +} + +/* Set System Boot Options + */ +static void +rq08(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree; + tvbuff_t *sub; + guint8 pno; + const char *desc; + + pno = tvb_get_guint8(tvb, 0) & 0x7f; + if (pno < array_length(boot_options)) { + desc = boot_options[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + ti = proto_tree_add_text(tree, tvb, 0, 1, + "Boot option parameter selector: %s (0x%02x)", + desc, pno); + s_tree = proto_item_add_subtree(ti, ett_ipmi_chs_08_byte1); + proto_tree_add_item(s_tree, hf_ipmi_chs_08_valid, tvb, 0, 1, TRUE); + proto_tree_add_uint_format(s_tree, hf_ipmi_chs_08_selector, tvb, 0, 1, + pno, "%sBoot option parameter selector: %s (0x%02x)", + ipmi_dcd8(pno, 0x7f), desc, pno); + + /* Data is optional; no data means 'just set validity' */ + if (tvb_length(tvb) > 1) { + if (pno < array_length(boot_options)) { + sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + boot_options[pno].intrp(sub, tree); + } else { + proto_tree_add_none_format(tree, hf_ipmi_chs_08_data, tvb, 1, + tvb_length(tvb) - 1, "Parameter data: %s", desc); + } + } +} + +static const value_string cc08[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0, NULL } +}; + +/* Get System Boot Options + */ +static void +rq09(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree; + guint8 pno; + const char *desc; + + pno = tvb_get_guint8(tvb, 0) & 0x7f; + if (pno < array_length(boot_options)) { + desc = boot_options[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + + ti = proto_tree_add_text(tree, tvb, 0, 1, + "Boot option parameter selector: %s (0x%02x)", + desc, pno); + s_tree = proto_item_add_subtree(ti, ett_ipmi_chs_09_rq_byte1); + proto_tree_add_uint_format(s_tree, hf_ipmi_chs_09_rq_param_select, tvb, 0, 1, + pno, "%sBoot option parameter selector: %s (0x%02x)", + ipmi_dcd8(pno, 0x7f), desc, pno); + + proto_tree_add_item(tree, hf_ipmi_chs_09_rq_set_select, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_09_rq_block_select, tvb, 2, 1, TRUE); +} + +static void +rs09(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_chs_09_rs_param_version, NULL }; + proto_item *ti; + proto_tree *s_tree; + tvbuff_t *sub; + guint8 pno; + const char *desc; + + pno = tvb_get_guint8(tvb, 1) & 0x7f; + if (pno < array_length(boot_options)) { + desc = boot_options[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_chs_09_rs_byte1, byte1, TRUE, 0); + + ti = proto_tree_add_text(tree, tvb, 1, 1, + "Boot option parameter selector: %s (0x%02x)", + desc, pno); + s_tree = proto_item_add_subtree(ti, ett_ipmi_chs_09_rs_byte2); + proto_tree_add_item(s_tree, hf_ipmi_chs_09_rs_valid, tvb, 1, 1, TRUE); + proto_tree_add_uint_format(s_tree, hf_ipmi_chs_09_rs_param_select, tvb, 1, 1, + pno, "%sBoot option parameter selector: %s (0x%02x)", + ipmi_dcd8(pno, 0x7f), desc, pno); + + if (pno < array_length(boot_options)) { + sub = tvb_new_subset(tvb, 2, tvb_length(tvb) - 2, tvb_length(tvb) - 2); + boot_options[pno].intrp(sub, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_chs_09_rs_param_data, tvb, 2, + tvb_length(tvb) - 2, TRUE); + } +} + +static const value_string cc09[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +/* Get POH Counter + */ +static void +rs0f(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_chs_0f_minpercnt, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_chs_0f_counter, tvb, 1, 4, TRUE); +} + +static ipmi_cmd_t cmd_chassis[] = { + /* Chassis commands */ + { 0x00, NULL, rs00, NULL, NULL, "Get Chassis Capabilities", 0 }, + { 0x01, NULL, rs01, NULL, NULL, "Get Chassis Status", 0 }, + { 0x02, rq02, NULL, NULL, NULL, "Chassis Control", 0 }, + { 0x03, NULL, NULL, NULL, NULL, "Chassis Reset", 0 }, + { 0x04, rq04, NULL, NULL, NULL, "Chassis Identify", 0 }, + { 0x05, rq05, NULL, NULL, NULL, "Set Chassis Capabilities", 0 }, + { 0x06, rq06, rs06, NULL, NULL, "Set Power Restore Policy", 0 }, + { 0x07, NULL, rs07, NULL, NULL, "Get System Restart Cause", 0 }, + { 0x08, rq08, NULL, cc08, NULL, "Set System Boot Options", 0 }, + { 0x09, rq09, rs09, cc09, NULL, "Get System Boot Options", 0 }, + { 0x0a, IPMI_TBD, NULL, NULL, "Set Front Panel Buttons Enables", 0 }, + { 0x0b, IPMI_TBD, NULL, NULL, "Set Power Cycle Interval", 0 }, + { 0x0f, NULL, rs0f, NULL, NULL, "Get POH Counter", 0 }, +}; + +void +ipmi_register_chassis(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_chs_bo00_sip, + { "Set In Progress", + "ipmi.bootopt00.sip", FT_UINT8, BASE_HEX, bo00_sip_vals, 0x03, "", HFILL }}, + { &hf_ipmi_chs_bo01_spsel, + { "Service Partition Selector", + "ipmi.bootopt01.spsel", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo02_request, + { "Request BIOS to scan for specified service partition", + "ipmi.bootopt02.spscan.request", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_bo02_discovered, + { "Service Partition discovered", + "ipmi.bootopt02.spscan.discovered", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_bo03_pef, + { "Reset/power cycle caused by PEF", + "ipmi.bootopt03.bmcboot.pef", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x10, "", HFILL }}, + { &hf_ipmi_chs_bo03_cctrl_timeout, + { "Chassis Control command not received within 60s timeout", + "ipmi.bootopt03.bmcboot.cctrl_timeout", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_chs_bo03_wd_timeout, + { "Reset/power cycle caused by watchdog timeout", + "ipmi.bootopt03.bmcboot.wd_timeout", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_chs_bo03_softreset, + { "Pushbutton reset / soft reset", + "ipmi.bootopt03.bmcboot.softreset", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_chs_bo03_powerup, + { "Power up via pushbutton or wake event", + "ipmi.bootopt03.bmcboot.powerup", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_chs_bo04_write_mask, + { "Write mask", + "ipmi.bootopt04.write_mask", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo04_bootinit_ack_oem, + { "OEM", + "ipmi.bootopt04.bootinit_ack.oem", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x10, "", HFILL }}, + { &hf_ipmi_chs_bo04_bootinit_ack_sms, + { "SMS", + "ipmi.bootopt04.bootinit_ack.sms", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_chs_bo04_bootinit_ack_os, + { "OS / Service Partition", + "ipmi.bootopt04.bootinit_ack.os", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_chs_bo04_bootinit_ack_osloader, + { "OS Loader", + "ipmi.bootopt04.bootinit_ack.osloader", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_chs_bo04_bootinit_ack_bios, + { "BIOS/POST", + "ipmi.bootopt04.bootinit_ack.bios", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_chs_bo05_bootflags_valid, + { "Boot flags valid", + "ipmi.bootopt05.boot_flags_valid", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_chs_bo05_permanent, + { "Permanency", + "ipmi.bootopt05.permanent", FT_BOOLEAN, 8, TFS(&bo05_permanent_tfs), 0x40, "", HFILL }}, + { &hf_ipmi_chs_bo05_boottype, + { "Boot type", + "ipmi.bootopt05.boottype", FT_BOOLEAN, 8, TFS(&bo05_boottype_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_chs_bo05_cmos_clear, + { "CMOS Clear", + "ipmi.bootopt05.cmos_clear", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_chs_bo05_lock_kbd, + { "Lock Keyboard", + "ipmi.bootopt05.lock_kbd", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_chs_bo05_bootdev, + { "Boot Device Selector", + "ipmi.bootopt05.bootdev", FT_UINT8, BASE_HEX, bo05_bootdev_vals, 0x3c, "", HFILL }}, + { &hf_ipmi_chs_bo05_screen_blank, + { "Screen Blank", + "ipmi.bootopt05.screen_blank", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_bo05_lockout_reset, + { "Lock out Reset buttons", + "ipmi.bootopt05.lockout_reset", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_bo05_lockout_poweroff, + { "Lock out (power off / sleep request) via Power Button", + "ipmi.bootopt05.lockout_poweroff", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_chs_bo05_bios_verbosity, + { "BIOS verbosity", + "ipmi.bootopt05.bios_verbosity", FT_UINT8, BASE_HEX, bo05_bios_verbosity_vals, 0x60, "", HFILL }}, + { &hf_ipmi_chs_bo05_progress_traps, + { "Force Progress Event Traps", + "ipmi.bootopt05.progress_traps", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_chs_bo05_pwd_bypass, + { "User password bypass", + "ipmi.bootopt05.pwd_bypass", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_chs_bo05_lock_sleep, + { "Lock Out Sleep Button", + "ipmi.bootopt05.lock_sleep", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_chs_bo05_console_redirection, + { "Console redirection", + "ipmi.bootopt05.console_redirection", FT_UINT8, BASE_HEX, bo05_console_redir_vals, 0x03, "", HFILL }}, + { &hf_ipmi_chs_bo05_bios_shared_override, + { "BIOS Shared Mode Override", + "ipmi.bootopt05.bios_shared_override", FT_BOOLEAN, 8, TFS(&bo05_bios_shared_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_chs_bo05_bios_muxctl_override, + { "BIOS Mux Control Override", + "ipmi.bootopt05.bios_muxctl_override", FT_UINT8, BASE_HEX, bo05_bios_muxctl_vals, 0x07, "", HFILL }}, + { &hf_ipmi_chs_bo05_byte5, + { "Data 5 (reserved)", + "ipmi.bootopt05.byte5", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo06_chan_num, + { "Channel", + "ipmi.bootopt06.chan_num", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_chs_bo06_session_id, + { "Session ID", + "ipmi.bootopt06.session_id", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo06_bootinfo_timestamp, + { "Boot Info Timestamp", + "impi.bootopt06.bootinfo_timestamp", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo07_block_selector, + { "Block selector", + "ipmi.bootopt07.block_selector", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_bo07_block_data, + { "Block data", + "ipmi.bootopt07.block_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_chs_00_capflags_ppi, + { "Power interlock", + "ipmi.ch00.cap.power_interlock", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x08, "", HFILL }}, + { &hf_ipmi_chs_00_capflags_di, + { "Diagnostic Interrupt", + "ipmi.ch00.cap.diag_int", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x04, "", HFILL }}, + { &hf_ipmi_chs_00_capflags_fpl, + { "Front Panel Lockout", + "ipmi.ch00.cap.fpl", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x02, "", HFILL }}, + { &hf_ipmi_chs_00_capflags_is, + { "Intrusion sensor", + "ipmi.ch00.cap.intrusion", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x01, "", HFILL }}, + { &hf_ipmi_chs_00_fru_dev_addr, + { "Chassis FRU Info Device Address", + "ipmi.ch00.fru_info", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_00_sdr_dev_addr, + { "Chassis SDR Device Address", + "ipmi.ch00.sdr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_00_sel_dev_addr, + { "Chassis SEL Device Address", + "ipmi.ch00.sel", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_00_sm_dev_addr, + { "Chassis System Management Device Address", + "ipmi.ch00.sm", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_00_bridge_dev_addr, + { "Chassis Bridge Device Address", + "ipmi.ch00.bridge", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_chs_01_pwr_state_policy, + { "Power Restore Policy", + "ipmi.ch01.cur_pwr.policy", FT_UINT8, BASE_HEX, vals_01_pwr_policy, 0x60, "", HFILL }}, + { &hf_ipmi_chs_01_pwr_state_ctl_fault, + { "Power Control Fault", + "ipmi.ch01.cur_pwr.ctl_fault", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_chs_01_pwr_state_fault, + { "Power Fault", + "ipmi.ch01.cur_pwr.fault", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_chs_01_pwr_state_ilock, + { "Interlock", + "ipmi.ch01.cur_pwr.interlock", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_chs_01_pwr_state_overload, + { "Overload", + "ipmi.ch01.cur_pwr.overload", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_01_pwr_state_powered, + { "Power is on", + "ipmi.ch01.cur_pwr.powered", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_01_last_event_via_ipmi, + { "Last `Power is on' state was entered via IPMI command", + "ipmi.ch01.last.on_via_ipmi", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_chs_01_last_event_down_by_fault, + { "Last power down caused by power fault", + "ipmi.ch01.last.down_by_fault", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_chs_01_last_event_interlock, + { "Last power down caused by a power interlock being activated", + "ipmi.ch01.last.interlock", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_chs_01_last_event_overload, + { "Last power down caused by a power overload", + "ipmi.ch01.last.overload", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_01_last_event_ac_failed, + { "AC failed", + "ipmi.ch01.last.ac_failed", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_01_misc_identsupp, + { "Chassis Identify command and state info supported", + "ipmi.ch01.identsupp", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_chs_01_misc_identstate, + { "Chassis Identify state (if supported)", + "ipmi.ch01.identstate", FT_UINT8, BASE_HEX, vals_01_identstate, 0x30, "", HFILL }}, + { &hf_ipmi_chs_01_misc_fan, + { "Cooling/fan fault detected", + "ipmi.ch01.misc.fan", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_chs_01_misc_drive, + { "Drive Fault", + "ipmi.ch01.misc.drive", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_chs_01_misc_fpl_active, + { "Front Panel Lockout active", + "ipmi.ch01.misc.fpl_active", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_01_misc_intrusion, + { "Chassis intrusion active", + "ipmi.ch01.misc.intrusion", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_standby_allowed, + { "Standby disable allowed", + "ipmi.ch01.fpb.standby_allowed", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_diagintr_allowed, + { "Diagnostic interrupt disable allowed", + "ipmi.ch01.fpb.diagintr_allowed", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_reset_allowed, + { "Reset disable allowed", + "ipmi.ch01.fpb.reset_allowed", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_poweroff_allowed, + { "Poweroff disable allowed", + "ipmi.ch01.fpb.poweroff_allowed", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_standby_disabled, + { "Standby disabled", + "ipmi.ch01.fpb.standby_disabled", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_diagintr_disabled, + { "Diagnostic interrupt disabled", + "ipmi.ch01.fpb.diagintr_disabled", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_reset_disabled, + { "Reset disabled", + "ipmi.ch01.fpb.reset_disabled", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_01_fpb_poweroff_disabled, + { "Poweroff disabled", + "ipmi.ch01.fpb.poweroff_disabled", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_chs_02_cctrl, + { "Chassis Control", + "ipmi.ch02.chassis_control", FT_UINT8, BASE_HEX, vals_02_cctrl, 0x0f, "", HFILL }}, + + { &hf_ipmi_chs_04_ival, + { "Identify Interval in seconds", + "ipmi.ch04.interval", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_chs_04_perm_on, + { "Turn on Identify indefinitely", + "ipmi.ch04.perm_on", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_chs_05_flags_fpl, + { "Provides Front Panel Lockout", + "ipmi.ch05.flags.fpl", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_chs_05_flags_intrusion, + { "Provides intrusion sensor", + "ipmi.ch05.flags.intrusion", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_chs_05_fru_dev_addr, + { "Chassis FRU Info Device Address", + "ipmi.ch05.fru_info", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_05_sdr_dev_addr, + { "Chassis SDR Device Address", + "ipmi.ch05.sdr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_05_sel_dev_addr, + { "Chassis SEL Device Address", + "ipmi.ch05.sel", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_05_sm_dev_addr, + { "Chassis System Management Device Address", + "ipmi.ch05.sm", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_05_bridge_dev_addr, + { "Chassis Bridge Device Address", + "ipmi.ch05.bridge", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_chs_06_rq_policy, + { "Power Restore Policy", + "ipmi.ch06.rq_policy", FT_UINT8, BASE_HEX, vals_06_policy, 0x07, "", HFILL }}, + { &hf_ipmi_chs_06_rs_policy_support_powerup, + { "Always powering up", + "ipmi.ch06.rs_support.powerup", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x04, "", HFILL }}, + { &hf_ipmi_chs_06_rs_policy_support_restore, + { "Restoring previous state", + "ipmi.ch06.rs_support.restore", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x02, "", HFILL }}, + { &hf_ipmi_chs_06_rs_policy_support_poweroff, + { "Staying powered off", + "ipmi.ch06.rs_support.poweroff", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x01, "", HFILL }}, + + { &hf_ipmi_chs_07_cause, + { "Restart Cause", + "ipmi.ch07.cause", FT_UINT8, BASE_HEX, vals_07_cause, 0x0f, "", HFILL }}, + { &hf_ipmi_chs_07_chan, + { "Channel", + "ipmi.ch07.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0, "", HFILL }}, + + { &hf_ipmi_chs_08_valid, + { "Validity", + "ipmi.ch08.valid", FT_BOOLEAN, 8, TFS(&tfs_08_valid), 0x80, "", HFILL }}, + { &hf_ipmi_chs_08_selector, + { "Boot option parameter selector", + "ipmi.ch08.selector", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_chs_08_data, + { "Boot option parameter data", + "ipmi.ch08.data", FT_NONE, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_chs_09_rq_param_select, + { "Parameter selector", + "ipmi.ch09.rq_param_select", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_chs_09_rq_set_select, + { "Set Selector", + "ipmi.ch09.rq_set_select", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_09_rq_block_select, + { "Block Selector", + "ipmi.ch09.rq_block_select", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_09_rs_param_version, + { "Parameter Version", + "ipmi.ch09.rs_param_version", FT_UINT8, BASE_HEX, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_chs_09_rs_valid, + { "Parameter Valid", + "ipmi.ch09.rs_valid", FT_BOOLEAN, 8, TFS(&tfs_09_valid), 0x80, "", HFILL }}, + { &hf_ipmi_chs_09_rs_param_select, + { "Parameter Selector", + "ipmi.ch09.rs_param_select", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_chs_09_rs_param_data, + { "Configuration parameter data", + "ipmi.ch09.rs_param_data", FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_chs_0f_minpercnt, + { "Minutes per count", + "ipmi.ch0f.minpercnt", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_chs_0f_counter, + { "Counter reading", + "ipmi.ch0f.counter", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + }; + + static gint *ett[] = { + &ett_ipmi_chs_bo00_byte1, + &ett_ipmi_chs_bo02_byte1, + &ett_ipmi_chs_bo03_byte1, + &ett_ipmi_chs_bo04_byte2, + &ett_ipmi_chs_bo05_byte1, + &ett_ipmi_chs_bo05_byte2, + &ett_ipmi_chs_bo05_byte3, + &ett_ipmi_chs_bo05_byte4, + &ett_ipmi_chs_bo06_byte1, + &ett_ipmi_chs_00_capflags, + &ett_ipmi_chs_01_pwr_state, + &ett_ipmi_chs_01_last_event, + &ett_ipmi_chs_01_misc, + &ett_ipmi_chs_01_fpb, + &ett_ipmi_chs_02_byte1, + &ett_ipmi_chs_04_byte2, + &ett_ipmi_chs_05_flags, + &ett_ipmi_chs_06_byte1, + &ett_ipmi_chs_06_policy_support, + &ett_ipmi_chs_07_byte1, + &ett_ipmi_chs_08_byte1, + &ett_ipmi_chs_09_rq_byte1, + &ett_ipmi_chs_09_rs_byte1, + &ett_ipmi_chs_09_rs_byte2, + }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_CHASSIS_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_chassis, array_length(cmd_chassis)); +} diff --git a/epan/dissectors/packet-ipmi-picmg.c b/epan/dissectors/packet-ipmi-picmg.c new file mode 100644 index 0000000000..f259e39113 --- /dev/null +++ b/epan/dissectors/packet-ipmi-picmg.c @@ -0,0 +1,2315 @@ +/* packet-ipmi-picmg.c + * Sub-dissectors for IPMI messages (netFn=Group, defining body = PICMG) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static gint ett_ipmi_picmg_led_color = -1; +static gint ett_ipmi_picmg_link_info = -1; +static gint ett_ipmi_picmg_05_byte1 = -1; +static gint ett_ipmi_picmg_06_byte1 = -1; +static gint ett_ipmi_picmg_06_byte2 = -1; +static gint ett_ipmi_picmg_06_byte3 = -1; +static gint ett_ipmi_picmg_08_byte1 = -1; +static gint ett_ipmi_picmg_09_ipmba = -1; +static gint ett_ipmi_picmg_09_ipmbb = -1; +static gint ett_ipmi_picmg_0a_byte2 = -1; +static gint ett_ipmi_picmg_0a_byte3 = -1; +static gint ett_ipmi_picmg_0b_byte1 = -1; +static gint ett_ipmi_picmg_0f_chan = -1; +static gint ett_ipmi_picmg_12_byte1 = -1; +static gint ett_ipmi_picmg_14_prop = -1; +static gint ett_ipmi_picmg_1e_byte1 = -1; +static gint ett_ipmi_picmg_21_byte9 = -1; +static gint ett_ipmi_picmg_XX_compbits = -1; +static gint ett_ipmi_picmg_2e_byte2 = -1; +static gint ett_ipmi_picmg_prop00_byte1 = -1; +static gint ett_ipmi_picmg_prop01_byte1 = -1; +static gint ett_ipmi_picmg_34_byte3 = -1; +static gint ett_ipmi_picmg_36_byte2 = -1; +static gint ett_ipmi_picmg_37_byte2 = -1; + +static gint hf_ipmi_picmg_led_function = -1; +static gint hf_ipmi_picmg_led_on_duration = -1; +static gint hf_ipmi_picmg_led_color = -1; + +static gint hf_ipmi_picmg_linkinfo_grpid = -1; +static gint hf_ipmi_picmg_linkinfo_type_ext = -1; +static gint hf_ipmi_picmg_linkinfo_type = -1; +static gint hf_ipmi_picmg_linkinfo_ports = -1; +static gint hf_ipmi_picmg_linkinfo_iface = -1; +static gint hf_ipmi_picmg_linkinfo_chan = -1; +static gint hf_ipmi_picmg_linkinfo_state = -1; + +static gint hf_ipmi_picmg_00_version = -1; +static gint hf_ipmi_picmg_00_max_fruid = -1; +static gint hf_ipmi_picmg_00_ipmc_fruid = -1; + +static gint hf_ipmi_picmg_01_rq_fruid = -1; +static gint hf_ipmi_picmg_01_rq_addr_key_type = -1; +static gint hf_ipmi_picmg_01_rq_addr_key = -1; +static gint hf_ipmi_picmg_01_rq_site_type = -1; +static gint hf_ipmi_picmg_01_rs_hwaddr = -1; +static gint hf_ipmi_picmg_01_rs_ipmbaddr = -1; +static gint hf_ipmi_picmg_01_rs_rsrv = -1; +static gint hf_ipmi_picmg_01_rs_fruid = -1; +static gint hf_ipmi_picmg_01_rs_site_num = -1; +static gint hf_ipmi_picmg_01_rs_site_type = -1; + +static gint hf_ipmi_picmg_04_fruid = -1; +static gint hf_ipmi_picmg_04_cmd = -1; + +static gint hf_ipmi_picmg_05_fruid = -1; +static gint hf_ipmi_picmg_05_led3 = -1; +static gint hf_ipmi_picmg_05_led2 = -1; +static gint hf_ipmi_picmg_05_led1 = -1; +static gint hf_ipmi_picmg_05_blue_led = -1; +static gint hf_ipmi_picmg_05_app_leds = -1; + +static gint hf_ipmi_picmg_06_fruid = -1; +static gint hf_ipmi_picmg_06_ledid = -1; +static gint hf_ipmi_picmg_06_cap_white = -1; +static gint hf_ipmi_picmg_06_cap_orange = -1; +static gint hf_ipmi_picmg_06_cap_amber = -1; +static gint hf_ipmi_picmg_06_cap_green = -1; +static gint hf_ipmi_picmg_06_cap_red = -1; +static gint hf_ipmi_picmg_06_cap_blue = -1; +static gint hf_ipmi_picmg_06_default_local_color = -1; +static gint hf_ipmi_picmg_06_default_override_color = -1; + +static gint hf_ipmi_picmg_07_fruid = -1; +static gint hf_ipmi_picmg_07_ledid = -1; + +static gint hf_ipmi_picmg_08_fruid = -1; +static gint hf_ipmi_picmg_08_ledid = -1; +static gint hf_ipmi_picmg_08_state_lamptest = -1; +static gint hf_ipmi_picmg_08_state_override = -1; +static gint hf_ipmi_picmg_08_state_local = -1; +static gint hf_ipmi_picmg_08_lamptest_duration = -1; + +static gint hf_ipmi_picmg_09_ipmba = -1; +static gint hf_ipmi_picmg_09_ipmbb = -1; + +static gint hf_ipmi_picmg_0a_fruid = -1; +static gint hf_ipmi_picmg_0a_msk_d_locked = -1; +static gint hf_ipmi_picmg_0a_msk_locked = -1; +static gint hf_ipmi_picmg_0a_d_locked = -1; +static gint hf_ipmi_picmg_0a_locked = -1; + +static gint hf_ipmi_picmg_0b_fruid = -1; +static gint hf_ipmi_picmg_0b_d_locked = -1; +static gint hf_ipmi_picmg_0b_locked = -1; + +static gint hf_ipmi_picmg_0c_fruid = -1; +static gint hf_ipmi_picmg_0c_cmd = -1; + +static gint hf_ipmi_picmg_0d_fruid = -1; +static gint hf_ipmi_picmg_0d_start = -1; +static gint hf_ipmi_picmg_0d_recordid = -1; + +static gint hf_ipmi_picmg_0f_iface = -1; +static gint hf_ipmi_picmg_0f_chan = -1; + +static gint hf_ipmi_picmg_10_fruid = -1; +static gint hf_ipmi_picmg_10_nslots = -1; +static gint hf_ipmi_picmg_10_ipmc_loc = -1; + +static gint hf_ipmi_picmg_11_fruid = -1; +static gint hf_ipmi_picmg_11_power_level = -1; +static gint hf_ipmi_picmg_11_set_to_desired = -1; + +static gint hf_ipmi_picmg_12_fruid = -1; +static gint hf_ipmi_picmg_12_pwr_type = -1; +static gint hf_ipmi_picmg_12_dynamic = -1; +static gint hf_ipmi_picmg_12_pwr_lvl = -1; +static gint hf_ipmi_picmg_12_delay = -1; +static gint hf_ipmi_picmg_12_pwr_mult = -1; +static gint hf_ipmi_picmg_12_pwr_draw = -1; + +static gint hf_ipmi_picmg_13_fruid = -1; + +static gint hf_ipmi_picmg_14_fruid = -1; +static gint hf_ipmi_picmg_14_speed_min = -1; +static gint hf_ipmi_picmg_14_speed_max = -1; +static gint hf_ipmi_picmg_14_speed_norm = -1; +static gint hf_ipmi_picmg_14_local_control = -1; + +static gint hf_ipmi_picmg_15_fruid = -1; +static gint hf_ipmi_picmg_15_fan_level = -1; +static gint hf_ipmi_picmg_15_local_enable = -1; + +static gint hf_ipmi_picmg_16_fruid = -1; +static gint hf_ipmi_picmg_16_override_level = -1; +static gint hf_ipmi_picmg_16_local_level = -1; +static gint hf_ipmi_picmg_16_local_enable = -1; + +static gint hf_ipmi_picmg_17_cmd = -1; +static gint hf_ipmi_picmg_17_resid = -1; +static gint hf_ipmi_picmg_17_status = -1; + +static gint hf_ipmi_picmg_18_li_key_type = -1; +static gint hf_ipmi_picmg_18_li_key = -1; +static gint hf_ipmi_picmg_18_link_num = -1; +static gint hf_ipmi_picmg_18_sensor_num = -1; + +static gint hf_ipmi_picmg_1b_addr_active = -1; +static gint hf_ipmi_picmg_1b_addr_backup = -1; + +static gint hf_ipmi_picmg_1c_fan_site_number = -1; +static gint hf_ipmi_picmg_1c_fan_enable_state = -1; +static gint hf_ipmi_picmg_1c_fan_policy_timeout = -1; +static gint hf_ipmi_picmg_1c_site_number = -1; +static gint hf_ipmi_picmg_1c_site_type = -1; + +static gint hf_ipmi_picmg_1d_fan_site_number = -1; +static gint hf_ipmi_picmg_1d_site_number = -1; +static gint hf_ipmi_picmg_1d_site_type = -1; +static gint hf_ipmi_picmg_1d_policy = -1; +static gint hf_ipmi_picmg_1d_coverage = -1; + +static gint hf_ipmi_picmg_1e_fruid = -1; +static gint hf_ipmi_picmg_1e_cap_diagintr = -1; +static gint hf_ipmi_picmg_1e_cap_graceful_reboot = -1; +static gint hf_ipmi_picmg_1e_cap_warm_reset = -1; + +static gint hf_ipmi_picmg_1f_rq_fruid = -1; +static gint hf_ipmi_picmg_1f_rq_op = -1; +static gint hf_ipmi_picmg_1f_rq_lockid = -1; +static gint hf_ipmi_picmg_1f_rs_lockid = -1; +static gint hf_ipmi_picmg_1f_rs_tstamp = -1; + +static gint hf_ipmi_picmg_20_fruid = -1; +static gint hf_ipmi_picmg_20_lockid = -1; +static gint hf_ipmi_picmg_20_offset = -1; +static gint hf_ipmi_picmg_20_data = -1; +static gint hf_ipmi_picmg_20_count = -1; + +static gint hf_ipmi_picmg_21_addr_num = -1; +static gint hf_ipmi_picmg_21_tstamp = -1; +static gint hf_ipmi_picmg_21_addr_count = -1; +static gint hf_ipmi_picmg_21_site_type = -1; +static gint hf_ipmi_picmg_21_site_num = -1; +static gint hf_ipmi_picmg_21_max_unavail = -1; +static gint hf_ipmi_picmg_21_is_shm = -1; +static gint hf_ipmi_picmg_21_addr_type = -1; +static gint hf_ipmi_picmg_21_ipaddr = -1; +static gint hf_ipmi_picmg_21_rmcpport = -1; + +static gint hf_ipmi_picmg_22_feed_idx = -1; +static gint hf_ipmi_picmg_22_update_cnt = -1; +static gint hf_ipmi_picmg_22_pwr_alloc = -1; + +static gint hf_ipmi_picmg_XX_comp7 = -1; +static gint hf_ipmi_picmg_XX_comp6 = -1; +static gint hf_ipmi_picmg_XX_comp5 = -1; +static gint hf_ipmi_picmg_XX_comp4 = -1; +static gint hf_ipmi_picmg_XX_comp3 = -1; +static gint hf_ipmi_picmg_XX_comp2 = -1; +static gint hf_ipmi_picmg_XX_comp1 = -1; +static gint hf_ipmi_picmg_XX_comp0 = -1; + +static gint hf_ipmi_picmg_2e_version = -1; +static gint hf_ipmi_picmg_2e_upgrade_undesirable = -1; +static gint hf_ipmi_picmg_2e_auto_rollback_override = -1; +static gint hf_ipmi_picmg_2e_ipmc_degraded = -1; +static gint hf_ipmi_picmg_2e_deferred_activate = -1; +static gint hf_ipmi_picmg_2e_services_affected = -1; +static gint hf_ipmi_picmg_2e_manual_rollback = -1; +static gint hf_ipmi_picmg_2e_auto_rollback = -1; +static gint hf_ipmi_picmg_2e_self_test = -1; +static gint hf_ipmi_picmg_2e_upgrade_tout = -1; +static gint hf_ipmi_picmg_2e_selftest_tout = -1; +static gint hf_ipmi_picmg_2e_rollback_tout = -1; +static gint hf_ipmi_picmg_2e_inaccessibility_tout = -1; + +static gint hf_ipmi_picmg_prop00_cold_reset = -1; +static gint hf_ipmi_picmg_prop00_deferred_activation = -1; +static gint hf_ipmi_picmg_prop00_comparison = -1; +static gint hf_ipmi_picmg_prop00_preparation = -1; +static gint hf_ipmi_picmg_prop00_rollback = -1; +static gint hf_ipmi_picmg_prop01_fw_major = -1; +static gint hf_ipmi_picmg_prop01_fw_minor = -1; +static gint hf_ipmi_picmg_prop01_fw_aux = -1; +static gint hf_ipmi_picmg_prop02_desc = -1; + +static gint hf_ipmi_picmg_2f_comp_id = -1; +static gint hf_ipmi_picmg_2f_comp_prop = -1; +static gint hf_ipmi_picmg_2f_prop_data = -1; + +static gint hf_ipmi_picmg_31_action = -1; + +static gint hf_ipmi_picmg_32_block = -1; +static gint hf_ipmi_picmg_32_data = -1; +static gint hf_ipmi_picmg_32_sec_offs = -1; +static gint hf_ipmi_picmg_32_sec_len = -1; + +static gint hf_ipmi_picmg_33_comp_id = -1; +static gint hf_ipmi_picmg_33_img_len = -1; + +static gint hf_ipmi_picmg_34_cmd = -1; +static gint hf_ipmi_picmg_34_ccode = -1; +static gint hf_ipmi_picmg_34_percentage = -1; + +static gint hf_ipmi_picmg_35_rollback_override = -1; + +static gint hf_ipmi_picmg_36_result = -1; +static gint hf_ipmi_picmg_36_fail = -1; +static gint hf_ipmi_picmg_36_fail_sel = -1; +static gint hf_ipmi_picmg_36_fail_sdr = -1; +static gint hf_ipmi_picmg_36_fail_bmc_fru = -1; +static gint hf_ipmi_picmg_36_fail_ipmb_sig = -1; +static gint hf_ipmi_picmg_36_fail_sdr_empty = -1; +static gint hf_ipmi_picmg_36_fail_iua = -1; +static gint hf_ipmi_picmg_36_fail_bb_fw = -1; +static gint hf_ipmi_picmg_36_fail_oper_fw = -1; + +static gint hf_ipmi_picmg_37_percent = -1; + +static const value_string site_type_vals[] = { + { 0x00, "PICMG board" }, + { 0x01, "Power Entry" }, + { 0x02, "Shelf FRU Information" }, + { 0x03, "Dedicated ShMC" }, + { 0x04, "Fan Tray / Cooling Unit" }, + { 0x05, "Fan Filter Tray" }, + { 0x06, "Alarm" }, + { 0x07, "AdvancedMC module" }, + { 0x08, "PMC" }, + { 0x09, "Rear Transition Module" }, + { 0x0A, "MicroTCA Carrier Hub" }, + { 0x0B, "Power Module" }, + { 0xC0, "OEM" }, + { 0xC1, "OEM" }, + { 0xC2, "OEM" }, + { 0xC3, "OEM" }, + { 0xC4, "OEM" }, + { 0xC5, "OEM" }, + { 0xC6, "OEM" }, + { 0xC7, "OEM" }, + { 0xC8, "OEM" }, + { 0xC9, "OEM" }, + { 0xCA, "OEM" }, + { 0xCB, "OEM" }, + { 0xCC, "OEM" }, + { 0xCD, "OEM" }, + { 0xCE, "OEM" }, + { 0xCF, "OEM" }, + { 0, NULL } +}; + +static const value_string addr_key_type_vals[] = { + { 0x00, "Hardware Address" }, + { 0x01, "IPMB-0 Address" }, + { 0x03, "Physical Address" }, + { 0, NULL } +}; + +static const struct true_false_string set_clear_tfs = { + "Set", "Clear" +}; + +static const value_string led_color_vals[] = { + { 0x00, "Reserved (Control not supported)" }, + { 0x01, "Blue" }, + { 0x02, "Red" }, + { 0x03, "Green" }, + { 0x04, "Amber" }, + { 0x05, "Orange" }, + { 0x06, "White" }, + { 0x0E, "Do not change" }, + { 0x0F, "Use default" }, + { 0, NULL } +}; + +static const value_string linkinfo_type_vals[] = { + { 0x01, "PICMG3.0 Base Interface 10/100/1000 BASE-T" }, + { 0x02, "PICMG3.1 Ethernet Fabric Interface" }, + { 0x03, "PICMG3.2 Infiniband Fabric Interface" }, + { 0x04, "PICMG3.3 StarFabric Fabric Interface" }, + { 0x05, "PICMG3.4 PCI Express Fabric Interface" }, + { 0xf0, "OEM" }, { 0xf1, "OEM" }, { 0xf2, "OEM" }, { 0xf3, "OEM" }, + { 0xf4, "OEM" }, { 0xf5, "OEM" }, { 0xf6, "OEM" }, { 0xf7, "OEM" }, + { 0xf8, "OEM" }, { 0xf9, "OEM" }, { 0xfa, "OEM" }, { 0xfb, "OEM" }, + { 0xfc, "OEM" }, { 0xfd, "OEM" }, { 0xfe, "OEM" }, + + { 0, NULL } +}; + +static const value_string linkinfo_ports_vals[] = { + { 0x00, "None" }, + { 0x01, "0" }, + { 0x02, "1" }, + { 0x03, "0,1" }, + { 0x04, "2" }, + { 0x05, "0,2" }, + { 0x06, "1,2" }, + { 0x07, "0,1,2" }, + { 0x08, "3" }, + { 0x09, "0,3" }, + { 0x0a, "1,3" }, + { 0x0b, "0,1,3" }, + { 0x0c, "2,3" }, + { 0x0d, "0,2,3" }, + { 0x0e, "1,2,3" }, + { 0x0f, "0,1,2,3" }, + + { 0, NULL } +}; + +static const value_string linkinfo_iface_vals[] = { + { 0x00, "Base Interface" }, + { 0x01, "Fabric Interface" }, + { 0x02, "Update Channel Interface" }, + + { 0, NULL } +}; + +static const value_string busresid_vals[] = { + { 0x00, "Metallic Test Bus #1" }, + { 0x01, "Metallic Test Bus #2" }, + { 0x02, "Synch clock group #1" }, + { 0x03, "Synch clock group #2" }, + { 0x04, "Synch clock group #3" }, + { 0, NULL } +}; + +static const value_string fan_level_vals[] = { + { 0xFE, "Shut down" }, + { 0xFF, "Local control" }, + { 0, NULL } +}; + +static const value_string enable_vals[] = { + { 0x00, "Disable" }, + { 0x01, "Enable" }, + { 0, NULL } +}; + +static const value_string enabled_vals[] = { + { 0x00, "Disabled" }, + { 0x01, "Enabled" }, + { 0, NULL } +}; + +static const value_string vals_04_cmd[] = { + { 0x00, "Cold Reset" }, + { 0x01, "Warm Reset" }, + { 0x02, "Graceful Reboot" }, + { 0x03, "Issue Diagnostic Interrupt" }, + { 0x04, "Quiesce" }, + { 0, NULL } +}; + +static const value_string vals_0c_cmd[] = { + { 0x00, "Deactivate FRU" }, + { 0x01, "Activate FRU" }, + { 0, NULL } +}; + +static const value_string vals_11_set[] = { + { 0x00, "Do not change present levels" }, + { 0x01, "Copy desired levels to present levels" }, + { 0, NULL } +}; + +static const value_string vals_12_pwr_type[] = { + { 0x00, "Steady state power draw levels" }, + { 0x01, "Desired steady state draw levels" }, + { 0x02, "Early power draw levels" }, + { 0x03, "Desired early levels" }, + { 0, NULL } +}; + +static const value_string vals_18_keytype[] = { + { 0x00, "Link Info Key contains Link Number" }, + { 0x01, "Link Info Key contains Sensor Number" }, + { 0, NULL } +}; + +static const value_string vals_1d_policy[] = { + { 0x00, "Disabled" }, + { 0x01, "Enabled" }, + { 0xFF, "Indeterminate" }, + { 0, NULL } +}; + +static const value_string vals_1d_coverage[] = { + { 0x00, "Not Covered" }, + { 0x01, "Covered" }, + { 0, NULL } +}; + +static const value_string vals_1f_op[] = { + { 0x00, "Get Last Commit Timestamp" }, + { 0x01, "Lock" }, + { 0x02, "Unlock and Discard" }, + { 0x03, "Unlock and Commit" }, + { 0, NULL } +}; + +static const value_string vals_21_addr_type[] = { + { 0x01, "IPv4" }, + { 0x60, "OEM" }, { 0x61, "OEM" }, { 0x62, "OEM" }, { 0x63, "OEM" }, + { 0x64, "OEM" }, { 0x65, "OEM" }, { 0x66, "OEM" }, { 0x67, "OEM" }, + { 0x68, "OEM" }, { 0x69, "OEM" }, { 0x6a, "OEM" }, { 0x6b, "OEM" }, + { 0x6c, "OEM" }, { 0x6d, "OEM" }, { 0x6e, "OEM" }, { 0x6f, "OEM" }, + { 0x70, "OEM" }, { 0x71, "OEM" }, { 0x72, "OEM" }, { 0x73, "OEM" }, + { 0x74, "OEM" }, { 0x75, "OEM" }, { 0x76, "OEM" }, { 0x77, "OEM" }, + { 0x78, "OEM" }, { 0x79, "OEM" }, { 0x7a, "OEM" }, { 0x7b, "OEM" }, + { 0x7c, "OEM" }, { 0x7d, "OEM" }, { 0x7e, "OEM" }, { 0x7f, "OEM" }, + { 0, NULL } +}; + +static const value_string vals_prop00_rollback[] = { + { 0x00, "Not supported" }, + { 0x01, "Rollback supported, Backup required" }, + { 0x02, "Rollback supported, Backup not required" }, + { 0, NULL } +}; + +static const value_string vals_31_action[] = { + { 0x00, "Backup components" }, + { 0x01, "Prepare components" }, + { 0x02, "Upload for upgrade" }, + { 0x03, "Upload for compare" }, + { 0, NULL } +}; + +static const value_string vals_35_override[] = { + { 0x00, "Automatic Rollback allowed" }, + { 0x01, "Automatic Rollback override" }, + { 0, NULL } +}; + +static const value_string vals_36_result[] = { + { 0x55, "No error. All Self Tests Passed" }, + { 0x56, "Reserved, cannot be used" }, + { 0x57, "Corrupted or inaccesible data or devices" }, + { 0x58, "Fatal hardware error" }, + { 0x60, "Component failure" }, + { 0xff, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_36_fail_unknown = { + "Test failed", + "Unknown" +}; + +/* Get PICMG Properties. + */ +static void +rs00(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 v; + + v = tvb_get_guint8(tvb, 0); + proto_tree_add_item(tree, hf_ipmi_picmg_00_version, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_00_max_fruid, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_00_ipmc_fruid, tvb, 2, 1, TRUE); +} + +/* Get Address Info Command. + */ +static void +rq01(tvbuff_t *tvb, proto_tree *tree) +{ + if (tvb_length(tvb) > 0) { + proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_fruid, tvb, 0, 1, TRUE); + } + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_addr_key_type, tvb, 1, 1, TRUE); + } + if (tvb_length(tvb) > 2) { + proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_addr_key, tvb, 2, 1, TRUE); + } + if (tvb_length(tvb) > 3) { + proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_site_type, tvb, 3, 1, TRUE); + } +} + +static void +rs01(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_hwaddr, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_ipmbaddr, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_rsrv, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_fruid, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_site_num, tvb, 4, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_site_type, tvb, 5, 1, TRUE); + /* TBD Next byte is carrier number in MTCA */ +} + +/* Get Shelf Address Info + */ +static void +rs02(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_typelen(tree, "Shelf Address", tvb, 0, TRUE); +} + +/* Set Shelf Address Info + */ +static void +rq03(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_typelen(tree, "Shelf Address", tvb, 0, TRUE); +} + +/* FRU Control. + */ +static void +rq04(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_04_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_04_cmd, tvb, 1, 1, TRUE); +} + +/* Get FRU LED Properties + */ +static void +rq05(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_05_fruid, tvb, 0, 1, TRUE); +} + +static void +rs05(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_05_led3, &hf_ipmi_picmg_05_led2, + &hf_ipmi_picmg_05_led1, &hf_ipmi_picmg_05_blue_led, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "General Status LEDs: ", "None", + ett_ipmi_picmg_05_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_picmg_05_app_leds, tvb, 1, 1, TRUE); +} + +/* Get LED Color Capabilities + */ +static void +rq06(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_06_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_06_ledid, tvb, 1, 1, TRUE); +} + +static void +rs06(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_06_cap_white, &hf_ipmi_picmg_06_cap_orange, + &hf_ipmi_picmg_06_cap_amber, &hf_ipmi_picmg_06_cap_green, &hf_ipmi_picmg_06_cap_red, + &hf_ipmi_picmg_06_cap_blue, NULL }; + static const int *byte2[] = { &hf_ipmi_picmg_06_default_local_color, NULL }; + static const int *byte3[] = { &hf_ipmi_picmg_06_default_override_color, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Color capabilities: ", "None", + ett_ipmi_picmg_06_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_picmg_06_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, + ett_ipmi_picmg_06_byte3, byte3, TRUE, 0); +} + +static void +parse_led_state(proto_tree *tree, tvbuff_t *tvb, guint offs, const char *desc) +{ + static const int *color[] = { &hf_ipmi_picmg_led_color, NULL }; + static const value_string funcs[] = { + { 0x00, "LED Off override" }, + { 0xfb, "Lamp Test state" }, + { 0xfc, "Restore Local Control" }, + { 0xfd, "Reserved" }, + { 0xfe, "Reserved" }, + { 0xff, "LED On override" }, + { 0, NULL } + }; + proto_item *ti; + guint8 v; + + v = tvb_get_guint8(tvb, offs); + proto_tree_add_uint_format(tree, hf_ipmi_picmg_led_function, tvb, offs, 1, + v, "%sFunction: %s (0x%02x)", desc, + val_to_str(v, funcs, "LED Blinking override, off-duration %d0ms"), + v); + v = tvb_get_guint8(tvb, offs + 1); + proto_tree_add_uint_format(tree, hf_ipmi_picmg_led_on_duration, tvb, offs + 1, 1, + v, "%sOn-duration: %d0ms", desc, v); + v = tvb_get_guint8(tvb, offs + 2) & 0x0f; + ti = proto_tree_add_bitmask_text(tree, tvb, offs + 2, 1, + NULL, NULL, ett_ipmi_picmg_led_color, color, TRUE, 0); + proto_item_set_text(ti, "%sColor: %s", desc, val_to_str(v, led_color_vals, "Reserved")); +} + +/* Set FRU LED State + */ +static void +rq07(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_07_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_07_ledid, tvb, 1, 1, TRUE); + parse_led_state(tree, tvb, 2, ""); +} + +/* Get FRU LED State + */ +static void +rq08(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_08_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_08_ledid, tvb, 1, 1, TRUE); +} + +static void +rs08(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_08_state_lamptest, &hf_ipmi_picmg_08_state_override, + &hf_ipmi_picmg_08_state_local, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "LED States: ", "None", + ett_ipmi_picmg_08_byte1, byte1, TRUE, 0); + parse_led_state(tree, tvb, 1, "Local Control "); + if (tvb_length(tvb) > 4) { + parse_led_state(tree, tvb, 4, "Override "); + } + if (tvb_length(tvb) > 7) { + proto_tree_add_item(tree, hf_ipmi_picmg_08_lamptest_duration, tvb, 7, 1, TRUE); + } +} + +/* Set IPMB State + */ +static void +parse_ipmb_state(proto_tree *tree, tvbuff_t *tvb, guint offs, int hf, int ett) +{ + char buf[32]; + const char *desc; + proto_tree *s_tree; + proto_item *ti; + guint8 v, num; + + v = tvb_get_guint8(tvb, offs); + if (v == 0xff) { + proto_tree_add_uint_format_value(tree, hf, tvb, 0, 1, + v, "Don't change (0xff)"); + } else { + num = v >> 1; + if (!num) { + desc = "All Links"; + } else if (num < 0x60) { + g_snprintf(buf, sizeof(buf), "Link #%d", num); + desc = buf; + } else { + desc = "Reserved"; + } + ti = proto_tree_add_uint_format_value(tree, hf, tvb, 0, 1, + v, "%s, %s", desc, (v & 1) ? "Local Control" : "Override"); + s_tree = proto_item_add_subtree(ti, ett); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sLink: %s (0x%02x)", + ipmi_dcd8(v, 0xfe), desc, num); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sState: %s", + ipmi_dcd8(v, 0x01), (v & 1) ? "Local Control State" : "Override State (Isolate)"); + } +} + +static void +rq09(tvbuff_t *tvb, proto_tree *tree) +{ + parse_ipmb_state(tree, tvb, 0, hf_ipmi_picmg_09_ipmba, ett_ipmi_picmg_09_ipmba); + parse_ipmb_state(tree, tvb, 1, hf_ipmi_picmg_09_ipmbb, ett_ipmi_picmg_09_ipmbb); +} + +/* Set FRU Activation Policy + */ +static void +rq0a(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_picmg_0a_msk_d_locked, &hf_ipmi_picmg_0a_msk_locked, NULL }; + static const int *byte3[] = { &hf_ipmi_picmg_0a_d_locked, &hf_ipmi_picmg_0a_locked, NULL }; + + proto_tree_add_item(tree, hf_ipmi_picmg_0a_fruid, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Will affect bits: ", "None", + ett_ipmi_picmg_0a_byte2, byte2, TRUE, BMT_NO_TFS); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, "Activation Policy Set Bits: ", NULL, + ett_ipmi_picmg_0a_byte3, byte3, TRUE, 0); +} + +/* Get FRU Activation Policy + */ +static void +rq0b(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_0b_fruid, tvb, 0, 1, TRUE); +} + +static void +rs0b(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_0b_d_locked, &hf_ipmi_picmg_0b_locked, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Activation Policy Bits: ", NULL, + ett_ipmi_picmg_0b_byte1, byte1, TRUE, 0); +} + + +/* Set FRU Activation + */ +static void +rq0c(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_0c_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_0c_cmd, tvb, 1, 1, TRUE); +} + +/* Get Device Locator Record ID + */ +static void +rq0d(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_0d_fruid, tvb, 0, 1, TRUE); + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_picmg_0d_start, tvb, 1, 2, TRUE); + } +} + +static void +rs0d(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_0d_recordid, tvb, 0, 2, TRUE); +} + +static void +parse_link_info_state(proto_tree *tree, tvbuff_t *tvb, guint offs, const char *num, const value_string *vs) +{ + static const int *link_info[] = { &hf_ipmi_picmg_linkinfo_grpid, &hf_ipmi_picmg_linkinfo_type_ext, + &hf_ipmi_picmg_linkinfo_type, &hf_ipmi_picmg_linkinfo_ports, &hf_ipmi_picmg_linkinfo_iface, + &hf_ipmi_picmg_linkinfo_chan, NULL }; + guint8 v = tvb_get_guint8(tvb, offs + 4); + char buf[32]; + + g_snprintf(buf, sizeof(buf), "Link info%s: ", num); + proto_tree_add_bitmask_text(tree, tvb, offs, 4, buf, NULL, + ett_ipmi_picmg_link_info, link_info, TRUE, 0); + proto_tree_add_uint_format(tree, hf_ipmi_picmg_linkinfo_state, tvb, offs + 4, 1, + v, "State%s: %s (0x%02x)", num, val_to_str(v, vs, "Reserved"), v); +} + +/* Set Port State + */ +static void +rq0e(tvbuff_t *tvb, proto_tree *tree) +{ + static const value_string state_vals[] = { + { 0x00, "Disable" }, + { 0x01, "Enable" }, + { 0, NULL } + }; + + parse_link_info_state(tree, tvb, 0, "", state_vals); +} + +/* Get Port State + */ +static void +rq0f(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *chan[] = { &hf_ipmi_picmg_0f_iface, &hf_ipmi_picmg_0f_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_picmg_0f_chan, chan, TRUE, 0); +} + +static void +rs0f(tvbuff_t *tvb, proto_tree *tree) +{ + static const value_string state_vals[] = { + { 0x00, "Disabled" }, + { 0x01, "Enabled" }, + { 0, NULL } + }; + + if (tvb_length(tvb) > 0) { + parse_link_info_state(tree, tvb, 0, " 1", state_vals); + } + if (tvb_length(tvb) > 5) { + parse_link_info_state(tree, tvb, 5, " 2", state_vals); + } + if (tvb_length(tvb) > 10) { + parse_link_info_state(tree, tvb, 10, " 3", state_vals); + } + if (tvb_length(tvb) > 15) { + parse_link_info_state(tree, tvb, 15, " 4", state_vals); + } +} + +/* Compute Power Properties + */ +static void +rq10(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_10_fruid, tvb, 0, 1, TRUE); +} + +static void +rs10(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_10_nslots, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_10_ipmc_loc, tvb, 1, 1, TRUE); +} + +/* Set Power Level + */ +static void +rq11(tvbuff_t *tvb, proto_tree *tree) +{ + static const value_string plvl_vals[] = { + { 0x00, "Power Off" }, + { 0xff, "Do not change" }, + { 0, NULL } + }; + guint8 v = tvb_get_guint8(tvb, 1); + + proto_tree_add_item(tree, hf_ipmi_picmg_11_fruid, tvb, 0, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_11_power_level, tvb, 1, 1, + v, "%s", val_to_str(v, plvl_vals, "Power Level %d")); + proto_tree_add_item(tree, hf_ipmi_picmg_11_set_to_desired, tvb, 2, 1, TRUE); +} + +/* Get Power Level + */ +static void +rq12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_12_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_12_pwr_type, tvb, 1, 1, TRUE); +} + +static void +rs12(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_12_dynamic, &hf_ipmi_picmg_12_pwr_lvl, NULL }; + guint8 v, v2, i, max; + guint32 tmp; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_picmg_12_byte1, byte1, TRUE, BMT_NO_FALSE); + proto_tree_add_item(tree, hf_ipmi_picmg_12_delay, tvb, 1, 1, TRUE); + v = tvb_get_guint8(tvb, 2); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_12_pwr_mult, tvb, 2, 1, + v, "%d.%dW", v / 10, v % 10); + max = tvb_length(tvb) - 3; + if (max == 0) { + max = 1; /* One byte is mandatory */ + } else if (max > 20) { + max = 20; /* 20 levels at most */ + } + for (i = 1; i <= max; i++) { + v2 = tvb_get_guint8(tvb, 2 + i); + tmp = (guint)v2 * v; + proto_tree_add_uint_format(tree, hf_ipmi_picmg_12_pwr_draw, tvb, 2 + i, 1, + v2, "Power Draw [%d]: %d.%dW (0x%02x)", i, + tmp / 10, tmp % 10, v2); + + } +} + +/* Renegotiate Power + */ +static void +rq13(tvbuff_t *tvb, proto_tree *tree) +{ + if (tvb_length(tvb) > 0) { + proto_tree_add_item(tree, hf_ipmi_picmg_13_fruid, tvb, 0, 1, TRUE); + } +} + +/* Get Fan Speed Properties + */ +static void +rq14(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_14_fruid, tvb, 0, 1, TRUE); +} + +static void +rs14(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *prop[] = { &hf_ipmi_picmg_14_local_control, NULL }; + + proto_tree_add_item(tree, hf_ipmi_picmg_14_speed_min, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_14_speed_max, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_14_speed_norm, tvb, 2, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Fan Tray Properties: ", "None", + ett_ipmi_picmg_14_prop, prop, TRUE, 0); +} + +/* Set Fan Level + */ +static void +rq15(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 v = tvb_get_guint8(tvb, 1); + + proto_tree_add_item(tree, hf_ipmi_picmg_15_fruid, tvb, 0, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_15_fan_level, tvb, 1, 1, + v, "%s", val_to_str(v, fan_level_vals, "%d")); + if (tvb_length(tvb) > 2) { + proto_tree_add_item(tree, hf_ipmi_picmg_15_local_enable, tvb, 2, 1, TRUE); + } +} + +/* Get Fan Level + */ +static void +rq16(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_16_fruid, tvb, 0, 1, TRUE); +} + +static void +rs16(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 v; + + v = tvb_get_guint8(tvb, 0); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_16_override_level, tvb, 0, 1, + v, "%s", val_to_str(v, fan_level_vals, "%d")); + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_picmg_16_local_level, tvb, 1, 1, TRUE); + } + if (tvb_length(tvb) > 2) { + proto_tree_add_item(tree, hf_ipmi_picmg_16_local_enable, tvb, 2, 1, TRUE); + } +} + +/* Bused Resource Control + */ +static void +rq17(tvbuff_t *tvb, proto_tree *tree) +{ + static const value_string vals_17_cmd_fromshmm[] = { + { 0x00, "Query" }, + { 0x01, "Release" }, + { 0x02, "Force" }, + { 0x03, "Bus Free" }, + { 0, NULL } + }; + static const value_string vals_17_cmd_toshmm[] = { + { 0x00, "Request" }, + { 0x01, "Relinquish" }, + { 0x02, "Notify" }, + { 0, NULL } + }; + guint to_shmm = ipmi_current_hdr->trg_sa == 0x20; + guint cmd = tvb_get_guint8(tvb, 0); + + if (!tree) { + ipmi_setsaveddata(0, (to_shmm << 8) | cmd); + return; + } + + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_17_cmd, tvb, 0, 1, + cmd, "%s (0x%02x)", val_to_str(cmd, + to_shmm ? vals_17_cmd_toshmm : vals_17_cmd_fromshmm, + "Reserved"), cmd); + proto_tree_add_item(tree, hf_ipmi_picmg_17_resid, tvb, 1, 1, TRUE); +} + +static void +rs17(tvbuff_t *tvb, proto_tree *tree) +{ + /* Key is 3 bytes: direction, command, status */ + static const value_string response_vals[] = { + { 0x000000, "In Control" }, + { 0x000001, "No Control" }, + { 0x000100, "Ack" }, + { 0x000101, "Refused" }, + { 0x000102, "No Control" }, + { 0x000200, "Ack" }, + { 0x000201, "No Control" }, + { 0x000300, "Accept" }, + { 0x000301, "Not Needed" }, + { 0x010000, "Grant" }, + { 0x010001, "Busy" }, + { 0x010002, "Defer" }, + { 0x010003, "Deny" }, + { 0x010100, "Ack" }, + { 0x010101, "Error" }, + { 0x010200, "Ack" }, + { 0x010201, "Error" }, + { 0x010202, "Deny" }, + { 0, NULL } + }; + guint32 val; + guint8 status; + + if (!ipmi_getsaveddata(0, &val)) { + /* Without knowing the command, we cannot decipher the response */ + proto_tree_add_item(tree, hf_ipmi_picmg_17_status, tvb, 0, 1, TRUE); + return; + } + + status = tvb_get_guint8(tvb, 0); + val = (val << 8) | status; + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_17_status, tvb, 0, 1, + status, "%s (0x%02x)", val_to_str(val, response_vals, "Reserved"), status); +} + +/* Get IPMB Link Info + */ +static void +rq18(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_18_li_key_type, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_18_li_key, tvb, 1, 1, TRUE); +} + +static void +rs18(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_18_link_num, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_18_sensor_num, tvb, 1, 1, TRUE); +} + +/* Get Shelf Manager IPMB Address + */ +static void +rs1b(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1b_addr_active, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1b_addr_backup, tvb, 0, 1, TRUE); +} + +/* Set Fan Policy + */ +static void +rq1c(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_site_number, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_enable_state, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_policy_timeout, tvb, 2, 1, TRUE); + if (tvb_length(tvb) > 3) { + proto_tree_add_item(tree, hf_ipmi_picmg_1c_site_number, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1c_site_type, tvb, 4, 1, TRUE); + } +} + +/* Get Fan Policy + */ +static void +rq1d(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1d_fan_site_number, tvb, 0, 1, TRUE); + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_picmg_1d_site_number, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1d_site_type, tvb, 2, 1, TRUE); + } +} + +static void +rs1d(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1d_policy, tvb, 0, 1, TRUE); + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_picmg_1d_coverage, tvb, 1, 1, TRUE); + } +} + +/* FRU Control Capabilities + */ +static void +rq1e(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1e_fruid, tvb, 0, 1, TRUE); +} + +static void +rs1e(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_picmg_1e_cap_diagintr, + &hf_ipmi_picmg_1e_cap_graceful_reboot, &hf_ipmi_picmg_1e_cap_warm_reset, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "FRU Control Capabilities: ", "None", + ett_ipmi_picmg_1e_byte1, byte1, TRUE, 0); +} + +/* FRU Inventory Device Lock Control + */ +static void +rq1f(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1f_rq_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1f_rq_op, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_1f_rq_lockid, tvb, 2, 2, TRUE); +} + +static void +rs1f(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_1f_rs_lockid, tvb, 0, 2, TRUE); + ipmi_add_timestamp(tree, hf_ipmi_picmg_1f_rs_tstamp, tvb, 2); +} + +static const value_string cc1f[] = { + { 0x80, "Invalid FRU Information" }, + { 0x81, "Lock Failed" }, + { 0, NULL } +}; + +/* FRU Inventory Device Write + */ +static void +rq20(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_20_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_20_lockid, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_20_offset, tvb, 3, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_20_data, tvb, 5, tvb_length(tvb) - 5, TRUE); +} + +static void +rs20(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_20_count, tvb, 0, 1, TRUE); +} + +static const value_string cc20[] = { + { 0x80, "Invalid Lock ID" }, + { 0, NULL } +}; + +/* Get Shelf Manager IP Address + */ +static void +rq21(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_21_addr_num, tvb, 0, 1, TRUE); +} + +static void +rs21(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte9[] = { &hf_ipmi_picmg_21_is_shm, &hf_ipmi_picmg_21_addr_type, NULL }; + guint8 addrtype; + + ipmi_add_timestamp(tree, hf_ipmi_picmg_21_tstamp, tvb, 0); + proto_tree_add_item(tree, hf_ipmi_picmg_21_addr_count, tvb, 4, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_21_site_type, tvb, 5, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_21_site_num, tvb, 6, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_21_max_unavail, tvb, 7, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 8, 1, NULL, NULL, ett_ipmi_picmg_21_byte9, byte9, TRUE, 0); + + addrtype = tvb_get_guint8(tvb, 8) & 0x7f; + if (addrtype == 0x01) { + /* IP address and RMCP port are in network byte order! */ + proto_tree_add_item(tree, hf_ipmi_picmg_21_ipaddr, tvb, 9, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_picmg_21_rmcpport, tvb, 13, 2, FALSE); + }; +} + +/* Get Shelf Power Allocation + */ +static void +rq22(tvbuff_t *tvb, proto_tree *tree) +{ + if (!tree) { + ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0)); + return; + } + proto_tree_add_item(tree, hf_ipmi_picmg_22_feed_idx, tvb, 0, 1, TRUE); +} + +static void +rs22(tvbuff_t *tvb, proto_tree *tree) +{ + guint32 offs = 0; + guint16 v; + guint i, max; + + proto_tree_add_item(tree, hf_ipmi_picmg_22_update_cnt, tvb, 0, 2, TRUE); + + max = tvb_length(tvb) / 2 - 1; + if (!max) { + /* At least one shall be present */ + max = 1; + } + ipmi_getsaveddata(0, &offs); + for (i = 0; i < max; i++) { + v = tvb_get_letohs(tvb, 2 + 2 * i); + proto_tree_add_uint_format(tree, hf_ipmi_picmg_22_pwr_alloc, tvb, 2 + 2 * i, 2, + v, "Power Feed [%d] Allocation: %d Watts", offs + i, v); + } +} + +static void +add_component_bits(proto_tree *tree, tvbuff_t *tvb, guint offs, const char *desc) +{ + static const gint *compbits[] = { &hf_ipmi_picmg_XX_comp7, &hf_ipmi_picmg_XX_comp6, &hf_ipmi_picmg_XX_comp5, + &hf_ipmi_picmg_XX_comp4, &hf_ipmi_picmg_XX_comp3, &hf_ipmi_picmg_XX_comp2, &hf_ipmi_picmg_XX_comp1, &hf_ipmi_picmg_XX_comp0, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, offs, 1, desc, "None", + ett_ipmi_picmg_XX_compbits, compbits, TRUE, 0); +} + +/* Get Target Upgrade Capabilities + */ +static void +rs2e(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_picmg_2e_upgrade_undesirable, &hf_ipmi_picmg_2e_auto_rollback_override, + &hf_ipmi_picmg_2e_ipmc_degraded, &hf_ipmi_picmg_2e_deferred_activate, &hf_ipmi_picmg_2e_services_affected, + &hf_ipmi_picmg_2e_manual_rollback, &hf_ipmi_picmg_2e_auto_rollback, &hf_ipmi_picmg_2e_self_test, NULL }; + + proto_tree_add_item(tree, hf_ipmi_picmg_2e_version, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Capabilities: ", "None", + ett_ipmi_picmg_2e_byte2, byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_picmg_2e_upgrade_tout, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_2e_selftest_tout, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_2e_rollback_tout, tvb, 4, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_2e_inaccessibility_tout, tvb, 5, 1, TRUE); + add_component_bits(tree, tvb, 6, "Components present: "); +} + +static const value_string cc2e[] = { + { 0x81, "Firmware Upgrade is not supported over this interface" }, + { 0, NULL } +}; + +/* Get Component Properties + */ +static void +prop_00(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_picmg_prop00_cold_reset, &hf_ipmi_picmg_prop00_deferred_activation, + &hf_ipmi_picmg_prop00_comparison, &hf_ipmi_picmg_prop00_preparation, &hf_ipmi_picmg_prop00_rollback, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "General Component Properties: ", "None", + ett_ipmi_picmg_prop00_byte1, byte1, TRUE, 0); +} + +static void +parse_version(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_picmg_prop01_fw_major, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_picmg_prop01_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_picmg_prop01_fw_minor, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_prop01_fw_aux, tvb, 2, 4, TRUE); +} + +static void +prop_02(tvbuff_t *tvb, proto_tree *tree) +{ + guint len = tvb_length(tvb); + + if (len > 12) { + len = 12; + } + proto_tree_add_item(tree, hf_ipmi_picmg_prop02_desc, tvb, 0, len, TRUE); +} + +static const struct { + void (*intrp)(tvbuff_t *tvb, proto_tree *tree); + const char *name; +} compprops[] = { + { prop_00, "General Component Properties" }, + { parse_version, "Current Version" }, + { prop_02, "Description String" }, + { parse_version, "Rollback firmware version" }, + { parse_version, "Deferred upgrade firmware version" } +}; + +static void +rq2f(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 pno = tvb_get_guint8(tvb, 1); + const char *desc; + + if (!tree) { + ipmi_setsaveddata(0, pno); + return; + } + + if (pno < array_length(compprops)) { + desc = compprops[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_item(tree, hf_ipmi_picmg_2f_comp_id, tvb, 0, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_2f_comp_prop, tvb, 1, 1, pno, + "%s (0x%02x)", desc, pno); +} + +static void +rs2f(tvbuff_t *tvb, proto_tree *tree) +{ + guint32 pno; + const char *desc; + proto_item *ti; + + if (!ipmi_getsaveddata(0, &pno)) { + /* Can't parse further if property selector is not known */ + proto_tree_add_item(tree, hf_ipmi_picmg_2f_prop_data, tvb, 0, tvb_length(tvb), TRUE); + return; + } + + if (pno < array_length(compprops)) { + desc = compprops[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + ti = proto_tree_add_text(tree, tvb, 0, 0, "Property selector: %s (0x%02x)", desc, pno); + PROTO_ITEM_SET_GENERATED(ti); + if (pno < array_length(compprops)) { + compprops[pno].intrp(tvb, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_picmg_2f_prop_data, tvb, 0, tvb_length(tvb), TRUE); + } +} + +static const value_string cc2f[] = { + { 0x81, "Firmware Upgrade is not supported over this interface" }, + { 0x82, "Invalid Component ID" }, + { 0x83, "Invalid Component property selector" }, + { 0, NULL } +}; + +/* Abort Firmware Upgrade + */ +static const value_string cc30[] = { + { 0x80, "Firmware Upgrade cannot be aborted at this moment" }, + { 0x81, "Firmware Upgrade aborted, IPMC cannot resume normal operation" }, + { 0, NULL } +}; + +/* Initiate upgrade action + */ +static void +rq31(tvbuff_t *tvb, proto_tree *tree) +{ + add_component_bits(tree, tvb, 0, "Components: "); + proto_tree_add_item(tree, hf_ipmi_picmg_31_action, tvb, 1, 1, TRUE); +} + +static const value_string cc31[] = { + { 0x80, "Command in progress" }, + { 0x81, "Invalid component" }, + { 0, NULL } +}; + +/* Upload Firmware Block + */ +static void +rq32(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_32_block, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_32_data, tvb, 1, tvb_length(tvb) - 1, TRUE); +} + +static void +rs32(tvbuff_t *tvb, proto_tree *tree) +{ + if (tvb_length(tvb) > 0) { + proto_tree_add_item(tree, hf_ipmi_picmg_32_sec_offs, tvb, 0, 4, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_32_sec_len, tvb, 4, 4, TRUE); + } +} + +static const value_string cc32[] = { + { 0x80, "Command in progress" }, + { 0x81, "Invalid component" }, + { 0x82, "Internal checksum error detected in the received blocks" }, + { 0, NULL } +}; + +/* Finish Firmware Upgrade + */ +static void +rq33(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_picmg_33_comp_id, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_picmg_33_img_len, tvb, 1, 4, TRUE); +} + +static const value_string cc33[] = { + { 0x80, "Command in progress" }, + { 0x81, "Number of bytes received does not match size in the request" }, + { 0x82, "Internal checksum error detected in the received image" }, + { 0x83, "Uploaded firmware does not match current" }, + { 0, NULL } +}; + +/* Get Upgrade Status + */ +static void +rs34(tvbuff_t *tvb, proto_tree *tree) +{ + static const guint8 sig = 0; + static const gint *byte3[] = { &hf_ipmi_picmg_34_percentage, NULL }; + guint8 v; + ipmi_cmd_t *c; + + v = tvb_get_guint8(tvb, 0); + c = ipmi_getcmd(ipmi_getnetfn(IPMI_GROUP_REQ, &sig), v); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_34_cmd, tvb, 0, 1, v, + "%s (0x%02x)", c->desc, v); + v = tvb_get_guint8(tvb, 1); + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_34_ccode, tvb, 1, 1, v, + "%s (0x%02x)", ipmi_get_completion_code(v, c), v); + if (tvb_length(tvb) > 2) { + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, + ett_ipmi_picmg_34_byte3, byte3, TRUE, 0); + } +} + +static const value_string cc34[] = { + { 0x80, "Command in progress" }, + { 0, NULL } +}; + +/* Activate Firmware + */ +static void +rq35(tvbuff_t *tvb, proto_tree *tree) +{ + if (tvb_length(tvb) > 0) { + proto_tree_add_item(tree, hf_ipmi_picmg_35_rollback_override, tvb, 0, 1, TRUE); + } +} + +static const value_string cc35[] = { + { 0x80, "Command in progress" }, + { 0, NULL } +}; + +/* Query Self-test Results + */ +static void +rs36(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_picmg_36_fail_sel, &hf_ipmi_picmg_36_fail_sdr, + &hf_ipmi_picmg_36_fail_bmc_fru, &hf_ipmi_picmg_36_fail_ipmb_sig, &hf_ipmi_picmg_36_fail_sdr_empty, + &hf_ipmi_picmg_36_fail_iua, &hf_ipmi_picmg_36_fail_bb_fw, &hf_ipmi_picmg_36_fail_oper_fw, NULL }; + int res, fail; + + res = tvb_get_guint8(tvb, 0); + fail = tvb_get_guint8(tvb, 1); + + proto_tree_add_uint_format(tree, hf_ipmi_picmg_36_result, tvb, 0, 1, + res, "Self test result: %s (0x%02x)", + val_to_str(res, vals_36_result, "Device-specific internal failure"), + res); + + if (res == 0x55 || res == 0xff) { + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_36_fail, tvb, 1, 1, + fail, "0x%02x (must be 0x00)", + fail); + } else if (res == 0x57) { + proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_picmg_36_fail, ett_ipmi_picmg_36_byte2, byte2, TRUE); + } else if (res == 0x60) { + add_component_bits(tree, tvb, 1, "Failed components: "); + } else { + proto_tree_add_uint_format_value(tree, hf_ipmi_picmg_36_fail, tvb, 1, 1, + fail, "0x%02x (device-specific)", fail); + } +} + +static const value_string cc36[] = { + { 0x80, "Self-test in progress" }, + { 0x81, "Firmware upgrade not supported over this interface" }, + { 0, NULL } +}; + +/* Query Rollback Results + */ +static void +rs37(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_picmg_37_percent, NULL }; + const char *desc; + + switch (ipmi_current_hdr->ccode) { + case 0x00: desc = "Components completed rollback: "; break; + case 0x80: desc = "Components (should be None): "; break; + case 0x81: desc = "Components failed to rollback: "; break; + default: desc = "Components (ignored): "; break; + } + + add_component_bits(tree, tvb, 0, desc); + if (tvb_length(tvb) > 1) { + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_picmg_37_byte2, byte2, TRUE, 0); + } +} + +static const value_string cc37[] = { + { 0x80, "Rollback in progress" }, + { 0x81, "Rollback failure" }, + { 0x82, "Rollback overridden" }, + { 0x83, "Rollback denied for integrity reasons" }, + { 0, NULL } +}; + +/* Initiate Manual Rollback + */ +static const value_string cc38[] = { + { 0x80, "Rollback in progress" }, + { 0, NULL } +}; + +static ipmi_cmd_t cmd_picmg[] = { + /* AdvancedTCA Commands */ + { 0x00, NULL, rs00, NULL, NULL, "[ATCA] Get PICMG Properties", 0 }, + { 0x01, rq01, rs01, NULL, NULL, "[ATCA] Get Address Info", 0 }, + { 0x02, NULL, rs02, NULL, NULL, "[ATCA] Get Shelf Address Info", 0 }, + { 0x03, rq03, NULL, NULL, NULL, "[ATCA] Set Shelf Address Info", 0 }, + { 0x04, rq04, NULL, NULL, NULL, "[ATCA] FRU Control", 0 }, + { 0x05, rq05, rs05, NULL, NULL, "[ATCA] Get FRU LED Properties", 0 }, + { 0x06, rq06, rs06, NULL, NULL, "[ATCA] Get LED Color Capabilities", 0 }, + { 0x07, rq07, NULL, NULL, NULL, "[ATCA] Set FRU LED State", 0 }, + { 0x08, rq08, rs08, NULL, NULL, "[ATCA] Get FRU LED State", 0 }, + { 0x09, rq09, NULL, NULL, NULL, "[ATCA] Set IPMB State", 0 }, + { 0x0a, rq0a, NULL, NULL, NULL, "[ATCA] Set FRU Activation Policy", 0 }, + { 0x0b, rq0b, rs0b, NULL, NULL, "[ATCA] Get FRU Activation Policy", 0 }, + { 0x0c, rq0c, NULL, NULL, NULL, "[ATCA] Set FRU Activation", 0 }, + { 0x0d, rq0d, rs0d, NULL, NULL, "[ATCA] Get Device Locator Record ID", 0 }, + { 0x0e, rq0e, NULL, NULL, NULL, "[ATCA] Set Port State", 0 }, + { 0x0f, rq0f, rs0f, NULL, NULL, "[ATCA] Get Port State", 0 }, + { 0x10, rq10, rs10, NULL, NULL, "[ATCA] Compute Power Properties", 0 }, + { 0x11, rq11, NULL, NULL, NULL, "[ATCA] Set Power Level", 0 }, + { 0x12, rq12, rs12, NULL, NULL, "[ATCA] Get Power Level", 0 }, + { 0x13, rq13, NULL, NULL, NULL, "[ATCA] Renegotiate Power", 0 }, + { 0x14, rq14, rs14, NULL, NULL, "[ATCA] Get Fan Speed Properties", 0 }, + { 0x15, rq15, NULL, NULL, NULL, "[ATCA] Set Fan Level", 0 }, + { 0x16, rq16, rs16, NULL, NULL, "[ATCA] Get Fan Level", 0 }, + { 0x17, rq17, rs17, NULL, NULL, "[ATCA] Bused Resource Control", CMD_CALLRQ }, + { 0x18, rq18, rs18, NULL, NULL, "[ATCA] Get IPMB Link Info", 0 }, + { 0x19, IPMI_TBD, NULL, NULL, "[AMC.0] Set AMC Port State", 0 }, + { 0x1a, IPMI_TBD, NULL, NULL, "[AMC.0] Get AMC Port State", 0 }, + { 0x1b, NULL, rs1b, NULL, NULL, "[ATCA] Get Shelf Manager IPMB Address", 0 }, + { 0x1c, rq1c, NULL, NULL, NULL, "[ATCA] Set Fan Policy", 0 }, + { 0x1d, rq1d, rs1d, NULL, NULL, "[ATCA] Get Fan Policy", 0 }, + { 0x1e, rq1e, rs1e, NULL, NULL, "[ATCA] FRU Control Capabilities", 0 }, + { 0x1f, rq1f, rs1f, cc1f, NULL, "[ATCA] FRU Inventory Device Lock Control", 0 }, + { 0x20, rq20, rs20, cc20, NULL, "[ATCA] FRU Inventory Device Write", 0 }, + { 0x21, rq21, rs21, NULL, NULL, "[ATCA] Get Shelf Manager IP Addresses", 0 }, + { 0x22, rq22, rs22, NULL, NULL, "[ATCA] Get Shelf Power Allocation", CMD_CALLRQ }, + { 0x23, IPMI_TBD, NULL, NULL, "[uTCA] Get Location Information", 0 }, + { 0x24, IPMI_TBD, NULL, NULL, "[uTCA] Power Channel Control", 0 }, + { 0x25, IPMI_TBD, NULL, NULL, "[uTCA] Get Power Channel Status", 0 }, + { 0x26, IPMI_TBD, NULL, NULL, "[uTCA] PM Reset", 0 }, + { 0x27, IPMI_TBD, NULL, NULL, "[uTCA] Get PM Status", 0 }, + { 0x28, IPMI_TBD, NULL, NULL, "[uTCA] PM Heartbeat", 0 }, + { 0x29, IPMI_TBD, NULL, NULL, "[uTCA] Get Telco Alarm Capability", 0 }, + { 0x2a, IPMI_TBD, NULL, NULL, "[uTCA] Set Telco Alarm State", 0 }, + { 0x2b, IPMI_TBD, NULL, NULL, "[uTCA] Get Telco Alarm State", 0 }, + { 0x2c, IPMI_TBD, NULL, NULL, "[AMC.0] Set Clock State", 0 }, + { 0x2d, IPMI_TBD, NULL, NULL, "[AMC.0] Get Clock State", 0 }, + { 0x2e, NULL, rs2e, cc2e, NULL, "[HPM.1] Get Target Upgrade Capabilities", 0 }, + { 0x2f, rq2f, rs2f, cc2f, NULL, "[HPM.1] Get Component Properties", CMD_CALLRQ }, + { 0x30, NULL, NULL, cc30, NULL, "[HPM.1] Abort Firmware Upgrade", 0 }, + { 0x31, rq31, NULL, cc31, NULL, "[HPM.1] Initiate Upgrade Action", 0 }, + { 0x32, rq32, rs32, cc32, NULL, "[HPM.1] Upload Firmware Block", 0 }, + { 0x33, rq33, NULL, cc33, NULL, "[HPM.1] Finish Firmware Upload", 0 }, + { 0x34, NULL, rs34, cc34, NULL, "[HPM.1] Get Upgrade Status", 0 }, + { 0x35, rq35, NULL, cc35, NULL, "[HPM.1] Activate Firmware", 0 }, + { 0x36, NULL, rs36, cc36, NULL, "[HPM.1] Query Self-test Results", 0 }, + { 0x37, NULL, rs37, cc37, NULL, "[HPM.1] Query Rollback Status", 0 }, + { 0x38, NULL, NULL, cc38, NULL, "[HPM.1] Initiate Manual Rollback", 0 }, +}; + +void +ipmi_register_picmg(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_picmg_led_function, + { "LED Function", + "ipmi.led.function", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_led_on_duration, + { "On-duration", + "ipmi.led.on_duration", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_led_color, + { "Color", + "ipmi.led.color", FT_UINT8, BASE_HEX, led_color_vals, 0x0f, "", HFILL }}, + + { &hf_ipmi_picmg_linkinfo_grpid, + { "Grouping ID", + "ipmi.linkinfo.grpid", FT_UINT32, BASE_DEC, NULL, 0xff000000, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_type_ext, + { "Type extension", + "ipmi.linkinfo.type_ext", FT_UINT32, BASE_HEX, NULL, 0x00f00000, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_type, + { "Type", + "ipmi.linkinfo.type", FT_UINT32, BASE_HEX, linkinfo_type_vals, 0x000ff000, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_ports, + { "Ports", + "ipmi.linkinfo.ports", FT_UINT32, BASE_HEX, linkinfo_ports_vals, 0x00000f00, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_iface, + { "Interface", + "ipmi.linkinfo.iface", FT_UINT32, BASE_HEX, linkinfo_iface_vals, 0x000000c0, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_chan, + { "Channel", + "ipmi.linkinfo.chan", FT_UINT32, BASE_DEC, NULL, 0x0000003f, "", HFILL }}, + { &hf_ipmi_picmg_linkinfo_state, + { "State", + "ipmi.picmg0e.state", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_00_version, + { "PICMG Extension Version", + "ipmi.picmg00.version", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + { &hf_ipmi_picmg_00_max_fruid, + { "Max FRU Device ID", + "ipmi.picmg00.max_fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_00_ipmc_fruid, + { "FRU Device ID for IPMC", + "ipmi.picmg00.ipmc_fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_01_rq_fruid, + { "FRU ID", + "ipmi.picmg01.rq_fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rq_addr_key_type, + { "Address Key Type", + "ipmi.picmg01.rq_addr_key_type", FT_UINT8, BASE_HEX, addr_key_type_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rq_addr_key, + { "Address Key", + "ipmi.picmg01.rq_addr_key", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rq_site_type, + { "Site Type", + "ipmi.picmg01.rq_site_type", FT_UINT8, BASE_HEX, site_type_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_hwaddr, + { "Hardware Address", + "ipmi.picmg01.rs_hwaddr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_ipmbaddr, + { "IPMB-0 Address", + "ipmi.picmg01.rs_ipmbaddr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_rsrv, + { "Reserved (shall be 0xFF)", + "ipmi.picmg01.rs_rsrv", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_fruid, + { "FRU ID", + "ipmi.picmg01.rs_fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_site_num, + { "Site Number", + "ipmi.picmg01.rs_site_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_01_rs_site_type, + { "Site Type", + "ipmi.picmg01.rs_site_type", FT_UINT8, BASE_HEX, site_type_vals, 0, "", HFILL }}, + + { &hf_ipmi_picmg_04_fruid, + { "FRU ID", + "ipmi.picmg04.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_04_cmd, + { "Command", + "ipmi.picmg04.cmd", FT_UINT8, BASE_HEX, vals_04_cmd, 0, "", HFILL }}, + + { &hf_ipmi_picmg_05_fruid, + { "FRU ID", + "ipmi.picmg05.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_05_led3, + { "LED 3", + "ipmi.picmg05.led3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_05_led2, + { "LED 2", + "ipmi.picmg05.led2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_05_led1, + { "LED 1", + "ipmi.picmg05.led1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_05_blue_led, + { "BLUE LED", + "ipmi.picmg05.blue_led", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_picmg_05_app_leds, + { "Application-specific LED Count", + "ipmi.picmg05.app_leds", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_06_fruid, + { "FRU ID", + "ipmi.picmg06.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_06_ledid, + { "LED ID", + "ipmi.picmg06.ledid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_white, + { "White", + "ipmi.picmg06.cap_white", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_orange, + { "Orange", + "ipmi.picmg06.cap_orange", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_amber, + { "Amber", + "ipmi.picmg06.cap_amber", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_green, + { "Green", + "ipmi.picmg06.cap_green", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_red, + { "Red", + "ipmi.picmg06.cap_red", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_06_cap_blue, + { "Blue", + "ipmi.picmg06.cap_blue", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_06_default_local_color, + { "Default LED Color in Local Control state", + "ipmi.picmg06.def_local", FT_UINT8, BASE_HEX, led_color_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_picmg_06_default_override_color, + { "Default LED Color in Override state", + "ipmi.picmg06.def_override", FT_UINT8, BASE_HEX, led_color_vals, 0x0f, "", HFILL }}, + + { &hf_ipmi_picmg_07_fruid, + { "FRU ID", + "ipmi.picmg07.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_07_ledid, + { "LED ID", + "ipmi.picmg07.ledid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_08_fruid, + { "FRU ID", + "ipmi.picmg08.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_08_ledid, + { "LED ID", + "ipmi.picmg08.ledid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_08_state_lamptest, + { "Lamp Test", + "ipmi.picmg08.state_lamptest", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_08_state_override, + { "Override", + "ipmi.picmg08.state_override", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_08_state_local, + { "Local Control", + "ipmi.picmg08.state_local", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_picmg_08_lamptest_duration, + { "Lamp test duration", + "ipmi.picmg08.lamptest_duration", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_09_ipmba, + { "IPMB-A State", + "ipmi.picmg09.ipmba", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_09_ipmbb, + { "IPMB-B State", + "ipmi.picmg09.ipmbb", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_0a_fruid, + { "FRU ID", + "ipmi.picmg0a.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_0a_msk_d_locked, + { "Deactivation-Locked bit", + "ipmi.picmg0a.msk_deactivation", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_0a_msk_locked, + { "Locked bit", + "ipmi.picmg0a.msk_locked", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_picmg_0a_d_locked, + { "Deactivation-Locked bit", + "ipmi.picmg0a.deactivation", FT_BOOLEAN, 8, TFS(&set_clear_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_picmg_0a_locked, + { "Locked bit", + "ipmi.picmg0a.locked", FT_BOOLEAN, 8, TFS(&set_clear_tfs), 0x01, "", HFILL }}, + + { &hf_ipmi_picmg_0b_fruid, + { "FRU ID", + "ipmi.picmg0b.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_0b_d_locked, + { "Deactivation-Locked bit", + "ipmi.picmg0b.deactivation", FT_BOOLEAN, 8, TFS(&set_clear_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_picmg_0b_locked, + { "Locked bit", + "ipmi.picmg0b.locked", FT_BOOLEAN, 8, TFS(&set_clear_tfs), 0x01, "", HFILL }}, + + { &hf_ipmi_picmg_0c_fruid, + { "FRU ID", + "ipmi.picmg0c.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_0c_cmd, + { "Command", + "ipmi.picmg0c.cmd", FT_UINT8, BASE_HEX, vals_0c_cmd, 0, "", HFILL }}, + + { &hf_ipmi_picmg_0d_fruid, + { "FRU ID", + "ipmi.picmg0d.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_0d_start, + { "Search after record ID", + "ipmi.picmg0d.start", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_0d_recordid, + { "Record ID", + "ipmi.picmg0d.recordid", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_0f_iface, + { "Interface", + "ipmi.linkinfo.iface", FT_UINT8, BASE_HEX, linkinfo_iface_vals, 0x000000c0, "", HFILL }}, + { &hf_ipmi_picmg_0f_chan, + { "Channel", + "ipmi.linkinfo.chan", FT_UINT8, BASE_DEC, NULL, 0x0000003f, "", HFILL }}, + + { &hf_ipmi_picmg_10_fruid, + { "FRU ID", + "ipmi.picmg10.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_10_nslots, + { "Number of spanned slots", + "ipmi.picmg10.nslots", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_10_ipmc_loc, + { "IPMC Location", + "ipmi.picmg10.ipmc_loc", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_11_fruid, + { "FRU ID", + "ipmi.picmg11.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_11_power_level, + { "Power Level", + "ipmi.picmg11.power_level", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_11_set_to_desired, + { "Set Present Levels to Desired", + "ipmi.picmg11.set_to_desired", FT_UINT8, BASE_HEX, vals_11_set, 0, "", HFILL }}, + + { &hf_ipmi_picmg_12_fruid, + { "FRU ID", + "ipmi.picmg12.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_12_pwr_type, + { "Power Type", + "ipmi.picmg12.pwr_type", FT_UINT8, BASE_HEX, vals_12_pwr_type, 0, "", HFILL }}, + { &hf_ipmi_picmg_12_dynamic, + { "Dynamic Power Configuration", + "ipmi.picmg12.dynamic", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_picmg_12_pwr_lvl, + { "Power Level", + "ipmi.picmg12.pwd_lvl", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_picmg_12_delay, + { "Delay to stable power", + "ipmi.picmg12.delay", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_12_pwr_mult, + { "Power multiplier", + "ipmi.picmg12.pwr_mult", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_12_pwr_draw, + { "Power draw", + "ipmi.picmg12.pwr_draw", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_13_fruid, + { "FRU ID", + "ipmi.picmg13.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_14_fruid, + { "FRU ID", + "ipmi.picmg14.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_14_speed_min, + { "Minimum Speed Level", + "ipmi.picmg14.speed_min", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_14_speed_max, + { "Maximum Speed Level", + "ipmi.picmg14.speed_max", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_14_speed_norm, + { "Normal Operating Level", + "ipmi.picmg14.speed_norm", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_14_local_control, + { "Local Control Mode Supported", + "ipmi.picmg14.local_control", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + + { &hf_ipmi_picmg_15_fruid, + { "FRU ID", + "ipmi.picmg15.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_15_fan_level, + { "Fan Level", + "ipmi.picmg15.fan_level", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_15_local_enable, + { "Local Control Enable State", + "ipmi.picmg15.local_enable", FT_UINT8, BASE_HEX, enable_vals, 0, "", HFILL }}, + + { &hf_ipmi_picmg_16_fruid, + { "FRU ID", + "ipmi.picmg16.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_16_override_level, + { "Override Fan Level", + "ipmi.picmg16.override_level", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_16_local_level, + { "Local Control Fan Level", + "ipmi.picmg16.local_level", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_16_local_enable, + { "Local Control Enable State", + "ipmi.picmg16.local_enable", FT_UINT8, BASE_HEX, enabled_vals, 0, "", HFILL }}, + + { &hf_ipmi_picmg_17_cmd, + { "Command", + "ipmi.picmg17.cmd", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_17_resid, + { "Bused Resource ID", + "ipmi.picmg17.resid", FT_UINT8, BASE_HEX, busresid_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_17_status, + { "Status", + "ipmi.picmg17.status", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_18_li_key_type, + { "Link Info Key Type", + "ipmi.picmg18.li_key_type", FT_UINT8, BASE_HEX, vals_18_keytype, 0, "", HFILL }}, + { &hf_ipmi_picmg_18_li_key, + { "Link Info Key", + "ipmi.picmg18.li_key", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_18_link_num, + { "Link Number", + "ipmi.picmg18.link_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_18_sensor_num, + { "Sensor Number", + "ipmi.picmg18.sensor_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_1b_addr_active, + { "Active Shelf Manager IPMB Address", + "ipmi.picmg1b.addr_active", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1b_addr_backup, + { "Backup Shelf Manager IPMB Address", + "ipmi.picmg1b.addr_backup", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_1c_fan_site_number, + { "Fan Tray Site Number", + "ipmi.picmg1c.fan_site_number", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1c_fan_enable_state, + { "Fan Enable state", + "ipmi.picmg1c.fan_enable_state", FT_UINT8, BASE_HEX, enable_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_1c_fan_policy_timeout, + { "Fan Policy Timeout", + "ipmi.picmg1c.fan_policy_timeout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_5s_1based, 0, "", HFILL }}, + { &hf_ipmi_picmg_1c_site_number, + { "Site Number", + "ipmi.picmg1c.site_number", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1c_site_type, + { "Site Type", + "ipmi.picmg1c.site_type", FT_UINT8, BASE_HEX, site_type_vals, 0, "", HFILL }}, + + { &hf_ipmi_picmg_1d_fan_site_number, + { "Fan Tray Site Number", + "ipmi.picmg1d.fan_site_number", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1d_site_number, + { "Site Number", + "ipmi.picmg1d.site_number", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1d_site_type, + { "Site Type", + "ipmi.picmg1d.site_type", FT_UINT8, BASE_HEX, site_type_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_1d_policy, + { "Policy", + "ipmi.picmg1d.fan_enable_state", FT_UINT8, BASE_HEX, vals_1d_policy, 0, "", HFILL }}, + { &hf_ipmi_picmg_1d_coverage, + { "Coverage", + "ipmi.picmg1d.coverage", FT_UINT8, BASE_HEX, vals_1d_coverage, 0, "", HFILL }}, + + { &hf_ipmi_picmg_1e_fruid, + { "FRU ID", + "ipmi.picmg1e.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1e_cap_diagintr, + { "Diagnostic interrupt", + "ipmi.picmg1e.cap_diagintr", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_1e_cap_graceful_reboot, + { "Graceful reboot", + "ipmi.picmg1e.cap_reboot", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_1e_cap_warm_reset, + { "Warm Reset", + "ipmi.picmg1e.cap_warmreset", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + + { &hf_ipmi_picmg_1f_rq_fruid, + { "FRU ID", + "ipmi.picmg1f.rq_fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1f_rq_op, + { "Operation", + "ipmi.picmg1f.rq_op", FT_UINT8, BASE_HEX, vals_1f_op, 0, "", HFILL }}, + { &hf_ipmi_picmg_1f_rq_lockid, + { "Lock ID", + "ipmi.picmg1f.rq_lockid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1f_rs_lockid, + { "Lock ID", + "ipmi.picmg1f.rs_lockid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_1f_rs_tstamp, + { "Last Commit Timestamp", + "ipmi.picmg1f.rs_tstamp", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_20_fruid, + { "FRU ID", + "ipmi.picmg20.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_20_lockid, + { "Lock ID", + "ipmi.picmg20.lockid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_20_offset, + { "Offset to write", + "ipmi.picmg20.offset", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_20_data, + { "Data to write", + "ipmi.picmg20.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_20_count, + { "Count written", + "ipmi.picmg20.count", FT_BYTES, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_21_addr_num, + { "Address Number", + "ipmi.picmg21.addr_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_tstamp, + { "Shelf IP Address Last Change Timestamp", + "ipmi.picmg21.tstamp", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_addr_count, + { "Address Count", + "ipmi.picmg21.addr_count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_site_type, + { "Site Type", + "ipmi.picmg21.site_type", FT_UINT8, BASE_HEX, site_type_vals, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_site_num, + { "Site Number", + "ipmi.picmg21.site_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_max_unavail, + { "Maximum Unavailable Time", + "ipmi.picmg21.max_unavail", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_is_shm, + { "Shelf Manager IP Address", + "ipmi.picmg21.is_shm", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_picmg_21_addr_type, + { "Address Type", + "ipmi.picmg21.addr_type", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_picmg_21_ipaddr, + { "IP Address", + "ipmi.picmg21.ip_addr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_21_rmcpport, + { "RMCP Port", + "ipmi.picmg21.rmcp_port", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_22_feed_idx, + { "Power Feed Index", + "ipmi.picmg22.feed_idx", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_22_update_cnt, + { "Update Counter", + "ipmi.picmg22.update_cnt", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_22_pwr_alloc, + { "Power Feed Allocation", + "ipmi.picmg22.pwr_alloc", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_XX_comp7, + { "Component 7", + "ipmi.hpm1.comp7", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp6, + { "Component 6", + "ipmi.hpm1.comp6", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp5, + { "Component 5", + "ipmi.hpm1.comp5", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp4, + { "Component 4", + "ipmi.hpm1.comp4", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp3, + { "Component 3", + "ipmi.hpm1.comp3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp2, + { "Component 2", + "ipmi.hpm1.comp2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp1, + { "Component 1", + "ipmi.hpm1.comp1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_XX_comp0, + { "Component 0", + "ipmi.hpm1.comp0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_picmg_2e_version, + { "HPM.1 version", + "ipmi.picmg2e.hpm1_version", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_2e_upgrade_undesirable, + { "Firmware Upgrade Undesirable", + "ipmi.picmg2e.upgrade_undesirable", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_picmg_2e_auto_rollback_override, + { "Automatic Rollback Overridden", + "ipmi.picmg2e.auto_rollback_override", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_picmg_2e_ipmc_degraded, + { "IPMC degraded during upgrade", + "ipmi.picmg2e.ipmc_degraded", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_picmg_2e_deferred_activate, + { "Deferred Activation supported", + "ipmi.picmg2e.deferred_activate", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_picmg_2e_services_affected, + { "Services affected by upgrade", + "ipmi.picmg2e.services_affected", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_2e_manual_rollback, + { "Manual Rollback supported", + "ipmi.picmg2e.manual_rollback", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_2e_auto_rollback, + { "Automatic Rollback supported", + "ipmi.picmg2e.auto_rollback", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_picmg_2e_self_test, + { "Self-Test supported", + "ipmi.picmg2e.self_test", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_picmg_2e_upgrade_tout, + { "Upgrade timeout", + "ipmi.picmg2e.upgrade_tout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_5s_1based, 0, "", HFILL }}, + { &hf_ipmi_picmg_2e_selftest_tout, + { "Self-test timeout", + "ipmi.picmg2e.selftest_tout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_5s_1based, 0, "", HFILL }}, + { &hf_ipmi_picmg_2e_rollback_tout, + { "Rollback timeout", + "ipmi.picmg2e.rollback_tout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_5s_1based, 0, "", HFILL }}, + { &hf_ipmi_picmg_2e_inaccessibility_tout, + { "Inaccessibility timeout", + "ipmi.picmg2e.inaccessibility_tout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_5s_1based, 0, "", HFILL }}, + + { &hf_ipmi_picmg_prop00_cold_reset, + { "Payload cold reset required", + "ipmi.prop00.cold_reset", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_picmg_prop00_deferred_activation, + { "Deferred firmware activation supported", + "ipmi.prop00.deferred_activation", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_picmg_prop00_comparison, + { "Firmware comparison supported", + "ipmi.prop00.firmware_comparison", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_picmg_prop00_preparation, + { "Prepare Components action required", + "ipmi.prop00.preparation", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_picmg_prop00_rollback, + { "Rollback/Backup support", + "ipmi.prop00.rollback", FT_UINT8, BASE_HEX, vals_prop00_rollback, 0x03, "", HFILL }}, + { &hf_ipmi_picmg_prop01_fw_major, + { "Major Firmware Revision (binary encoded)", + "ipmi.prop01.fw_major", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_picmg_prop01_fw_minor, + { "Minor Firmware Revision (BCD encoded)", + "ipmi.prop01.fw_minor", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_prop01_fw_aux, + { "Auxillary Firmware Revision Information", + "ipmi.prop01.fw_aux", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_prop02_desc, + { "Description string", + "ipmi.prop02.desc", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_2f_comp_id, + { "Component ID", + "ipmi.picmg2f.comp_id", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_2f_comp_prop, + { "Component property selector", + "ipmi.picmg2f.comp_prop", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_2f_prop_data, + { "Unknown property data", + "ipmi.picmg2f.prop_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_31_action, + { "Upgrade action", + "ipmi.picmg31.action", FT_UINT8, BASE_HEX, vals_31_action, 0, "", HFILL }}, + + { &hf_ipmi_picmg_32_block, + { "Block Number", + "ipmi.picmg32.block", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_32_data, + { "Data", + "ipmi.picmg32.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_32_sec_offs, + { "Section Offset", + "ipmi.picmg32.sec_offs", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_32_sec_len, + { "Section Length", + "ipmi.picmg32.sec_len", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_33_comp_id, + { "Component ID", + "ipmi.picmg33.comp_id", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_33_img_len, + { "Image Length", + "ipmi.picmg33.img_len", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_picmg_34_cmd, + { "Command in progress", + "ipmi.picmg34.cmd", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_34_ccode, + { "Last command completion code", + "ipmi.picmg34.ccode", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_34_percentage, + { "Completion estimate", + "ipmi.picmg34.percent", FT_UINT8, BASE_CUSTOM, ipmi_fmt_percent, 0x7f, "", HFILL }}, + + { &hf_ipmi_picmg_35_rollback_override, + { "Rollback Override Policy", + "ipmi.picmg35.rollback_override", FT_UINT8, BASE_HEX, vals_35_override, 0, "", HFILL }}, + + { &hf_ipmi_picmg_36_result, + { "Self test result", + "ipmi.picmg36.self_test_result", FT_UINT8, BASE_HEX, vals_36_result, 0, "", HFILL }}, + { &hf_ipmi_picmg_36_fail, + { "Self-test error bitfield", + "ipmi.picmg36.fail", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_sel, + { "Cannot access SEL device", + "ipmi.picmg36.fail.sel", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x80, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_sdr, + { "Cannot access SDR Repository", + "ipmi.picmg36.fail.sdr", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x40, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_bmc_fru, + { "Cannot access BMC FRU device", + "ipmi.picmg36.fail.bmc_fru", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x20, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_ipmb_sig, + { "IPMB signal lines do not respond", + "ipmi.picmg36.fail.ipmb_sig", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x10, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_sdr_empty, + { "SDR Repository is empty", + "ipmi.picmg36.fail.sdr_empty", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x08, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_iua, + { "Internal Use Area of BMC FRU corrupted", + "ipmi.picmg36.fail.iua", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x04, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_bb_fw, + { "Controller update boot block firmware corrupted", + "ipmi.picmg36.fail.bb_fw", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x02, "", HFILL }}, + { &hf_ipmi_picmg_36_fail_oper_fw, + { "Controller operational firmware corrupted", + "ipmi.picmg36.fail.oper_fw", FT_BOOLEAN, 8, TFS(&tfs_36_fail_unknown), 0x01, "", HFILL }}, + + { &hf_ipmi_picmg_37_percent, + { "Estimated percentage complete", + "ipmi.picmg37.percent", FT_UINT8, BASE_CUSTOM, ipmi_fmt_percent, 0x7f, "", HFILL }}, + + }; + static gint *ett[] = { + &ett_ipmi_picmg_led_color, + &ett_ipmi_picmg_link_info, + &ett_ipmi_picmg_05_byte1, + &ett_ipmi_picmg_06_byte1, + &ett_ipmi_picmg_06_byte2, + &ett_ipmi_picmg_06_byte3, + &ett_ipmi_picmg_08_byte1, + &ett_ipmi_picmg_09_ipmba, + &ett_ipmi_picmg_09_ipmbb, + &ett_ipmi_picmg_0a_byte2, + &ett_ipmi_picmg_0a_byte3, + &ett_ipmi_picmg_0b_byte1, + &ett_ipmi_picmg_0f_chan, + &ett_ipmi_picmg_12_byte1, + &ett_ipmi_picmg_14_prop, + &ett_ipmi_picmg_1e_byte1, + &ett_ipmi_picmg_21_byte9, + &ett_ipmi_picmg_XX_compbits, + &ett_ipmi_picmg_2e_byte2, + &ett_ipmi_picmg_prop00_byte1, + &ett_ipmi_picmg_prop01_byte1, + &ett_ipmi_picmg_34_byte3, + &ett_ipmi_picmg_36_byte2, + &ett_ipmi_picmg_37_byte2, + }; + static guint8 sig_picmg[1] = { 0 }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_GROUP_REQ, IPMI_OEM_NONE, sig_picmg, 1, + "PICMG", cmd_picmg, array_length(cmd_picmg)); +} diff --git a/epan/dissectors/packet-ipmi-pps.c b/epan/dissectors/packet-ipmi-pps.c new file mode 100644 index 0000000000..a02b3d8f7b --- /dev/null +++ b/epan/dissectors/packet-ipmi-pps.c @@ -0,0 +1,104 @@ +/* packet-ipmi-pps.c + * Sub-dissectors for IPMI messages (netFn=OEM/Group, defining body = PPS) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static ipmi_cmd_t cmd_pps[] = { + { 0x00, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Status", 0 }, + { 0x01, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Serial Interface Properties", 0 }, + { 0x02, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Serial Interface Properties", 0 }, + { 0x03, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Debug Level", 0 }, + { 0x04, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Debug Level", 0 }, + { 0x05, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Hardware Address", 0 }, + { 0x06, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Hardware Address", 0 }, + { 0x07, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Handle Switch", 0 }, + { 0x08, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Handle Switch", 0 }, + { 0x09, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Payload Communication Timeout", 0 }, + { 0x0a, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Payload Communication Timeout", 0 }, + { 0x0b, IPMI_TBD, NULL, NULL, "[PPS OEM] Enable Payload Control", 0 }, + { 0x0c, IPMI_TBD, NULL, NULL, "[PPS OEM] Disable Payload Control", 0 }, + { 0x0d, IPMI_TBD, NULL, NULL, "[PPS OEM] Reset IPMC", 0 }, + { 0x0e, IPMI_TBD, NULL, NULL, "[PPS OEM] Hang IPMC", 0 }, + { 0x0f, IPMI_TBD, NULL, NULL, "[PPS OEM] Bused Resource Control", 0 }, + { 0x10, IPMI_TBD, NULL, NULL, "[PPS OEM] Bused Resource Status", 0 }, + { 0x11, IPMI_TBD, NULL, NULL, "[PPS OEM] Graceful Reset", 0 }, + { 0x12, IPMI_TBD, NULL, NULL, "[PPS OEM] Diagnostic Interrupt Results", 0 }, + { 0x13, IPMI_TBD, NULL, NULL, "[PPS OEM] Set/Clear Telco Alarm", 0 }, + { 0x14, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Telco Alarm Sensor Number", 0 }, + { 0x15, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Payload Shutdown Timeout", 0 }, + { 0x16, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Payload Shutdown Timeout", 0 }, + { 0x17, IPMI_TBD, NULL, NULL, "[PPS OEM] Switch over Serial Debug", 0 }, + { 0x18, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Local FRU LED State", 0 }, + { 0x19, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Local FRU LED State", 0 }, + { 0x1a, IPMI_TBD, NULL, NULL, "[PPS OEM] Update Discrete Sensor", 0 }, + { 0x1b, IPMI_TBD, NULL, NULL, "[PPS OEM] Update Threshold Sensor", 0 }, + { 0x1c, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Prepare", 0 }, + { 0x1d, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Write", 0 }, + { 0x1e, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Complete", 0 }, + { 0x1f, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Start", 0 }, + { 0x20, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Stop", 0 }, + { 0x21, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Resume", 0 }, + { 0x22, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Cease", 0 }, + { 0x23, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Sensor Set", 0 }, + { 0x24, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Notify", 0 }, + { 0x25, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Get FRU State", 0 }, + { 0x26, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Invalidate Hardware Address", 0 }, + { 0x27, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Module Status", 0 }, + { 0x28, IPMI_TBD, NULL, NULL, "[PPS OEM] Enable AMC Site", 0 }, + { 0x29, IPMI_TBD, NULL, NULL, "[PPS OEM] Disable AMC Site", 0 }, + { 0x2a, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Wait for Payload Notify", 0 }, + { 0x2b, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Test Flags", 0 }, + { 0x2c, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Geographic Address", 0 }, + { 0x2d, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Geographic Address", 0 }, + { 0x30, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Data", 0 }, + { 0x31, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Hysteresis", 0 }, + { 0x32, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Threshold", 0 }, + { 0x33, IPMI_TBD, NULL, NULL, "[PPS OEM] Reset EEPROM SDR Repository", 0 }, + { 0x34, IPMI_TBD, NULL, NULL, "[PPS OEM] Backend Power Control", 0 }, + { 0x35, IPMI_TBD, NULL, NULL, "[PPS OEM] Read CPLD Register", 0 }, + { 0x36, IPMI_TBD, NULL, NULL, "[PPS OEM] Write CPLD Register", 0 } +}; + +void +ipmi_register_pps(gint proto_ipmi _U_) +{ + static guint8 sig_pps[3] = { 0x0a, 0x40, 0x00 }; + static guint8 sig_pps_rev[3] = { 0x00, 0x40, 0x0a }; + + ipmi_register_netfn_cmdtab(IPMI_OEM_REQ, IPMI_OEM_NONE, sig_pps, 3, + "Pigeon Point Systems", cmd_pps, array_length(cmd_pps)); + ipmi_register_netfn_cmdtab(IPMI_OEM_REQ, IPMI_OEM_NONE, sig_pps_rev, 3, + "Pigeon Point Systems (reversed)", cmd_pps, array_length(cmd_pps)); +} diff --git a/epan/dissectors/packet-ipmi-se.c b/epan/dissectors/packet-ipmi-se.c new file mode 100644 index 0000000000..1e030c9349 --- /dev/null +++ b/epan/dissectors/packet-ipmi-se.c @@ -0,0 +1,3665 @@ +/* packet-ipmi-se.c + * Sub-dissectors for IPMI messages (netFn=Sensor/Event) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +/* Data types for sensor-specific info */ +struct sensor_info; +typedef gboolean (*intrp_t)(proto_tree *, tvbuff_t *, const struct sensor_info *, + guint32, guint32, guint32); + +struct sensor_info { + const value_string *offsets; + intrp_t intrp2; + intrp_t intrp3; + const char *desc; +}; + +struct evtype_info { + const value_string *byte2; + const value_string *byte3; + const value_string *offsets; + intrp_t intrp2; + intrp_t intrp3; + const char *desc; +}; + +static gint ett_ipmi_se_evt_byte3 = -1; +static gint ett_ipmi_se_evt_evd_byte1 = -1; +static gint ett_ipmi_se_evt_evd_byte2 = -1; +static gint ett_ipmi_se_evt_evd_byte3 = -1; + +static gint ett_ipmi_se_cp06_byte1 = -1; +static gint ett_ipmi_se_cp07_byte1 = -1; +static gint ett_ipmi_se_cp09_byte1 = -1; +static gint ett_ipmi_se_cp10_byte1 = -1; +static gint ett_ipmi_se_cp12_byte1 = -1; +static gint ett_ipmi_se_cp12_byte2 = -1; +static gint ett_ipmi_se_cp12_byte3 = -1; +static gint ett_ipmi_se_cp13_byte1 = -1; +static gint ett_ipmi_se_cp15_byte1 = -1; +static gint ett_ipmi_se_cp15_byte2 = -1; +static gint ett_ipmi_se_cp15_member = -1; +static gint ett_ipmi_se_cp15_byte11 = -1; + +static gint ett_ipmi_se_00_byte2 = -1; +static gint ett_ipmi_se_01_byte2 = -1; +static gint ett_ipmi_se_10_action = -1; +static gint ett_ipmi_se_12_byte1 = -1; +static gint ett_ipmi_se_13_byte1 = -1; +static gint ett_ipmi_se_13_rev = -1; +static gint ett_ipmi_se_14_byte1 = -1; +static gint ett_ipmi_se_16_byte1 = -1; +static gint ett_ipmi_se_16_byte2 = -1; +static gint ett_ipmi_se_16_byte3 = -1; +static gint ett_ipmi_se_20_rq_byte1 = -1; +static gint ett_ipmi_se_20_rs_byte2 = -1; +static gint ett_ipmi_se_23_readingfactors = -1; +static gint ett_ipmi_se_23_byte1 = -1; +static gint ett_ipmi_se_23_byte2 = -1; +static gint ett_ipmi_se_23_byte3 = -1; +static gint ett_ipmi_se_23_byte4 = -1; +static gint ett_ipmi_se_23_byte5 = -1; +static gint ett_ipmi_se_23_byte6 = -1; +static gint ett_ipmi_se_XX_mask = -1; +static gint ett_ipmi_se_XX_b1 = -1; +static gint ett_ipmi_se_XX_b2 = -1; +static gint ett_ipmi_se_XX_b3 = -1; +static gint ett_ipmi_se_XX_b4 = -1; +static gint ett_ipmi_se_28_byte2 = -1; +static gint ett_ipmi_se_29_byte1 = -1; +static gint ett_ipmi_se_2a_byte2 = -1; +static gint ett_ipmi_se_2b_byte1 = -1; +static gint ett_ipmi_se_2d_byte2 = -1; +static gint ett_ipmi_se_2d_b1 = -1; +static gint ett_ipmi_se_2d_b2 = -1; +static gint ett_ipmi_se_2e_evtype = -1; +static gint ett_ipmi_se_2f_evtype = -1; + +static gint hf_ipmi_se_evt_rev = -1; +static gint hf_ipmi_se_evt_sensor_type = -1; +static gint hf_ipmi_se_evt_sensor_num = -1; +static gint hf_ipmi_se_evt_byte3 = -1; +static gint hf_ipmi_se_evt_dir = -1; +static gint hf_ipmi_se_evt_type = -1; +static gint hf_ipmi_se_evt_data1 = -1; +static gint hf_ipmi_se_evt_data1_b2 = -1; +static gint hf_ipmi_se_evt_data1_b3 = -1; +static gint hf_ipmi_se_evt_data1_offs = -1; +static gint hf_ipmi_se_evt_data2 = -1; +static gint hf_ipmi_se_evt_data3 = -1; + +static gint hf_ipmi_se_cp00_sip = -1; +static gint hf_ipmi_se_cp01_alert_startup = -1; +static gint hf_ipmi_se_cp01_startup = -1; +static gint hf_ipmi_se_cp01_event_msg = -1; +static gint hf_ipmi_se_cp01_pef = -1; +static gint hf_ipmi_se_cp02_diag_intr = -1; +static gint hf_ipmi_se_cp02_oem_action = -1; +static gint hf_ipmi_se_cp02_pwr_cycle = -1; +static gint hf_ipmi_se_cp02_reset = -1; +static gint hf_ipmi_se_cp02_pwr_down = -1; +static gint hf_ipmi_se_cp02_alert = -1; +static gint hf_ipmi_se_cp03_startup = -1; +static gint hf_ipmi_se_cp04_alert_startup = -1; +static gint hf_ipmi_se_cp05_num_evfilters = -1; +static gint hf_ipmi_se_cp06_filter = -1; +static gint hf_ipmi_se_cp06_data = -1; +static gint hf_ipmi_se_cp07_filter = -1; +static gint hf_ipmi_se_cp07_data = -1; +static gint hf_ipmi_se_cp08_policies = -1; +static gint hf_ipmi_se_cp09_entry = -1; +static gint hf_ipmi_se_cp09_data = -1; +static gint hf_ipmi_se_cp10_useval = -1; +static gint hf_ipmi_se_cp10_guid = -1; +static gint hf_ipmi_se_cp11_num_alertstr = -1; +static gint hf_ipmi_se_cp12_byte1 = -1; +static gint hf_ipmi_se_cp12_alert_stringsel = -1; +static gint hf_ipmi_se_cp12_evfilter = -1; +static gint hf_ipmi_se_cp12_alert_stringset = -1; +static gint hf_ipmi_se_cp13_stringsel = -1; +static gint hf_ipmi_se_cp13_blocksel = -1; +static gint hf_ipmi_se_cp13_string = -1; +static gint hf_ipmi_se_cp14_num_gct = -1; +static gint hf_ipmi_se_cp15_gctsel = -1; +static gint hf_ipmi_se_cp15_force = -1; +static gint hf_ipmi_se_cp15_delayed = -1; +static gint hf_ipmi_se_cp15_channel = -1; +static gint hf_ipmi_se_cp15_group = -1; +static gint hf_ipmi_se_cp15_member_check = -1; +static gint hf_ipmi_se_cp15_member_id = -1; +static gint hf_ipmi_se_cp15_retries = -1; +static gint hf_ipmi_se_cp15_operation = -1; + +static gint hf_ipmi_se_00_addr = -1; +static gint hf_ipmi_se_00_lun = -1; + +static gint hf_ipmi_se_01_addr = -1; +static gint hf_ipmi_se_01_lun = -1; + +static gint hf_ipmi_se_10_pef_version = -1; +static gint hf_ipmi_se_10_action_oem_filter = -1; +static gint hf_ipmi_se_10_action_diag_intr = -1; +static gint hf_ipmi_se_10_action_oem_action = -1; +static gint hf_ipmi_se_10_action_pwr_cycle = -1; +static gint hf_ipmi_se_10_action_reset = -1; +static gint hf_ipmi_se_10_action_pwr_down = -1; +static gint hf_ipmi_se_10_action_alert = -1; +static gint hf_ipmi_se_10_entries = -1; + +static gint hf_ipmi_se_11_rq_timeout = -1; +static gint hf_ipmi_se_11_rs_timeout = -1; + +static gint hf_ipmi_se_12_byte1 = -1; +static gint hf_ipmi_se_12_param = -1; +static gint hf_ipmi_se_12_data = -1; + +static gint hf_ipmi_se_13_byte1 = -1; +static gint hf_ipmi_se_13_getrev = -1; +static gint hf_ipmi_se_13_param = -1; +static gint hf_ipmi_se_13_set = -1; +static gint hf_ipmi_se_13_block = -1; +static gint hf_ipmi_se_13_rev_present = -1; +static gint hf_ipmi_se_13_rev_compat = -1; +static gint hf_ipmi_se_13_data = -1; + +static gint hf_ipmi_se_14_processed_by = -1; +static gint hf_ipmi_se_14_rid = -1; + +static gint hf_ipmi_se_15_tstamp = -1; +static gint hf_ipmi_se_15_lastrec = -1; +static gint hf_ipmi_se_15_proc_sw = -1; +static gint hf_ipmi_se_15_proc_bmc = -1; + +static gint hf_ipmi_se_16_chan = -1; +static gint hf_ipmi_se_16_op = -1; +static gint hf_ipmi_se_16_dst = -1; +static gint hf_ipmi_se_16_send_string = -1; +static gint hf_ipmi_se_16_string_sel = -1; +static gint hf_ipmi_se_16_gen = -1; +static gint hf_ipmi_se_16_status = -1; + +static gint hf_ipmi_se_17_seq = -1; +static gint hf_ipmi_se_17_tstamp = -1; +static gint hf_ipmi_se_17_evsrc = -1; +static gint hf_ipmi_se_17_sensor_dev = -1; +static gint hf_ipmi_se_17_sensor_num = -1; +static gint hf_ipmi_se_17_evdata1 = -1; +static gint hf_ipmi_se_17_evdata2 = -1; +static gint hf_ipmi_se_17_evdata3 = -1; + +static gint hf_ipmi_se_20_rq_op = -1; +static gint hf_ipmi_se_20_rs_num = -1; +static gint hf_ipmi_se_20_rs_sdr = -1; +static gint hf_ipmi_se_20_rs_population = -1; +static gint hf_ipmi_se_20_rs_lun3 = -1; +static gint hf_ipmi_se_20_rs_lun2 = -1; +static gint hf_ipmi_se_20_rs_lun1 = -1; +static gint hf_ipmi_se_20_rs_lun0 = -1; +static gint hf_ipmi_se_20_rs_change = -1; + +static gint hf_ipmi_se_21_rid = -1; +static gint hf_ipmi_se_21_record = -1; +static gint hf_ipmi_se_21_offset = -1; +static gint hf_ipmi_se_21_len = -1; +static gint hf_ipmi_se_21_next = -1; +static gint hf_ipmi_se_21_recdata = -1; + +static gint hf_ipmi_se_22_resid = -1; + +static gint hf_ipmi_se_23_rq_sensor = -1; +static gint hf_ipmi_se_23_rq_reading = -1; +static gint hf_ipmi_se_23_rs_next_reading = -1; + +static gint hf_ipmi_se_24_sensor = -1; +static gint hf_ipmi_se_24_mask = -1; +static gint hf_ipmi_se_24_hyst_pos = -1; +static gint hf_ipmi_se_24_hyst_neg = -1; + +static gint hf_ipmi_se_25_sensor = -1; +static gint hf_ipmi_se_25_mask = -1; +static gint hf_ipmi_se_25_hyst_pos = -1; +static gint hf_ipmi_se_25_hyst_neg = -1; + +static gint hf_ipmi_se_26_sensor = -1; +static gint hf_ipmi_se_XX_m_unr = -1; +static gint hf_ipmi_se_XX_m_uc = -1; +static gint hf_ipmi_se_XX_m_unc = -1; +static gint hf_ipmi_se_XX_m_lnr = -1; +static gint hf_ipmi_se_XX_m_lc = -1; +static gint hf_ipmi_se_XX_m_lnc = -1; +static gint hf_ipmi_se_XX_thr_lnc = -1; +static gint hf_ipmi_se_XX_thr_lc = -1; +static gint hf_ipmi_se_XX_thr_lnr = -1; +static gint hf_ipmi_se_XX_thr_unc = -1; +static gint hf_ipmi_se_XX_thr_uc = -1; +static gint hf_ipmi_se_XX_thr_unr = -1; + +static gint hf_ipmi_se_27_sensor = -1; + +static gint hf_ipmi_se_XX_b1_7 = -1; +static gint hf_ipmi_se_XX_b1_6 = -1; +static gint hf_ipmi_se_XX_b1_5 = -1; +static gint hf_ipmi_se_XX_b1_4 = -1; +static gint hf_ipmi_se_XX_b1_3 = -1; +static gint hf_ipmi_se_XX_b1_2 = -1; +static gint hf_ipmi_se_XX_b1_1 = -1; +static gint hf_ipmi_se_XX_b1_0 = -1; +static gint hf_ipmi_se_XX_b2_6 = -1; +static gint hf_ipmi_se_XX_b2_5 = -1; +static gint hf_ipmi_se_XX_b2_4 = -1; +static gint hf_ipmi_se_XX_b2_3 = -1; +static gint hf_ipmi_se_XX_b2_2 = -1; +static gint hf_ipmi_se_XX_b2_1 = -1; +static gint hf_ipmi_se_XX_b2_0 = -1; +static gint hf_ipmi_se_XX_b3_7 = -1; +static gint hf_ipmi_se_XX_b3_6 = -1; +static gint hf_ipmi_se_XX_b3_5 = -1; +static gint hf_ipmi_se_XX_b3_4 = -1; +static gint hf_ipmi_se_XX_b3_3 = -1; +static gint hf_ipmi_se_XX_b3_2 = -1; +static gint hf_ipmi_se_XX_b3_1 = -1; +static gint hf_ipmi_se_XX_b3_0 = -1; +static gint hf_ipmi_se_XX_b4_6 = -1; +static gint hf_ipmi_se_XX_b4_5 = -1; +static gint hf_ipmi_se_XX_b4_4 = -1; +static gint hf_ipmi_se_XX_b4_3 = -1; +static gint hf_ipmi_se_XX_b4_2 = -1; +static gint hf_ipmi_se_XX_b4_1 = -1; +static gint hf_ipmi_se_XX_b4_0 = -1; + +static gint hf_ipmi_se_28_sensor = -1; +static gint hf_ipmi_se_28_fl_evm = -1; +static gint hf_ipmi_se_28_fl_scan = -1; +static gint hf_ipmi_se_28_fl_action = -1; + +static gint hf_ipmi_se_29_sensor = -1; +static gint hf_ipmi_se_29_fl_evm = -1; +static gint hf_ipmi_se_29_fl_scan = -1; + +static gint hf_ipmi_se_2a_sensor = -1; +static gint hf_ipmi_se_2a_fl_sel = -1; + +static gint hf_ipmi_se_2b_sensor = -1; +static gint hf_ipmi_se_2b_fl_evm = -1; +static gint hf_ipmi_se_2b_fl_scan = -1; +static gint hf_ipmi_se_2b_fl_unavail = -1; + +static gint hf_ipmi_se_2d_sensor = -1; +static gint hf_ipmi_se_2d_reading = -1; +static gint hf_ipmi_se_2d_b1_7 = -1; +static gint hf_ipmi_se_2d_b1_6 = -1; +static gint hf_ipmi_se_2d_b1_5 = -1; +static gint hf_ipmi_se_2d_b1_4 = -1; +static gint hf_ipmi_se_2d_b1_3 = -1; +static gint hf_ipmi_se_2d_b1_2 = -1; +static gint hf_ipmi_se_2d_b1_1 = -1; +static gint hf_ipmi_se_2d_b1_0 = -1; +static gint hf_ipmi_se_2d_b2_6 = -1; +static gint hf_ipmi_se_2d_b2_5 = -1; +static gint hf_ipmi_se_2d_b2_4 = -1; +static gint hf_ipmi_se_2d_b2_3 = -1; +static gint hf_ipmi_se_2d_b2_2 = -1; +static gint hf_ipmi_se_2d_b2_1 = -1; +static gint hf_ipmi_se_2d_b2_0 = -1; + +static gint hf_ipmi_se_2e_sensor = -1; +static gint hf_ipmi_se_2e_stype = -1; +static gint hf_ipmi_se_2e_evtype = -1; + +static gint hf_ipmi_se_2f_sensor = -1; +static gint hf_ipmi_se_2f_stype = -1; +static gint hf_ipmi_se_2f_evtype = -1; + +/* Platform Event parsing. Common for Platform Event and Alert Immediate. + */ +static const value_string evt_evm_rev_vals[] = { + { 0x03, "IPMI 1.0" }, + { 0x04, "IPMI 1.5+" }, + { 0, NULL }, +}; + +static const struct true_false_string evt_evdir_tfs = { + "Deassertion event", + "Assertion event" +}; + +static const value_string et_empty[] = { + { 0, NULL } +}; + +static const value_string etb2_thr[] = { + { 0x00, "Unspecified" }, + { 0x01, "Trigger reading" }, + { 0x02, "OEM code" }, + { 0x03, "Sensor-specific" }, + { 0, NULL } +}; + +static const value_string etb3_thr[] = { + { 0x00, "Unspecified" }, + { 0x01, "Trigger threshold" }, + { 0x02, "OEM code" }, + { 0x03, "Sensor-specific" }, + { 0, NULL } +}; + +static const value_string etb2_dscr[] = { + { 0x00, "Unspecified" }, + { 0x01, "Previous state and/or severity" }, + { 0x02, "OEM code" }, + { 0x03, "Sensor-specific" }, + { 0, NULL } +}; + +static const value_string etb3_dscr[] = { + { 0x00, "Unspecified" }, + { 0x02, "OEM code" }, + { 0x03, "Sensor-specific" }, + { 0, NULL } +}; + +static const value_string etb2_oem[] = { + { 0x00, "Unspecified" }, + { 0x01, "Previous state and/or severity" }, + { 0x02, "OEM code" }, + { 0, NULL } +}; + +static const value_string etb3_oem[] = { + { 0x00, "Unspecified" }, + { 0x02, "OEM code" }, + { 0, NULL } +}; + +static const value_string etoff_01[] = { + { 0x00, "Lower Non-Critical: going low" }, + { 0x01, "Lower Non-Critical: going high" }, + { 0x02, "Lower Critical: going low" }, + { 0x03, "Lower Critical: going high" }, + { 0x04, "Lower Non-Recoverable: going low" }, + { 0x05, "Lower Non-Recoverable: going high" }, + { 0x06, "Upper Non-Critical: going low" }, + { 0x07, "Upper Non-Critical: going high" }, + { 0x08, "Upper Critical: going low" }, + { 0x09, "Upper Critical: going high" }, + { 0x0a, "Upper Non-Recoverable: going low" }, + { 0x0b, "Upper Non-Recoverable: going high" }, + { 0, NULL } +}; + +static const value_string etoff_02[] = { + { 0x00, "Transition to Idle" }, + { 0x01, "Transition to Active" }, + { 0x02, "Transition to Busy" }, + { 0, NULL } +}; + +static const value_string etoff_03[] = { + { 0x00, "State Deasserted" }, + { 0x01, "State Asserted" }, + { 0, NULL } +}; + +static const value_string etoff_04[] = { + { 0x00, "Predictive Failure Deasserted" }, + { 0x01, "Predictive Failure Asserted" }, + { 0, NULL } +}; + +static const value_string etoff_05[] = { + { 0x00, "Limit Not Exceeded" }, + { 0x01, "Limit Exceeded" }, + { 0, NULL } +}; + +static const value_string etoff_06[] = { + { 0x00, "Performance Met" }, + { 0x01, "Performance Lags" }, + { 0, NULL } +}; + +static const value_string etoff_07[] = { + { 0x00, "Transition to OK" }, + { 0x01, "Transition to Non-Critical from OK" }, + { 0x02, "Transition to Critical from less severe" }, + { 0x03, "Transition to Non-Recoverable from less severe" }, + { 0x04, "Transition to Non-Critical from more severe" }, + { 0x05, "Transition to Critical from Non-Recoverable" }, + { 0x06, "Transition to Non-Recoverable" }, + { 0x07, "Monitor" }, + { 0x08, "Informational" }, + { 0, NULL } +}; + +static const value_string etoff_08[] = { + { 0x00, "Device Removed/Absent" }, + { 0x01, "Device Inserted/Present" }, + { 0, NULL } +}; + +static const value_string etoff_09[] = { + { 0x00, "Device Disabled" }, + { 0x01, "Device Enabled" }, + { 0, NULL } +}; + +static const value_string etoff_0a[] = { + { 0x00, "Transition to Running" }, + { 0x01, "Transition to In Test" }, + { 0x02, "Transition to Power Off" }, + { 0x03, "Transition to On Line" }, + { 0x04, "Transition to Off Line" }, + { 0x05, "Transition to Off Duty" }, + { 0x06, "Transition to Degraded" }, + { 0x07, "Transition to Power Save" }, + { 0x08, "Install Error" }, + { 0, NULL } +}; + +static const value_string etoff_0b[] = { + { 0x00, "Fully Redundant" }, + { 0x01, "Redundancy Lost" }, + { 0x02, "Redundancy Degraded" }, + { 0x03, "Non-Redundant: Sufficient Resources from Redundant" }, + { 0x04, "Non-Redundant: Sufficient Resources from Insufficient Resources" }, + { 0x05, "Non-Redundant: Insufficient Resources" }, + { 0x06, "Redundancy Degraded from Fully Redundant" }, + { 0x07, "Redundancy Degraded from Non-Redundant" }, + { 0, NULL } +}; + +static const value_string etoff_0c[] = { + { 0x00, "D0 Power State" }, + { 0x01, "D1 Power State" }, + { 0x02, "D2 Power State" }, + { 0x03, "D3 Power State" }, + { 0, NULL } +}; + +static gboolean +eti_thr_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x1) { + proto_tree_add_text(tree, tvb, 0, 1, "Trigger reading: %d%s", + d, d == 0xff ? " (unspecified)" : ""); + return TRUE; + } + return FALSE; +} + +static gboolean +eti_thr_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x1) { + proto_tree_add_text(tree, tvb, 0, 1, "Trigger threshold: %d%s", + d, d == 0xff ? " (unspecified)" : ""); + return TRUE; + } + return FALSE; +} + +static gboolean +eti_2_pst_sev(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si, + guint32 b, guint32 offs _U_, guint32 d) +{ + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + const char *desc; + + if (b == 0x1) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/severity"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d >> 4; + desc = (tmp == 0x0f) ? "Unspecified" : val_to_str(tmp, etoff_07, "Unknown"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sSeverity: %s (0x%02x)", + ipmi_dcd8(d, 0xf0), desc, tmp); + tmp = d & 0xf; + desc = (tmp == 0x0f) ? "Unspecified" : val_to_str(tmp, si->offsets, "Unknown"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), desc, tmp); + return TRUE; + } + return FALSE; +} + +static const struct evtype_info * +get_evtype_info(unsigned int evtype) +{ + static const struct { + unsigned int id; + struct evtype_info eti; + } eti_tab[] = { + { 0x01, { etb2_thr, etb3_thr, etoff_01, eti_thr_2, eti_thr_3, "Threshold" }}, + { 0x02, { etb2_dscr, etb3_dscr, etoff_02, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x03, { etb2_dscr, etb3_dscr, etoff_03, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x04, { etb2_dscr, etb3_dscr, etoff_04, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x05, { etb2_dscr, etb3_dscr, etoff_05, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x06, { etb2_dscr, etb3_dscr, etoff_06, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x07, { etb2_dscr, etb3_dscr, etoff_07, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x08, { etb2_dscr, etb3_dscr, etoff_08, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x09, { etb2_dscr, etb3_dscr, etoff_09, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x0a, { etb2_dscr, etb3_dscr, etoff_0a, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x0b, { etb2_dscr, etb3_dscr, etoff_0b, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x0c, { etb2_dscr, etb3_dscr, etoff_0c, eti_2_pst_sev, NULL, "Discreet" }}, + { 0x6f, { etb2_dscr, etb3_dscr, NULL, eti_2_pst_sev, NULL, "Sensor-specific" }} + }; + static const struct evtype_info eti_oem = { + etb2_oem, etb3_oem, et_empty, eti_2_pst_sev, NULL, "OEM-specific" + }; + static const struct evtype_info eti_rsrv = { + et_empty, et_empty, et_empty, NULL, NULL, "Reserved" + }; + unsigned int i; + + /* Look for explicitly specified event/reading type */ + for (i = 0; i < array_length(eti_tab); i++) { + if (eti_tab[i].id == evtype) { + return &eti_tab[i].eti; + } + } + + /* Falls in OEM range? */ + if (evtype >= 0x70 && evtype <= 0x7f) { + return &eti_oem; + } + + return &eti_rsrv; +} + +static const value_string ssoff_05[] = { + { 0x00, "General Chassis Intrusion" }, + { 0x01, "Drive Bay Intrusion" }, + { 0x02, "I/O Card Area Intrusion" }, + { 0x03, "Processor Area Intrusion" }, + { 0x04, "LAN Leash Lost" }, + { 0x05, "Unauthorized dock" }, + { 0x06, "FAN Area Intrusion" }, + { 0, NULL } +}; + +static const value_string ssoff_06[] = { + { 0x00, "Secure Mode (Front Panel Lockout) Violation Attempt" }, + { 0x01, "Pre-boot Password Violation: user password" }, + { 0x02, "Pre-boot Password Violation: setup password" }, + { 0x03, "Pre-boot Password Violation: network boot password" }, + { 0x04, "Other pre-boot password violation" }, + { 0x05, "Out-of-band password violation" }, + { 0, NULL } +}; + +static const value_string ssoff_07[] = { + { 0x00, "IERR" }, + { 0x01, "Thermal Trip" }, + { 0x02, "FRB1/BIST Failure" }, + { 0x03, "FRB2/Hang in POST Failure" }, + { 0x04, "FRB3/Processor Startup/Initialization Failure" }, + { 0x05, "Configuration Error" }, + { 0x06, "SM BIOS Uncorrectable CPU-complex error" }, + { 0x07, "Processor Presence Detected" }, + { 0x08, "Processor Disabled" }, + { 0x09, "Terminator Presence Detected" }, + { 0x0a, "Processor Automatically Throttled" }, + { 0, NULL } +}; + +static const value_string ssoff_08[] = { + { 0x00, "Presence Detected" }, + { 0x01, "Power Supply Failure Detected" }, + { 0x02, "Predictive Failure" }, + { 0x03, "Power Supply input lost (AC/DC)" }, + { 0x04, "Power Supply input lost or out-of-range" }, + { 0x05, "Power Supply out-of-range, but present" }, + { 0x06, "Configuration error" }, + { 0, NULL } +}; + +static const value_string ssoff_09[] = { + { 0x00, "Power Off / Power Down" }, + { 0x01, "Power Cycle" }, + { 0x02, "240VA Power Down" }, + { 0x03, "Interlock Power Down" }, + { 0x04, "AC Lost" }, + { 0x05, "Soft Power Control Failure" }, + { 0x06, "Power Unit Failure Detected" }, + { 0x07, "Predictive Failure" }, + { 0, NULL } +}; + +static const value_string ssoff_0c[] = { + { 0x00, "Correctable ECC/other correctable memory error" }, + { 0x01, "Uncorrectable ECC/other uncorrectable memory error" }, + { 0x02, "Parity" }, + { 0x03, "Memory Scrub Failed" }, + { 0x04, "Memory Device Disabled" }, + { 0x05, "Correctable ECC/other correctable memory error: logging limit reached" }, + { 0x06, "Presence Detected" }, + { 0x07, "Configuration Error" }, + { 0x08, "Spare" }, + { 0x09, "Memory Automatically Throttled" }, + { 0x0a, "Critical Overtemperature" }, + { 0, NULL } +}; + +static const value_string ssoff_0d[] = { + { 0x00, "Drive Presence" }, + { 0x01, "Drive Fault" }, + { 0x02, "Predictive Failure" }, + { 0x03, "Hot Spare" }, + { 0x04, "Consistency Check / Parity Check in progress" }, + { 0x05, "In Critical Array" }, + { 0x06, "In Failed Array" }, + { 0x07, "Rebuild/Remap in progress" }, + { 0x08, "Rebuild/Remap aborted" }, + { 0, NULL } +}; + +static const value_string ssoff_0f[] = { + { 0x00, "System Firmware Error (POST Error)" }, + { 0x01, "System Firmware Hang" }, + { 0x02, "System Firmware Progress" }, + { 0, NULL } +}; + +static const value_string ssoff_10[] = { + { 0x00, "Correctable Memory Error Logging Disabled" }, + { 0x01, "Event type Logging Disabled" }, + { 0x02, "Log Area Reset/Cleared" }, + { 0x03, "All Event Logging Disabled" }, + { 0x04, "SEL Full" }, + { 0x05, "SEL Almost Full" }, + { 0, NULL } +}; + +static const value_string ssoff_11[] = { + { 0x00, "BIOS Watchdog Reset" }, + { 0x01, "OS Watchdog Reset" }, + { 0x02, "OS Watchdog Shutdown" }, + { 0x03, "OS Watchdog Power Down" }, + { 0x04, "OS Watchdog Power Cycle" }, + { 0x05, "OS Watchdog NMI/Diagnostic Interrupt" }, + { 0x06, "OS Watchdog Expired, status only" }, + { 0x07, "OS Watchdog pre-timeout interrupt, non-NMI" }, + { 0, NULL } +}; + +static const value_string ssoff_12[] = { + { 0x00, "System Reconfigured" }, + { 0x01, "OEM System Boot Event" }, + { 0x02, "Undetermined system hardware failure" }, + { 0x03, "Entry added to Auxillary Log" }, + { 0x04, "PEF Action" }, + { 0x05, "Timestamp Clock Synch" }, + { 0, NULL } +}; + +static const value_string ssoff_13[] = { + { 0x00, "Front Panel NMI/Diagnostic Interrupt" }, + { 0x01, "Bus Timeout" }, + { 0x02, "I/O Channel Check NMI" }, + { 0x03, "Software NMI" }, + { 0x04, "PCI PERR" }, + { 0x05, "PCI SERR" }, + { 0x06, "EISA Fail Safe Timeout" }, + { 0x07, "Bus Correctable Error" }, + { 0x08, "Bus Uncorrectable Error" }, + { 0x09, "Fatal NMI" }, + { 0x0a, "Bus Fatal Error" }, + { 0x0b, "Bus Degraded" }, + { 0, NULL } +}; + +static const value_string ssoff_14[] = { + { 0x00, "Power Button Pressed" }, + { 0x01, "Sleep Button Pressed" }, + { 0x02, "Reset Button Pressed" }, + { 0x03, "FRU Latch open" }, + { 0x04, "FRU Service Request Button Pressed" }, + { 0, NULL } +}; + +static const value_string ssoff_19[] = { + { 0x00, "Soft Power Control Failure" }, + { 0, NULL } +}; + +static const value_string ssoff_1b[] = { + { 0x00, "Cable/Interconnect is connected" }, + { 0x01, "Configuration error - Incorrect cable connected / Incorrect interconnection" }, + { 0, NULL } +}; + +static const value_string ssoff_1d[] = { + { 0x00, "Initiated by Power Up" }, + { 0x01, "Initiated by hard reset" }, + { 0x02, "Initiated by warm reset" }, + { 0x03, "User requested PXE boot" }, + { 0x04, "Automatic boot to diagnostic" }, + { 0x05, "OS / run-time software initiated hard reset" }, + { 0x06, "OS / run-time software initiated warm reset" }, + { 0x07, "System Restart" }, + { 0, NULL } +}; + +static const value_string ssoff_1e[] = { + { 0x00, "No bootable media" }, + { 0x01, "No bootable diskette left in drive" }, + { 0x02, "PXE Server not found" }, + { 0x03, "Invalid boot sector" }, + { 0x04, "Timeout waiting for user selection of boot source" }, + { 0, NULL } +}; + +static const value_string ssoff_1f[] = { + { 0x00, "A: boot completed" }, + { 0x01, "C: boot completed" }, + { 0x02, "PXE boot completed" }, + { 0x03, "Diagnostic boot completed" }, + { 0x04, "CD-ROM boot completed" }, + { 0x05, "ROM boot completed" }, + { 0x06, "Boot completed - boot device not specified" }, + { 0, NULL } +}; + +static const value_string ssoff_20[] = { + { 0x00, "Critical stop during OS load/initialization" }, + { 0x01, "Run-time critical stop" }, + { 0x02, "OS Graceful Stop" }, + { 0x03, "OS Graceful Shutdown" }, + { 0x04, "Soft Shutdown initiated by PEF" }, + { 0x05, "Agent Not Responding" }, + { 0, NULL } +}; + +static const value_string ssoff_21[] = { + { 0x00, "Fault Status asserted" }, + { 0x01, "Identify Status asserted" }, + { 0x02, "Slot/Connector Device installed/attached" }, + { 0x03, "Slot/Connector Ready for Device Installation" }, + { 0x04, "Slot/Connector Ready for Device Removal" }, + { 0x05, "Slot Power is Off" }, + { 0x06, "Slot/Connector Device Removal Request" }, + { 0x07, "Interlock Asserted" }, + { 0x08, "Slot is Disabled" }, + { 0x09, "Slot holds spare device" }, + { 0, NULL } +}; + +static const value_string ssoff_22[] = { + { 0x00, "S0/G0 'working'" }, + { 0x01, "S1 'sleeping with system h/w & processor context maintained'" }, + { 0x02, "S2 'sleeping, processor context lost'" }, + { 0x03, "S3 'sleeping, processor & h/w, memory retained'" }, + { 0x04, "S4 'non-volatile sleep / suspend-to-disk'" }, + { 0x05, "S5/G2 'soft-off'" }, + { 0x06, "S4/S5 'soft-off', particular S4/S5 state cannot be determined" }, + { 0x07, "G3 / Mechanical Off" }, + { 0x08, "Sleeping in S1, S2 or S3 states" }, + { 0x09, "G1 sleeping" }, + { 0x0a, "S5 entered by override" }, + { 0x0b, "Legacy ON state" }, + { 0x0c, "Legacy OFF state" }, + { 0x0e, "Unknown" }, + { 0, NULL } +}; + +static const value_string ssoff_23[] = { + { 0x00, "Timer expired, status only" }, + { 0x01, "Hard Reset" }, + { 0x02, "Power Down" }, + { 0x03, "Power Cycle" }, + { 0x08, "Timer Interrupt" }, + { 0, NULL } +}; + +static const value_string ssoff_24[] = { + { 0x00, "Platform Generated Page" }, + { 0x01, "Platform Generated LAN Event" }, + { 0x02, "Platform Event Trap generated" }, + { 0x03, "Platform generated SNMP trap" }, + { 0, NULL } +}; + +static const value_string ssoff_25[] = { + { 0x00, "Entity Present" }, + { 0x01, "Entity Absent" }, + { 0x02, "Entity Disabled" }, + { 0, NULL } +}; + +static const value_string ssoff_27[] = { + { 0x00, "LAN Heartbeat Lost" }, + { 0x01, "LAN Heartbeat" }, + { 0, NULL } +}; + +static const value_string ssoff_28[] = { + { 0x00, "Sensor access degraded or unavailable" }, + { 0x01, "Controller access degraded or unavailable" }, + { 0x02, "Management controller off-line" }, + { 0x03, "Management controller unavailable" }, + { 0x04, "Sensor failure" }, + { 0x05, "FRU failure" }, + { 0, NULL } +}; + +static const value_string ssoff_29[] = { + { 0x00, "Battery low" }, + { 0x01, "Battery failed" }, + { 0x02, "Battery presence detected" }, + { 0, NULL } +}; + +static const value_string ssoff_2a[] = { + { 0x00, "Session Activated" }, + { 0x01, "Session Deactivated" }, + { 0, NULL } +}; + +static const value_string ssoff_2b[] = { + { 0x00, "Hardware change detected with associated Entity" }, + { 0x01, "Firmware or software change detected with associated Entity" }, + { 0x02, "Hardware incompatibility detected with associated Entity" }, + { 0x03, "Firmware or software incompatibility detected with associated Entity" }, + { 0x04, "Entity is of an invalid or unsupported hardware version" }, + { 0x05, "Entity contains an invalid or unsupported firmware or software version" }, + { 0x06, "Hardware Change detected with associated Entity was successful" }, + { 0x07, "Software or Firmware Change detected with associated Entity was successful" }, + { 0, NULL } +}; + +static const value_string ssoff_2c[] = { + { 0x00, "M0 - FRU Not Installed" }, + { 0x01, "M1 - FRU Inactive" }, + { 0x02, "M2 - FRU Activation Requested" }, + { 0x03, "M3 - FRU Activation In Progress" }, + { 0x04, "M4 - FRU Active" }, + { 0x05, "M5 - FRU Deactivation Requested" }, + { 0x06, "M6 - FRU Deactivation In Progress" }, + { 0x07, "M7 - FRU Communication Lost" }, + { 0, NULL } +}; + +static const value_string ssoff_f0[] = { + { 0x00, "M0 - FRU Not Installed" }, + { 0x01, "M1 - FRU Inactive" }, + { 0x02, "M2 - FRU Activation Requested" }, + { 0x03, "M3 - FRU Activation In Progress" }, + { 0x04, "M4 - FRU Active" }, + { 0x05, "M5 - FRU Deactivation Requested" }, + { 0x06, "M6 - FRU Deactivation In Progress" }, + { 0x07, "M7 - FRU Communication Lost" }, + { 0, NULL } +}; + +static const value_string ssoff_f1[] = { + { 0x00, "IPMB-A disabled, IPMB-B disabled" }, + { 0x01, "IPMB-A enabled, IPMB-B disabled" }, + { 0x02, "IPMB-A disabled, IPMB-B enabled" }, + { 0x03, "IPMB-A enabled, IPMB-B enabled" }, + { 0, NULL } +}; + +static const value_string ssoff_f2[] = { + { 0x00, "Module handle closed" }, + { 0x01, "Module handle open" }, + { 0x02, "Quiesced" }, + { 0x03, "Backend Power Failure" }, + { 0x04, "Backend Power Shut Down" }, + { 0, NULL } +}; + +static const value_string ssoff_f3[] = { + { 0x00, "Global status change" }, + { 0x01, "Channel status change" }, + { 0, NULL } +}; + +static const value_string ssoff_f4[] = { + { 0x00, "Minor Reset" }, + { 0x01, "Major Reset" }, + { 0x02, "Alarm Cutoff" }, + { 0, NULL } +}; + +static gboolean +ssi_05_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + if (b == 0x3 && offs == 0x04) { + /* LAN Leash Lost */ + proto_tree_add_text(tree, tvb, 0, 1, "Network controller #: %d", d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_08_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + static const value_string err_vals[] = { + { 0x00, "Vendor mismatch" }, + { 0x01, "Revision mismatch" }, + { 0x02, "Processor missing" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3 && offs == 0x06) { + /* Configuration error */ + ti = proto_tree_add_text(tree, tvb, 0, 1, "Error type"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3); + tmp = d & 0x0f; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sError type: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, err_vals, "Reserved"), tmp); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_0c_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x3) { + proto_tree_add_text(tree, tvb, 0, 1, "Memory module/device ID: %d", d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_0f_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + static const value_string err_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "No system memory is physically installed" }, + { 0x02, "No usable system memory" }, + { 0x03, "Unrecoverable hard-disk/ATAPI/IDE device failure" }, + { 0x04, "Unrecoverable system board failure" }, + { 0x05, "Unrecoverable diskette subsystem failure" }, + { 0x06, "Unrecoverable hard-disk controller failure" }, + { 0x07, "Unrecoverable PS/2 or USB keyboard failure" }, + { 0x08, "Removable boot media not found" }, + { 0x09, "Unrecoverable video controller failure" }, + { 0x0a, "No video device detected" }, + { 0x0b, "Firmware (BIOS) ROM corruption detected" }, + { 0x0c, "CPU voltage mismatch" }, + { 0x0d, "CPU speed matching failure" }, + { 0, NULL } + }; + static const value_string progress_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "Memory initialization" }, + { 0x02, "Hard-disk initialization" }, + { 0x03, "Secondary processor(s) initialization" }, + { 0x04, "User authentication" }, + { 0x05, "User-initiated system setup" }, + { 0x06, "USB resource configuration" }, + { 0x07, "PCI resource configuration" }, + { 0x08, "Option ROM initialization" }, + { 0x09, "Video initialization" }, + { 0x0a, "Cache initialization" }, + { 0x0b, "SM Bus initialization" }, + { 0x0c, "Keyboard controller initialization" }, + { 0x0d, "Embedded controller / management controller initialization" }, + { 0x0e, "Docking station attachment" }, + { 0x0f, "Enabling docking station" }, + { 0x10, "Docking station ejection" }, + { 0x11, "Disabling docking station" }, + { 0x12, "Calling operating system wake-up vector" }, + { 0x13, "Starting operating system boot process" }, + { 0x14, "Baseboard or motherboard initialization" }, + { 0x16, "Floppy initialization" }, + { 0x17, "Keyboard test" }, + { 0x18, "Pointing device test" }, + { 0x19, "Primary processor initialization" }, + { 0, NULL } + }; + + if (b == 0x3 && offs == 0x00) { + proto_tree_add_text(tree, tvb, 0, 1, "Extension code: %s (0x%02x)", + val_to_str(d, err_vals, "Reserved"), d); + return TRUE; + } + if (b == 0x3 && (offs == 0x01 || offs == 0x02)) { + proto_tree_add_text(tree, tvb, 0, 1, "Extension code: %s (0x%02x)", + val_to_str(d, progress_vals, "Reserved"), d); + return TRUE; + } + return FALSE; +} + +static const struct evtype_info *ssi_10_saveptr; + +static gboolean +ssi_10_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + if (b == 0x3 && offs == 0x00) { + proto_tree_add_text(tree, tvb, 0, 1, "Memory module/device ID: %d", d); + return TRUE; + } + if (b == 0x3 && offs == 0x01) { + ssi_10_saveptr = get_evtype_info(d); + proto_tree_add_text(tree, tvb, 0, 1, "Event/reading type: %s (0x%02x)", + ssi_10_saveptr->desc, d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_10_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + proto_item *ti; + proto_tree *s_tree; + const value_string *off_vals; + + if (b == 0x3 && offs == 0x01) { + if (!ssi_10_saveptr) { + return FALSE; /* something went wrong */ + } + off_vals = ssi_10_saveptr->offsets ? ssi_10_saveptr->offsets : et_empty; + ti = proto_tree_add_text(tree, tvb, 0, 1, "Logging details/Offset"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3); + proto_tree_add_text(tree, tvb, 0, 1, "%sLogging disable for all events of given type: %s", + ipmi_dcd8(d, 0x20), (d & 0x20) ? "True" : "False"); + proto_tree_add_text(tree, tvb, 0, 1, "%s%s event", + ipmi_dcd8(d, 0x10), (d & 0x10) ? "Deassertion" : "Assertion"); + d &= 0x0f; + proto_tree_add_text(tree, tvb, 0, 1, "%sEvent Offset: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(d, off_vals, "Unknown"), d); + return TRUE; + } + if (b == 0x3 && offs == 0x05) { + proto_tree_add_text(tree, tvb, 0, 1, "SEL filled: %d%%", d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_12_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + static const value_string act_vals[] = { + { 0x00, "Entry added" }, + { 0x01, "Entry added because event did not map to standard IPMI event" }, + { 0x02, "Entry added along with one or more corresponding SEL entries" }, + { 0x03, "Log cleared" }, + { 0x04, "Log disabled" }, + { 0x05, "Log enabled" }, + { 0, NULL } + }; + static const value_string type_vals[] = { + { 0x00, "MCA Log" }, + { 0x01, "OEM 1" }, + { 0x02, "OEM 2" }, + { 0, NULL } + }; + static const value_string clock_vals[] = { + { 0x00, "SEL Timestamp Clock updated" }, + { 0x01, "SDR Timestamp Clock updated" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3 && offs == 0x03) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Log action/type"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d >> 4; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sLog entry action: %s (0x%02x)", + ipmi_dcd8(d, 0xf0), val_to_str(tmp, act_vals, "Reserved"), tmp); + tmp = d & 0x0f; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sLog type: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, type_vals, "Reserved"), tmp); + return TRUE; + } + if (b == 0x3 && offs == 0x04) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "PEF Actions to be taken"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sDiagnostic interrupt (NMI): %s", + ipmi_dcd8(d, 0x20), (d & 0x20) ? "True" : "False"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sOEM Action: %s", + ipmi_dcd8(d, 0x10), (d & 0x10) ? "True" : "False"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPower Cycle: %s", + ipmi_dcd8(d, 0x08), (d & 0x08) ? "True" : "False"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sReset: %s", + ipmi_dcd8(d, 0x04), (d & 0x04) ? "True" : "False"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPower Off: %s", + ipmi_dcd8(d, 0x02), (d & 0x02) ? "True" : "False"); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sAlert: %s", + ipmi_dcd8(d, 0x01), (d & 0x01) ? "True" : "False"); + return TRUE; + } + if (b == 0x3 && offs == 0x05) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Details"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sEvent is %s of pair", + ipmi_dcd8(d, 0x80), (d & 0x80) ? "second" : "first"); + tmp = d & 0x0f; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sTimestamp clock type: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, clock_vals, "Reserved"), tmp); + } + return FALSE; +} + +static gboolean +ssi_19_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + if (b == 0x3 && offs == 0x00) { + proto_tree_add_text(tree, tvb, 0, 1, "Requested power state: %s (0x%02x)", + val_to_str(d, ssoff_22, "Reserved"), d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_19_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + if (b == 0x3 && offs == 0x00) { + proto_tree_add_text(tree, tvb, 0, 1, "Power state at time of request: %s (0x%02x)", + val_to_str(d, ssoff_22, "Reserved"), d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_1d_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + /* Copied from ipmi_chassis.c */ + static const value_string cause_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "Chassis Control command" }, + { 0x02, "Reset via pushbutton" }, + { 0x03, "Power-up via pushbutton" }, + { 0x04, "Watchdog expiration" }, + { 0x05, "OEM" }, + { 0x06, "Automatic power-up on AC being applied due to 'always restore' power restore policy" }, + { 0x07, "Automatic power-up on AC being applied due to 'restore previous power state' power restore policy" }, + { 0x08, "Reset via PEF" }, + { 0x09, "Power-cycle via PEF" }, + { 0x0a, "Soft reset" }, + { 0x0b, "Power-up via RTC wakeup" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3 && offs == 0x07) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Restart cause"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d & 0x0f; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sRestart cause: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, cause_vals, "Reserved"), tmp); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_1d_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + gchar s[ITEM_LABEL_LENGTH]; + + ipmi_fmt_channel(s, d); + if (b == 0x3 && offs == 0x07) { + proto_tree_add_text(tree, tvb, 0, 1, "Channel: %s", s); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_21_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string type_vals[] = { + { 0x00, "PCI" }, + { 0x01, "Drive Array" }, + { 0x02, "External Peripheral Connector" }, + { 0x03, "Docking" }, + { 0x04, "Other standard internal expansion slot" }, + { 0x05, "Slot associated with entity specified by Entity ID for sensor" }, + { 0x06, "AdvancedTCA" }, + { 0x07, "DIMM/Memory device" }, + { 0x08, "FAN" }, + { 0x09, "PCI Express" }, + { 0x0a, "SCSI (parallel)" }, + { 0x0b, "SATA/SAS" }, + { 0, NULL } + }; + + if (b == 0x3) { + proto_tree_add_text(tree, tvb, 0, 1, "Slot/connector type: %s (0x%02x)", + val_to_str(d, type_vals, "Reserved"), d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_21_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x3) { + proto_tree_add_text(tree, tvb, 0, 1, "Slot/connector #: %d", d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_23_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string intr_vals[] = { + { 0x00, "None" }, + { 0x01, "SMI" }, + { 0x02, "NMI" }, + { 0x03, "Messaging interrupt" }, + { 0x0f, "Unspecified" }, + { 0, NULL } + }; + static const value_string use_vals[] = { + { 0x01, "BIOS FRB2" }, + { 0x02, "BIOS/POST" }, + { 0x03, "OS Load" }, + { 0x04, "SMS/OS" }, + { 0x05, "OEM" }, + { 0x0f, "Unspecified" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Timer use/interrupt"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d >> 4; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sInterrupt type: %s (0x%02x)", + ipmi_dcd8(d, 0xf0), val_to_str(tmp, intr_vals, "Reserved"), tmp); + tmp = d & 0x0f; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sTimer use at expiration: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, use_vals, "Reserved"), tmp); + + return TRUE; + } + return FALSE; +} + +static int ssi28_is_logical_fru; + +static gboolean +ssi_28_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3 && (offs == 0x00 || offs == 0x04)) { + proto_tree_add_text(tree, tvb, 0, 1, "Sensor number: %d", d); + return TRUE; + } + if (b == 0x3 && offs == 0x05) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "FRU details"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + ssi28_is_logical_fru = (d & 0x80) ? 1 : 0; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sLogical FRU device: %s", + ipmi_dcd8(d, 0x80), ssi28_is_logical_fru ? "True" : "False"); + tmp = (d & 0x18) >> 3; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sLUN for Master Read-Write command: 0x%02x", + ipmi_dcd8(d, 0x18), tmp); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrivate Bus ID: 0x%02x", + ipmi_dcd8(d, 0x07), d & 0x07); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_28_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x3 && offs == 0x05) { + if (ssi28_is_logical_fru == -1) { + return FALSE; /* something went wrong */ + } + if (ssi28_is_logical_fru) { + proto_tree_add_text(tree, tvb, 0, 1, "FRU Device ID within controller: 0x%02x", d); + } else { + proto_tree_add_text(tree, tvb, 0, 1, "I2C Slave Address: 0x%02x", d); + } + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_2a_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + proto_item *ti; + proto_tree *s_tree; + + if (b == 0x3) { + d &= 0x3f; + ti = proto_tree_add_text(tree, tvb, 0, 1, "User ID: %d", d); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + if (d) { + proto_tree_add_text(s_tree, tvb, 0, 1, "%sUser ID: %d", + ipmi_dcd8(d, 0x3f), d); + } else { + proto_tree_add_text(s_tree, tvb, 0, 1, "%sUser ID: unspecified (%d)", + ipmi_dcd8(d, 0x3f), d); + } + } + return FALSE; +} + +static gboolean +ssi_2a_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string deact_vals[] = { + { 0x00, "Unspecified cause" }, + { 0x01, "Close Session command" }, + { 0x02, "Timeout" }, + { 0x03, "Configuration change" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + gchar s[ITEM_LABEL_LENGTH]; + guint32 tmp; + + if (b == 0x3) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Deactivation cause/Channel #"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3); + tmp = (d >> 4) & 0x3; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sSession deactivated by: %s (0x%02x)", + ipmi_dcd8(d, 0x30), val_to_str(tmp, deact_vals, "Reserved"), tmp); + ipmi_fmt_channel(s, d & 0xf); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sChannel: %s", + ipmi_dcd8(d, 0x0f), s); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_2b_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string vctype_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "Management controller device ID" }, + { 0x02, "Management controller firmware revision" }, + { 0x03, "Management controller device revision" }, + { 0x04, "Management controller manufacturer ID" }, + { 0x05, "Management controller IPMI version" }, + { 0x06, "Management controller auxillary firmware ID" }, + { 0x07, "Management controller firmware boot block" }, + { 0x08, "Other management controller firmware" }, + { 0x09, "System firmware (EFI/BIOS) change" }, + { 0x0a, "SMBIOS change" }, + { 0x0b, "Operating system change" }, + { 0x0c, "Operating system loader change" }, + { 0x0d, "Service or diagnostic partition change" }, + { 0x0e, "Management software agent change" }, + { 0x0f, "Management software application change" }, + { 0x10, "Management software middleware change" }, + { 0x11, "Programmable hardware change" }, + { 0x12, "Board/FRU module change" }, + { 0x13, "Board/FRU component change" }, + { 0x14, "Board/FRU replaced with equivalent version" }, + { 0x15, "Board/FRU replaced with newer version" }, + { 0x16, "Board/FRU replaced with older version" }, + { 0x17, "Board/FRU configuration change" }, + { 0, NULL } + }; + + if (b == 0x3) { + proto_tree_add_text(tree, tvb, 0, 1, "Version change type: %s", + val_to_str(d, vctype_vals, "Reserved")); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_2c_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string cause_vals[] = { + { 0x00, "Normal State Change" }, + { 0x01, "Change commanded by software external to FRU" }, + { 0x02, "State Change due to operator changing a handle latch" }, + { 0x03, "State Change due to operator pressing the hot swap push button" }, + { 0x04, "State Change due to FRU programmatic action" }, + { 0x05, "Communication lost" }, + { 0x06, "Communication lost due to local failure" }, + { 0x07, "State Change due to unexpected extraction" }, + { 0x08, "State Change due to operator intervention/update" }, + { 0x09, "Unable to compute IPMB address" }, + { 0x0a, "Unexpected Deactivation" }, + { 0x0f, "State Change, Cause Unknown" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x3) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/Cause"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d >> 4; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sCause: %s (0x%02x)", + ipmi_dcd8(d, 0xf0), val_to_str(tmp, cause_vals, "Reserved"), tmp); + tmp = d & 0xf; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, si->offsets, "Reserved"), tmp); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_f0_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const value_string cause_vals[] = { + { 0x00, "Normal State Change" }, + { 0x01, "Change Commanded by Shelf Manager with Set FRU Activation" }, + { 0x02, "State Change due to operator changing a Handle Switch" }, + { 0x03, "State Change due to FRU programmatic action" }, + { 0x04, "Communication Lost or Regained" }, + { 0x05, "Communication Lost or Regained - locally detected" }, + { 0x06, "Surprise State Change due to extraction" }, + { 0x07, "State Change due to provided information" }, + { 0x08, "Invalid Hardware Address Detected" }, + { 0x09, "Unexpected Deactivation" }, + { 0x0f, "State Change, Cause Unknown" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x2) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/Cause"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d >> 4; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sCause: %s (0x%02x)", + ipmi_dcd8(d, 0xf0), val_to_str(tmp, cause_vals, "Reserved"), tmp); + tmp = d & 0xf; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)", + ipmi_dcd8(d, 0x0f), val_to_str(tmp, si->offsets, "Reserved"), tmp); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_f0_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + if (b == 0x2) { + proto_tree_add_text(tree, tvb, 0, 1, "FRU Id: %d", d); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_f1_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + proto_item *ti; + proto_tree *s_tree; + gchar s[ITEM_LABEL_LENGTH]; + + if (b == 0x02) { + ipmi_fmt_channel(s, d >> 4); + ti = proto_tree_add_text(tree, tvb, 0, 1, "Channel: %s", s); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + proto_tree_add_text(s_tree, tvb, 0, 1, "%sChannel: %s", + ipmi_dcd8(d, 0xf0), s); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_f1_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs _U_, guint32 d) +{ + static const char *override_state[2] = { + "Override state, bus isolated", + "Local control state" + }; + static const value_string status_vals[] = { + { 0x00, "No failure" }, + { 0x01, "Unable to drive clock HI" }, + { 0x02, "Unable to drive data HI" }, + { 0x03, "Unable to drive clock LO" }, + { 0x04, "Unable to drive data LO" }, + { 0x05, "Clock low timeout" }, + { 0x06, "Under test" }, + { 0x07, "Undiagnosed communications failure" }, + { 0, NULL } + }; + proto_item *ti; + proto_tree *s_tree; + guint32 tmp; + + if (b == 0x02) { + ti = proto_tree_add_text(tree, tvb, 0, 1, "Override state / Local status"); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3); + tmp = d & 0x80; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-B Override state: %s", + ipmi_dcd8(d, 0x80), override_state[!!tmp]); + tmp = (d & 0x70) >> 4; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-B Local status: %s (0x%02x)", + ipmi_dcd8(d, 0x70), val_to_str(tmp, status_vals, "Reserved"), tmp); + tmp = d & 0x08; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-A Override state: %s", + ipmi_dcd8(d, 0x08), override_state[!!tmp]); + tmp = d & 0x07; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-A Local status: %s (0x%02x)", + ipmi_dcd8(d, 0x07), val_to_str(tmp, status_vals, "Reserved"), tmp); + return TRUE; + } + return FALSE; +} + +static gboolean +ssi_f3_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + proto_tree *s_tree; + proto_item *ti; + guint32 tmp; + + if (b == 0x02 && offs == 0x00) { + /* Global status change */ + ti = proto_tree_add_text(tree, tvb, 0, 1, "Global Status: 0x%02x", d); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d & 0x08; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sRedundant PM: %s", + ipmi_dcd8(d, 0x08), + tmp ? "providing Payload Current" : + "not providing Payload Current (or this is Primary PM)"); + tmp = d & 0x04; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power: %s", + ipmi_dcd8(d, 0x04), tmp ? "is good" : "is not good"); + tmp = d & 0x02; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power: %s", + ipmi_dcd8(d, 0x02), tmp ? "is good" : "is not good"); + tmp = d & 0x01; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sRole: %s", + ipmi_dcd8(d, 0x01), tmp ? "Primary" : "Redundant"); + return TRUE; + } else if (b == 0x02 && offs == 0x01) { + /* Channel status change */ + ti = proto_tree_add_text(tree, tvb, 0, 1, "Channel Status: 0x%02x", d); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2); + tmp = d & 0x40; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPWR_ON: %s", + ipmi_dcd8(d, 0x40), tmp ? "asserted" : "not asserted/not supported"); + tmp = d & 0x20; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power Overcurrent: %s", + ipmi_dcd8(d, 0x20), tmp ? "has been detected" : "has not been detected"); + tmp = d & 0x10; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power: %s", + ipmi_dcd8(d, 0x10), tmp ? "is enabled" : "is disabled"); + tmp = d & 0x08; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sENABLE#: %s", + ipmi_dcd8(d, 0x08), tmp ? "asserted" : "not asserted"); + tmp = d & 0x04; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power Overcurrent: %s", + ipmi_dcd8(d, 0x04), tmp ? "has been detected" : "has not been detected"); + tmp = d & 0x02; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power: %s", + ipmi_dcd8(d, 0x02), tmp ? "is enabled" : "is disabled"); + tmp = d & 0x01; + proto_tree_add_text(s_tree, tvb, 0, 1, "%sPS1#: %s", + ipmi_dcd8(d, 0x01), tmp ? "asserted" : "not asserted"); + return TRUE; + } + + return FALSE; +} + +static gboolean +ssi_f3_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_, + guint32 b, guint32 offs, guint32 d) +{ + if (b == 0x02 && offs == 0x01) { + /* Channel status change */ + proto_tree_add_text(tree, tvb, 0, 1, "Power Channel number: %d", d); + return TRUE; + } + + return FALSE; +} + +static void +reinit_statics(void) +{ + ssi_10_saveptr = NULL; + ssi28_is_logical_fru = -1; +} + +static const struct sensor_info * +get_sensor_info(unsigned int stype) +{ + static const struct { + unsigned int id; + struct sensor_info si; + } si_tab[] = { + { 0x01, { NULL, NULL, NULL, "Temperature" }}, + { 0x02, { NULL, NULL, NULL, "Voltage" }}, + { 0x03, { NULL, NULL, NULL, "Current" }}, + { 0x04, { NULL, NULL, NULL, "Fan" }}, + { 0x05, { ssoff_05, ssi_05_2, NULL, "Physical Security (Chassis Intrusion)" }}, + { 0x06, { ssoff_06, NULL, NULL, "Platform Security Violation Attempt" }}, + { 0x07, { ssoff_07, NULL, NULL, "Processor" }}, + { 0x08, { ssoff_08, NULL, ssi_08_3, "Power Supply" }}, + { 0x09, { ssoff_09, NULL, NULL, "Power Unit" }}, + { 0x0a, { NULL, NULL, NULL, "Cooling Device" }}, + { 0x0b, { NULL, NULL, NULL, "Other Units-based Sensor (per units given in SDR)" }}, + { 0x0c, { ssoff_0c, NULL, ssi_0c_3, "Memory" }}, + { 0x0d, { ssoff_0d, NULL, NULL, "Drive Slot (Bay)" }}, + { 0x0e, { NULL, NULL, NULL, "POST Memory Resize" }}, + { 0x0f, { ssoff_0f, ssi_0f_2, NULL, "System Firmware Progress (formerly POST Error)" }}, + { 0x10, { ssoff_10, ssi_10_2, ssi_10_3, "Event Logging Disabled" }}, + { 0x11, { ssoff_11, NULL, NULL, "Watchdog 1" }}, + { 0x12, { ssoff_12, ssi_12_2, NULL, "System Event" }}, + { 0x13, { ssoff_13, NULL, NULL, "Critical Interrupt" }}, + { 0x14, { ssoff_14, NULL, NULL, "Button" }}, + { 0x15, { NULL, NULL, NULL, "Module / Board" }}, + { 0x16, { NULL, NULL, NULL, "Microcontroller / Coprocessor" }}, + { 0x17, { NULL, NULL, NULL, "Add-in Card" }}, + { 0x18, { NULL, NULL, NULL, "Chassis" }}, + { 0x19, { ssoff_19, ssi_19_2, ssi_19_3, "Chip Set" }}, + { 0x1a, { NULL, NULL, NULL, "Other FRU" }}, + { 0x1b, { ssoff_1b, NULL, NULL, "Cable / Interconnect" }}, + { 0x1c, { NULL, NULL, NULL, "Terminator" }}, + { 0x1d, { ssoff_1d, ssi_1d_2, ssi_1d_3, "System Boot / Restart Initiated" }}, + { 0x1e, { ssoff_1e, NULL, NULL, "Boot Error" }}, + { 0x1f, { ssoff_1f, NULL, NULL, "OS Boot" }}, + { 0x20, { ssoff_20, NULL, NULL, "OS Critical Stop" }}, + { 0x21, { ssoff_21, ssi_21_2, ssi_21_3, "Slot / Connector" }}, + { 0x22, { ssoff_22, NULL, NULL, "System ACPI Power State" }}, + { 0x23, { ssoff_23, ssi_23_2, NULL, "Watchdog 2" }}, + { 0x24, { ssoff_24, NULL, NULL, "Platform Alert" }}, + { 0x25, { ssoff_25, NULL, NULL, "Entity Presence" }}, + { 0x26, { NULL, NULL, NULL, "Monitor ASIC / IC" }}, + { 0x27, { ssoff_27, NULL, NULL, "LAN" }}, + { 0x28, { ssoff_28, ssi_28_2, ssi_28_3, "Management Subsystem Health" }}, + { 0x29, { ssoff_29, NULL, NULL, "Battery" }}, + { 0x2a, { ssoff_2a, ssi_2a_2, ssi_2a_3, "Session Audit" }}, + { 0x2b, { ssoff_2b, ssi_2b_2, NULL, "Version Change" }}, + { 0x2c, { ssoff_2c, ssi_2c_2, NULL, "FRU State" }}, + { 0xf0, { ssoff_f0, ssi_f0_2, ssi_f0_3, "Hot Swap (ATCA)" }}, + { 0xf1, { ssoff_f1, ssi_f1_2, ssi_f1_3, "IPMB Physical State (ATCA)" }}, + { 0xf2, { ssoff_f2, NULL, NULL, "Module Hot Swap (AMC.0)" }}, + { 0xf3, { ssoff_f3, ssi_f3_2, ssi_f3_3, "Power Channel Notification" }}, + { 0xf4, { ssoff_f4, NULL, NULL, "Telco Alarm Input" }} + }; + static const struct sensor_info si_oem = { + NULL, NULL, NULL, "OEM Reserved" + }; + static const struct sensor_info si_rsrv = { + NULL, NULL, NULL, "Reserved" + }; + unsigned int i; + + /* Look for explicitly defined ones */ + for (i = 0; i < array_length(si_tab); i++) { + if (si_tab[i].id == stype) { + return &si_tab[i].si; + } + } + + if (stype >= 0xc0 && stype <= 0xff) { + return &si_oem; + } + + return &si_rsrv; +}; + +static void +parse_platform_event(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree; + tvbuff_t *next_tvb; + unsigned int stype, evtype; + const struct sensor_info *si; + const struct evtype_info *eti; + unsigned int d, b2, b3, offs; + const value_string *off_vals; + + stype = tvb_get_guint8(tvb, 1); + si = get_sensor_info(stype); + evtype = tvb_get_guint8(tvb, 3) & 0x7f; + eti = get_evtype_info(evtype); + + proto_tree_add_item(tree, hf_ipmi_se_evt_rev, tvb, 0, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_se_evt_sensor_type, tvb, 1, 1, stype, + "%s (0x%02x)", si->desc, stype); + proto_tree_add_item(tree, hf_ipmi_se_evt_sensor_num, tvb, 2, 1, TRUE); + ti = proto_tree_add_item(tree, hf_ipmi_se_evt_byte3, tvb, 3, 1, TRUE); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_byte3); + proto_tree_add_item(s_tree, hf_ipmi_se_evt_dir, tvb, 3, 1, TRUE); + proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_type, tvb, 3, 1, evtype, + "%sEvent/Reading type: %s (0x%02x)", ipmi_dcd8(evtype, 0x7f), + eti->desc, evtype); + + offs = tvb_get_guint8(tvb, 4); + b2 = offs >> 6; + b3 = (offs >> 4) & 0x3; + off_vals = eti->offsets ? eti->offsets : si->offsets ? si->offsets : et_empty; + + ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data1, tvb, 4, 1, TRUE); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte1); + proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_b2, tvb, 4, 1, b2 << 6, + "%sByte 2: %s (0x%02x)", + ipmi_dcd8(offs, 0xc0), val_to_str(b2, eti->byte2, "Reserved"), b2); + proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_b3, tvb, 4, 1, b3 << 4, + "%sByte 3: %s (0x%02x)", + ipmi_dcd8(offs, 0x30), val_to_str(b3, eti->byte3, "Reserved"), b3); + offs &= 0x0f; + proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_offs, tvb, 4, 1, offs, + "%sOffset: %s (0x%02x)", + ipmi_dcd8(offs, 0x0f), val_to_str(offs, off_vals, "Reserved"), offs); + + /* This is tricky. First, bytes 2-3 are optional and may be absent. + Second, the necessity to interpret them either in a generic way or in + sensor-specific way depends on the value in byte 1. And at last, + there could be mixture of both ways: the byte 2 can relate to + 'previous state', which could be sensor-specific. + + Thus, intrp() methods return whether they actually handled the + value. If the 'generic' (related to event/reading type) method fails + to handle the value, we call the 'specific' one. If that fails as + well, we just output it as a hex value. + + This is further complicated by the fact that in some events, the + interpretation of the byte 3 depends on the 2nd byte - which could + be specified as having some generic type. Thus, we check it and + fall back to "default" display in such weird cases. + */ + reinit_statics(); + if (tvb_length(tvb) <= 5) { + return; + } + + next_tvb = tvb_new_subset(tvb, 5, 1, 1); + d = tvb_get_guint8(next_tvb, 0); + if ((eti->intrp2 && eti->intrp2(tree, next_tvb, si, b2, offs, d)) + || (si->intrp2 && si->intrp2(tree, next_tvb, si, b2, offs, d))) { + /* One of them succeeded. */ + ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data2, next_tvb, 0, 1, TRUE); + PROTO_ITEM_SET_HIDDEN(ti); + } else { + /* Just add as hex */ + proto_tree_add_item(tree, hf_ipmi_se_evt_data2, next_tvb, 0, 1, TRUE); + } + + /* Now the same for byte 3 */ + if (tvb_length(tvb) <= 6) { + return; + } + + next_tvb = tvb_new_subset(tvb, 6, 1, 1); + d = tvb_get_guint8(next_tvb, 0); + if ((eti->intrp3 && eti->intrp3(tree, next_tvb, si, b3, offs, d)) + || (si->intrp3 && si->intrp3(tree, next_tvb, si, b3, offs, d))) { + /* One of them succeeded. */ + ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data3, next_tvb, 0, 1, TRUE); + PROTO_ITEM_SET_HIDDEN(ti); + } else { + /* Just add as hex */ + proto_tree_add_item(tree, hf_ipmi_se_evt_data3, next_tvb, 0, 1, TRUE); + } +} + +/* Common for set/get config parameters */ +static const value_string cp00_sip_vals[] = { + { 0x00, "Set complete" }, + { 0x01, "Set in progress" }, + { 0x02, "Commit write" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string cp10_use_tfs = { + "BMC uses the following value", + "BMC uses the value returned from Get System GUID command" +}; + +static const struct true_false_string cp15_rq_frc_tfs = { + "Force control operation", + "Request control operation" +}; + +static const struct true_false_string cp15_imm_delay_tfs = { + "Delayed control", + "Immediate control" +}; + +static const value_string cp15_op_vals[] = { + { 0x00, "Power down" }, + { 0x01, "Power up" }, + { 0x02, "Power cycle" }, + { 0x03, "Hard reset" }, + { 0x04, "Pulse diagnostic interrupt" }, + { 0x05, "Initiate a soft-shutdown of OS via ACPI by emulating a fatal overtemperature" }, + { 0, NULL } +}; + +static void +cfgparam_00(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp00_sip, tvb, 0, 1, TRUE); +} + +static void +cfgparam_01(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp01_alert_startup, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp01_startup, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp01_event_msg, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp01_pef, tvb, 0, 1, TRUE); +} + +static void +cfgparam_02(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp02_diag_intr, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp02_oem_action, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp02_pwr_cycle, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp02_reset, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp02_pwr_down, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp02_alert, tvb, 0, 1, TRUE); +} + + +static void +cfgparam_03(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp03_startup, tvb, 0, 1, TRUE); +} + +static void +cfgparam_04(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp04_alert_startup, tvb, 0, 1, TRUE); +} + +static void +cfgparam_05(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp05_num_evfilters, tvb, 0, 1, TRUE); +} + +static void +cfgparam_06(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp06_filter, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp06_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_cp06_data, tvb, 1, 20, TRUE); +} + +static void +cfgparam_07(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp07_filter, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp07_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_cp06_data, tvb, 1, 1, TRUE); +} + +static void +cfgparam_08(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp08_policies, tvb, 0, 1, TRUE); +} + +static void +cfgparam_09(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp09_entry, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp09_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_cp09_data, tvb, 1, 3, TRUE); +} + +static void +cfgparam_10(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp10_useval, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp10_byte1, byte1, TRUE, 0); + ipmi_add_guid(tree, hf_ipmi_se_cp10_guid, tvb, 1); +} + +static void +cfgparam_11(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp11_num_alertstr, tvb, 0, 1, TRUE); +} + +static void +cfgparam_12(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_cp12_evfilter, NULL }; + static const int *byte3[] = { &hf_ipmi_se_cp12_alert_stringset, NULL }; + proto_item *ti; + proto_tree *s_tree; + guint8 tmp; + + ti = proto_tree_add_item(tree, hf_ipmi_se_cp12_byte1, tvb, 0, 1, TRUE); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_cp12_byte1); + tmp = tvb_get_guint8(tvb, 0) & 0x7f; + if (tmp) { + proto_tree_add_item(s_tree, hf_ipmi_se_cp12_alert_stringsel, tvb, 0, 1, TRUE); + } else { + proto_tree_add_uint_format(s_tree, hf_ipmi_se_cp12_alert_stringsel, tvb, 0, 1, + tmp, "%sSelects volatile string parameters", ipmi_dcd8(tmp, 0x7f)); + } + + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_cp12_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_se_cp12_byte3, byte3, TRUE, 0); +} + +static void +cfgparam_13(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp13_stringsel, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp13_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_cp13_blocksel, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_cp13_string, tvb, 2, tvb_length(tvb) - 2, TRUE); +} + +static void +cfgparam_14(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_cp14_num_gct, tvb, 0, 1, TRUE); +} + +static void +cp15_add_group_and_member(proto_tree *tree, tvbuff_t *tvb, guint offs, guint num) +{ + static const int *byte2[] = { &hf_ipmi_se_cp15_member_check, &hf_ipmi_se_cp15_member_id, NULL }; + const char *gdesc; + guint8 tmp; + + tmp = tvb_get_guint8(tvb, offs); + if (tmp == 0x00) { + gdesc = " (unspecified)"; + } else if (tmp == 0xff) { + gdesc = " (all groups)"; + } else { + gdesc = ""; + } + + proto_tree_add_uint_format(tree, hf_ipmi_se_cp15_group, tvb, offs, 1, tmp, + "Group ID %d: %d%s", num, tmp, gdesc); + proto_tree_add_bitmask_text(tree, tvb, offs + 1, 1, NULL, NULL, ett_ipmi_se_cp15_member, byte2, TRUE, 0); +} + +static void +cfgparam_15(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_cp15_gctsel, NULL }; + static const int *byte2[] = { &hf_ipmi_se_cp15_force, &hf_ipmi_se_cp15_delayed, &hf_ipmi_se_cp15_channel, NULL }; + static const int *byte11[] = { &hf_ipmi_se_cp15_retries, &hf_ipmi_se_cp15_operation, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp15_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_cp15_byte2, byte2, TRUE, 0); + cp15_add_group_and_member(tree, tvb, 2, 0); + cp15_add_group_and_member(tree, tvb, 4, 1); + cp15_add_group_and_member(tree, tvb, 6, 2); + cp15_add_group_and_member(tree, tvb, 8, 3); + proto_tree_add_bitmask_text(tree, tvb, 10, 1, NULL, NULL, ett_ipmi_se_cp15_byte11, byte11, TRUE, 0); +} + +static struct { + void (*intrp)(tvbuff_t *tvb, proto_tree *tree); + const char *name; +} conf_params[] = { + { cfgparam_00, "Set In Progress" }, + { cfgparam_01, "PEF Control" }, + { cfgparam_02, "PEF Action global control" }, + { cfgparam_03, "PEF Startup Delay" }, + { cfgparam_04, "PEF Alert Startup Delay" }, + { cfgparam_05, "Number of Event Filters" }, + { cfgparam_06, "Event Filter Table" }, + { cfgparam_07, "Event Filter Table Data 1" }, + { cfgparam_08, "Number of Alert Policy Entries" }, + { cfgparam_09, "Alert Policy Table" }, + { cfgparam_10, "System GUID" }, + { cfgparam_11, "Number of Alert Strings" }, + { cfgparam_12, "Alert String Keys" }, + { cfgparam_13, "Alert Strings" }, + { cfgparam_14, "Number of Group Control Table Entries" }, + { cfgparam_15, "Group Control Table" } +}; + +static const value_string vals_11_pef_timer[] = { + { 0x00, "Disable Postpone Timer" }, + { 0xfe, "Temporary PEF disable" }, + { 0xff, "Get Present Countdown Value" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_14_processed = { + "BMC", + "software" +}; + +static const value_string vals_16_op[] = { + { 0x00, "Initiate Alert" }, + { 0x01, "Get Alert Immediate status" }, + { 0x02, "Clear Alert Immediate status" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const value_string vals_16_status[] = { + { 0x00, "No status" }, + { 0x01, "Alert was Normal End" }, + { 0x02, "`Call Retry' retries failed" }, + { 0x03, "Alert failed due to timeouts waiting for acknowledge on all retries" }, + { 0xFF, "Alert by this command is in progress" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_20_op = { + "Get SDR Count", "Get sensor count" +}; + +static const struct true_false_string tfs_20_pop = { + "Dynamic", "Static" +}; + +static const value_string vals_28_act[] = { + { 0x00, "Do not change individual enables" }, + { 0x01, "Enable selected event messages" }, + { 0x02, "Disable selescted event messages" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_28_enable = { + "Enable", "Disable" +}; + +static const struct true_false_string tfs_29_enabled = { + "Enabled", "Disabled" +}; + +static const struct true_false_string tfs_2a_sel = { + "Selected", "All" +}; + +static const struct true_false_string tfs_2b_enabled = { + "Enabled", "Disabled" +}; + +/* Set event receiver. + */ +static void +rq00(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_00_lun, NULL }; + unsigned int addr; + + addr = tvb_get_guint8(tvb, 0); + if (addr == 0xff) { + proto_tree_add_uint_format(tree, hf_ipmi_se_00_addr, tvb, 0, 1, + addr, "Disable Message Generation (0xFF)"); + } else { + proto_tree_add_item(tree, hf_ipmi_se_00_addr, tvb, 0, 1, TRUE); + } + + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_00_byte2, byte2, TRUE, 0); +} + +/* Get event receiver. + */ +static void +rs01(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_01_lun, NULL }; + unsigned int addr; + + addr = tvb_get_guint8(tvb, 0); + if (addr == 0xff) { + proto_tree_add_uint_format(tree, hf_ipmi_se_01_addr, tvb, 0, 1, + addr, "Message Generation Disabled (0xFF)"); + } else { + proto_tree_add_item(tree, hf_ipmi_se_01_addr, tvb, 0, 1, TRUE); + } + + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_01_byte2, byte2, TRUE, 0); +} + +/* Platform event. + */ +static void +rq02(tvbuff_t *tvb, proto_tree *tree) +{ + parse_platform_event(tvb, tree); +} + +/* Get PEF capabilities. + */ +static void +rs10(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_10_action_oem_filter, &hf_ipmi_se_10_action_diag_intr, + &hf_ipmi_se_10_action_oem_action, &hf_ipmi_se_10_action_pwr_cycle, &hf_ipmi_se_10_action_reset, + &hf_ipmi_se_10_action_pwr_down, &hf_ipmi_se_10_action_alert, NULL }; + guint8 v; + + v = tvb_get_guint8(tvb, 0); + proto_tree_add_item(tree, hf_ipmi_se_10_pef_version, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Action support: ", "None", ett_ipmi_se_10_action, + byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_10_entries, tvb, 2, 1, TRUE); +} + +/* Arm PEF Postpone Timer. + */ +static void +rq11(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 val; + + val = tvb_get_guint8(tvb, 0); + proto_tree_add_uint_format(tree, hf_ipmi_se_11_rq_timeout, tvb, 0, 1, + val, val_to_str(val, vals_11_pef_timer, "Arm Timer for: %d sec")); +} + +static void +rs11(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 val; + + val = tvb_get_guint8(tvb, 0); + proto_tree_add_uint_format(tree, hf_ipmi_se_11_rs_timeout, tvb, 0, 1, + val, val_to_str(val, vals_11_pef_timer, "Present Timer Countdown value: %d sec")); +} + +/* Set PEF Configuration Parameters. + */ +static void +rq12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree; + tvbuff_t *sub; + guint8 pno; + const char *desc; + + pno = tvb_get_guint8(tvb, 0) & 0x7f; + if (pno < array_length(conf_params)) { + desc = conf_params[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + ti = proto_tree_add_uint_format(tree, hf_ipmi_se_12_byte1, tvb, 0, 1, + pno, "Parameter selector: %s (0x%02x)", desc, pno); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_12_byte1); + proto_tree_add_uint_format(s_tree, hf_ipmi_se_12_param, tvb, 0, 1, + pno, "%sParameter selector: %s (0x%02x)", + ipmi_dcd8(pno, 0x7f), desc, pno); + + if (pno < array_length(conf_params)) { + sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + conf_params[pno].intrp(sub, tree); + } else { + proto_tree_add_none_format(tree, hf_ipmi_se_12_data, tvb, 1, tvb_length(tvb) - 1, + "Configuration parameter data: %s", desc); + } +} + +static const value_string cc12[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0x83, "Attempt to read write-only parameter" }, + { 0, NULL } +}; + +/* Get PEF Configuration Parameters. + */ +static void +rq13(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree; + guint32 pno; + const char *desc; + + pno = tvb_get_guint8(tvb, 0); + + if (!tree) { + /* Just cache parameter selector */ + ipmi_setsaveddata(0, pno); + return; + } + + pno &= 0x7f; + + if (pno < array_length(conf_params)) { + desc = conf_params[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + ti = proto_tree_add_uint_format(tree, hf_ipmi_se_13_byte1, tvb, 0, 1, + pno, "Parameter selector: %s (0x%02x)", desc, pno); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_13_byte1); + proto_tree_add_item(s_tree, hf_ipmi_se_13_getrev, tvb, 0, 1, TRUE); + proto_tree_add_uint_format(s_tree, hf_ipmi_se_13_param, tvb, 0, 1, + pno, "%sParameter selector: %s (0x%02x)", + ipmi_dcd8(pno, 0x7f), desc, pno); + + proto_tree_add_item(tree, hf_ipmi_se_13_set, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_13_block, tvb, 2, 1, TRUE); +} + +static void +rs13(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_13_rev_present, &hf_ipmi_se_13_rev_compat, NULL }; + proto_item *ti; + tvbuff_t *sub; + guint32 pno; + const char *desc; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Parameter revision", NULL, + ett_ipmi_se_13_rev, byte1, TRUE, 0); + + if (!ipmi_getsaveddata(0, &pno)) { + /* No request found - cannot parse further */ + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, tvb_length(tvb) - 1, TRUE); + } + return; + } + + if ((pno & 0x80) && tvb_length(tvb) > 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter revision; parameter data returned"); + PROTO_ITEM_SET_GENERATED(ti); + } else if (!(pno & 0x80) && tvb_length(tvb) == 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned"); + PROTO_ITEM_SET_GENERATED(ti); + } + + pno &= 0x7f; + if (pno < array_length(conf_params)) { + desc = conf_params[pno].name; + } else if (pno >= 96 && pno <= 127) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc); + PROTO_ITEM_SET_GENERATED(ti); + + if (tvb_length(tvb) > 1) { + if (pno < array_length(conf_params)) { + sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + conf_params[pno].intrp(sub, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, tvb_length(tvb) - 1, TRUE); + } + } +} + +static const value_string cc13[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +/* Set Last Processed Event ID Command. + */ +static void +rq14(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_se_14_processed_by, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_14_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_14_rid, tvb, 1, 2, TRUE); +} + +static const value_string cc14[] = { + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Get Last Processed Event ID Command. + */ +static void +rs15(tvbuff_t *tvb, proto_tree *tree) +{ + guint16 tmp; + + ipmi_add_timestamp(tree, hf_ipmi_se_15_tstamp, tvb, 0); + tmp = tvb_get_letohs(tvb, 4); + if (tmp != 0xffff) { + proto_tree_add_item(tree, hf_ipmi_se_15_lastrec, tvb, 4, 2, TRUE); + } else { + proto_tree_add_uint_format_value(tree, hf_ipmi_se_15_lastrec, tvb, 4, 2, + tmp, "SEL is empty (0x%04x)", tmp); + } + proto_tree_add_item(tree, hf_ipmi_se_15_proc_sw, tvb, 6, 2, TRUE); + tmp = tvb_get_letohs(tvb, 8); + if (tmp != 0x0000) { + proto_tree_add_item(tree, hf_ipmi_se_15_proc_bmc, tvb, 8, 2, TRUE); + } else { + proto_tree_add_uint_format_value(tree, hf_ipmi_se_15_proc_bmc, tvb, 8, 2, + tmp, "Event processed but cannot be logged (0x%04x)", tmp); + } +} + +static const value_string cc15[] = { + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Alert Immediate. + */ +static void +rq16(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_se_16_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_se_16_op, &hf_ipmi_se_16_dst, NULL }; + static const gint *byte3[] = { &hf_ipmi_se_16_send_string, &hf_ipmi_se_16_string_sel, NULL }; + tvbuff_t *sub; + + if (!tree) { + /* Save the operation */ + ipmi_setsaveddata(0, (tvb_get_guint8(tvb, 1) & 0xc0) >> 6); + return; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_16_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_16_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_se_16_byte3, byte3, TRUE, 0); + if (tvb_length(tvb) > 3) { + proto_tree_add_item(tree, hf_ipmi_se_16_gen, tvb, 3, 1, TRUE); + sub = tvb_new_subset(tvb, 4, tvb_length(tvb) - 4, tvb_length(tvb) - 4); + parse_platform_event(sub, tree); + } +} + +static void +rs16(tvbuff_t *tvb, proto_tree *tree) +{ + guint32 val; + + if (ipmi_getsaveddata(0, &val) && val == 0x01) { + /* Operation == Get Alert Immediate Status */ + proto_tree_add_item(tree, hf_ipmi_se_16_status, tvb, 0, 1, TRUE); + } +} + +static const value_string cc16[] = { + { 0x81, "Alert Immediate rejected due to alert already in progress" }, + { 0x82, "Alert Immediate rejected due to IPMI messaging session active on this channel" }, + { 0x83, "Platform Event parameters not supported" }, + { 0, NULL } +}; + +/* PET Acknowledge. + */ +static void +rq17(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_17_seq, tvb, 0, 2, TRUE); + ipmi_add_timestamp(tree, hf_ipmi_se_17_tstamp, tvb, 2); + proto_tree_add_item(tree, hf_ipmi_se_17_evsrc, tvb, 6, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_17_sensor_dev, tvb, 7, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_17_sensor_num, tvb, 8, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_17_evdata1, tvb, 9, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_17_evdata2, tvb, 10, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_17_evdata3, tvb, 11, 1, TRUE); +} + +/* Get Device SDR Info. + */ +static void +rq20(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_20_rq_op, NULL }; + + if (tvb_length(tvb) > 0) { + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_se_20_rq_byte1, byte1, TRUE, 0); + ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0) & 0x01); + } +} + +static void +rs20(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_20_rs_population, &hf_ipmi_se_20_rs_lun3, + &hf_ipmi_se_20_rs_lun2, &hf_ipmi_se_20_rs_lun1, &hf_ipmi_se_20_rs_lun0, NULL }; + guint32 val; + + if (ipmi_getsaveddata(0, &val) && val) { + proto_tree_add_item(tree, hf_ipmi_se_20_rs_sdr, tvb, 0, 1, TRUE); + } else { + proto_tree_add_item(tree, hf_ipmi_se_20_rs_num, tvb, 0, 1, TRUE); + } + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_20_rs_byte2, + byte2, TRUE, 0); + if (tvb_get_guint8(tvb, 1) & 0x80) { + /* Dynamic sensor population */ + proto_tree_add_item(tree, hf_ipmi_se_20_rs_change, tvb, 2, 4, TRUE); + } +} + + +/* Get Device SDR. + */ +static void +rq21(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 len; + + len = tvb_get_guint8(tvb, 5); + + proto_tree_add_item(tree, hf_ipmi_se_21_rid, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_21_record, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_21_offset, tvb, 4, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_se_21_len, tvb, 5, 1, len, + "%u%s", len, len == 0xff ? "(entire record)" : ""); +} + +static void +rs21(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_21_next, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_21_recdata, tvb, 2, tvb_length(tvb) - 2, TRUE); +} + +static const value_string cc21[] = { + { 0x80, "Record changed" }, + { 0, NULL } +}; + +/* Reserve Device SDR Repository. + */ +static void +rs22(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_22_resid, tvb, 0, 2, TRUE); +} + +/* Get Sensor Reading Factors. + */ +static void +rq23(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_23_rq_sensor, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_23_rq_reading, tvb, 1, 1, TRUE); +} + +static inline gint16 +sign_extend(gint16 v, int bits) +{ + if ((v & (1 << (bits - 1))) == 0) { + return v; + } + + return v | (0xffff << bits); +} + +static void +rs23(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *ti; + proto_tree *s_tree, *st2; + guint16 tol, acc, accexp, tmp; + gint16 m, b, bexp, rexp; + + proto_tree_add_item(tree, hf_ipmi_se_23_rs_next_reading, tvb, 0, 1, TRUE); + + m = tvb_get_guint8(tvb, 1); + tmp = tvb_get_guint8(tvb, 2); + m |= (tmp & 0xc0) << 2; + tol = tmp & 0x3f; + b = tvb_get_guint8(tvb, 3); + tmp = tvb_get_guint8(tvb, 4); + b |= (tmp & 0xc0) << 2; + acc = tmp & 0x3f; + tmp = tvb_get_guint8(tvb, 5); + acc |= (tmp & 0xf0) << 4; + accexp = (tmp & 0x0c) >> 2; + tmp = tvb_get_guint8(tvb, 6); + rexp = (tmp & 0xf0) >> 4; + bexp = tmp & 0x0f; + + m = sign_extend(m, 10); + b = sign_extend(b, 10); + bexp = sign_extend(bexp, 4); + rexp = sign_extend(rexp, 4); + + ti = proto_tree_add_text(tree, tvb, 1, 6, "Factors: M=%d B=%d K1=%d K2=%d Acc=%u*10^%u Tol=%u", + m, b, bexp, rexp, acc, accexp, tol); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_23_readingfactors); + + tmp = tvb_get_guint8(tvb, 1); + ti = proto_tree_add_text(s_tree, tvb, 1, 1, "Byte 1"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte1); + proto_tree_add_text(st2, tvb, 1, 1, "%sM (LS 8bits)", ipmi_dcd8(tmp, 0xff)); + + tmp = tvb_get_guint8(tvb, 2); + ti = proto_tree_add_text(s_tree, tvb, 2, 1, "Byte 2"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte2); + proto_tree_add_text(st2, tvb, 2, 1, "%sM (MS 2bits)", ipmi_dcd8(tmp, 0xc0)); + proto_tree_add_text(st2, tvb, 2, 1, "%sTolerance", ipmi_dcd8(tmp, 0x3f)); + + tmp = tvb_get_guint8(tvb, 3); + ti = proto_tree_add_text(s_tree, tvb, 3, 1, "Byte 3"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte3); + proto_tree_add_text(st2, tvb, 3, 1, "%sB (LS 8bits)", ipmi_dcd8(tmp, 0xff)); + + tmp = tvb_get_guint8(tvb, 4); + ti = proto_tree_add_text(s_tree, tvb, 4, 1, "Byte 4"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte4); + proto_tree_add_text(st2, tvb, 4, 1, "%sB (MS 2bits)", ipmi_dcd8(tmp, 0xc0)); + proto_tree_add_text(st2, tvb, 4, 1, "%sAccuracy (LS 6bits)", ipmi_dcd8(tmp, 0x3f)); + + tmp = tvb_get_guint8(tvb, 5); + ti = proto_tree_add_text(s_tree, tvb, 5, 1, "Byte 5"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte5); + proto_tree_add_text(st2, tvb, 5, 1, "%sAccuracy (MS 4bits)", ipmi_dcd8(tmp, 0xf0)); + proto_tree_add_text(st2, tvb, 5, 1, "%sAccuracy exponent", ipmi_dcd8(tmp, 0x0c)); + + tmp = tvb_get_guint8(tvb, 6); + ti = proto_tree_add_text(s_tree, tvb, 6, 1, "Byte 6"); + st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte6); + proto_tree_add_text(st2, tvb, 6, 1, "%sR exponent", ipmi_dcd8(tmp, 0xf0)); + proto_tree_add_text(st2, tvb, 6, 1, "%sB exponent", ipmi_dcd8(tmp, 0x0f)); +} + +/* Set Sensor Hysteresis. + */ +static void +rq24(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_24_sensor, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_24_mask, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_24_hyst_pos, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_24_hyst_neg, tvb, 3, 1, TRUE); +} + +/* Get Sensor Hysteresis. + */ +static void +rq25(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_25_sensor, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_25_mask, tvb, 1, 1, TRUE); +} + +static void +rs25(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_25_hyst_pos, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_25_hyst_neg, tvb, 1, 1, TRUE); +} + +/* Common for Get/Set Thresholds */ +static void +add_thresholds(tvbuff_t *tvb, int offs, proto_tree *tree, const char *desc) +{ + static const int *threshold_mask[] = { &hf_ipmi_se_XX_m_unr, &hf_ipmi_se_XX_m_uc, &hf_ipmi_se_XX_m_unc, + &hf_ipmi_se_XX_m_lnr, &hf_ipmi_se_XX_m_lc, &hf_ipmi_se_XX_m_lnc, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, offs, 1, desc, "None", + ett_ipmi_se_XX_mask, threshold_mask, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lnc, tvb, offs + 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lc, tvb, offs + 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lnr, tvb, offs + 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_unc, tvb, offs + 4, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_uc, tvb, offs + 5, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_se_XX_thr_unr, tvb, offs + 6, 1, TRUE); +} + +/* Set Sensor Thresholds. + */ +static void +rq26(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_26_sensor, tvb, 0, 1, TRUE); + add_thresholds(tvb, 1, tree, "Set thresholds: "); +} + +/* Get Sensor Thresholds. + */ +static void +rq27(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_27_sensor, tvb, 0, 1, TRUE); +} + +static void +rs27(tvbuff_t *tvb, proto_tree *tree) +{ + add_thresholds(tvb, 0, tree, "Readable thresholds: "); +} + +/* Common for Get EE/Set EE/Rearm + */ +static void +add_events(tvbuff_t *tvb, int offs, proto_tree *tree, const struct true_false_string *tfs, + const char *desc) +{ + static const int *bsel[4][8] = { + { &hf_ipmi_se_XX_b1_0, &hf_ipmi_se_XX_b1_1, &hf_ipmi_se_XX_b1_2, &hf_ipmi_se_XX_b1_3, + &hf_ipmi_se_XX_b1_4, &hf_ipmi_se_XX_b1_5, &hf_ipmi_se_XX_b1_6, &hf_ipmi_se_XX_b1_7 }, + { &hf_ipmi_se_XX_b2_0, &hf_ipmi_se_XX_b2_1, &hf_ipmi_se_XX_b2_2, &hf_ipmi_se_XX_b2_3, + &hf_ipmi_se_XX_b2_4, &hf_ipmi_se_XX_b2_5, &hf_ipmi_se_XX_b2_6, NULL }, + { &hf_ipmi_se_XX_b3_0, &hf_ipmi_se_XX_b3_1, &hf_ipmi_se_XX_b3_2, &hf_ipmi_se_XX_b3_3, + &hf_ipmi_se_XX_b3_4, &hf_ipmi_se_XX_b3_5, &hf_ipmi_se_XX_b3_6, &hf_ipmi_se_XX_b3_7 }, + { &hf_ipmi_se_XX_b4_0, &hf_ipmi_se_XX_b4_1, &hf_ipmi_se_XX_b4_2, &hf_ipmi_se_XX_b4_3, + &hf_ipmi_se_XX_b4_4, &hf_ipmi_se_XX_b4_5, &hf_ipmi_se_XX_b4_6, NULL } + }; + static const int *tsel[] = { &ett_ipmi_se_XX_b1, &ett_ipmi_se_XX_b2, &ett_ipmi_se_XX_b3, &ett_ipmi_se_XX_b4 }; + proto_item *ti; + proto_tree *s_tree; + int len = tvb_length(tvb); + int i, j, val, msk; + + for (i = 0; offs < len; i++, offs++) { + val = tvb_get_guint8(tvb, offs); + ti = proto_tree_add_text(tree, tvb, offs, 1, "%s (byte %d)", desc, i); + s_tree = proto_item_add_subtree(ti, *tsel[i]); + for (j = 7; j >= 0; j--) { + if (!bsel[i][j]) { + continue; + } + msk = 1 << j; + proto_tree_add_boolean_format_value(s_tree, *bsel[i][j], tvb, offs, 1, + val & msk, "%s", (val & msk) ? tfs->true_string : tfs->false_string); + } + } +} + + +/* Set Sensor Event Enable. + */ +static void +rq28(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_28_fl_evm, &hf_ipmi_se_28_fl_scan, &hf_ipmi_se_28_fl_action, NULL }; + static const struct true_false_string tfs_lect = { "Select", "Do not select" }; + + proto_tree_add_item(tree, hf_ipmi_se_28_sensor, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_28_byte2, byte2, TRUE, 0); + add_events(tvb, 2, tree, &tfs_lect, "Selected events"); +} + +/* Get Sensor Event Enable. + */ +static void +rq29(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_29_sensor, tvb, 0, 1, TRUE); +} + +static void +rs29(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_29_fl_evm, &hf_ipmi_se_29_fl_scan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_29_byte1, byte1, TRUE, 0); + add_events(tvb, 1, tree, &tfs_29_enabled, "Enabled events"); +} + +/* Re-arm Sensor Events. + */ +static void +rq2a(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_se_2a_fl_sel, NULL }; + static const struct true_false_string rearm_tfs = { "Re-arm", "Do not re-arm" }; + + proto_tree_add_item(tree, hf_ipmi_se_2a_sensor, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_2a_byte2, byte2, TRUE, 0); + add_events(tvb, 2, tree, &rearm_tfs, "Re-arm Events"); +} + +/* Get Sensor Event Status. + */ +static void +rq2b(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_2b_sensor, tvb, 0, 1, TRUE); +} + +static void +rs2b(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_se_2b_fl_evm, &hf_ipmi_se_2b_fl_scan, &hf_ipmi_se_2b_fl_unavail, NULL }; + static const struct true_false_string occur_tfs = { "Occurred", "Did not occur" }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_2b_byte1, byte1, TRUE, 0); + add_events(tvb, 1, tree, &occur_tfs, "Event Status"); +} + +/* Get Sensor Reading. + */ +static void +rq2d(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_2d_sensor, tvb, 0, 1, TRUE); +} + +static void +rs2d(tvbuff_t *tvb, proto_tree *tree) +{ + /* Reuse flags from Event Status message */ + static const int *byte2[] = { &hf_ipmi_se_2b_fl_evm, &hf_ipmi_se_2b_fl_scan, &hf_ipmi_se_2b_fl_unavail, NULL }; + static const int *bsel[2][8] = { + { &hf_ipmi_se_2d_b1_0, &hf_ipmi_se_2d_b1_1, &hf_ipmi_se_2d_b1_2, &hf_ipmi_se_2d_b1_3, + &hf_ipmi_se_2d_b1_4, &hf_ipmi_se_2d_b1_5, &hf_ipmi_se_2d_b1_6, &hf_ipmi_se_2d_b1_7 }, + { &hf_ipmi_se_2d_b2_0, &hf_ipmi_se_2d_b2_1, &hf_ipmi_se_2d_b2_2, &hf_ipmi_se_2d_b2_3, + &hf_ipmi_se_2d_b2_4, &hf_ipmi_se_2d_b2_5, &hf_ipmi_se_2d_b2_6, NULL } + }; + static const int *tsel[2] = { &ett_ipmi_se_2d_b1, &ett_ipmi_se_2d_b2 }; + proto_item *ti; + proto_tree *s_tree; + int i, j, len; + + proto_tree_add_item(tree, hf_ipmi_se_2d_reading, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_2d_byte2, byte2, TRUE, 0); + len = tvb_length(tvb); + for (i = 0; i < 2 && i < len - 2; i++) { + ti = proto_tree_add_text(tree, tvb, i + 2, 1, "Threshold comparisons/assertions (byte %d)", i); + s_tree = proto_item_add_subtree(ti, *tsel[i]); + for (j = 7; j >= 0; j--) { + if (bsel[i][j]) { + proto_tree_add_item(s_tree, *bsel[i][j], tvb, i + 2, 1, TRUE); + } + } + } +} + +/* Set Sensor Type. + */ +static void +rq2e(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 stype, evtype; + const struct sensor_info *si; + const struct evtype_info *eti; + proto_item *ti; + proto_tree *s_tree; + + stype = tvb_get_guint8(tvb, 1); + si = get_sensor_info(stype); + evtype = tvb_get_guint8(tvb, 2) & 0x7f; + eti = get_evtype_info(evtype); + + proto_tree_add_item(tree, hf_ipmi_se_2e_sensor, tvb, 0, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_se_2e_stype, tvb, 1, 1, + stype, "%s (0x%02x)", si->desc, stype); + + ti = proto_tree_add_text(tree, tvb, 2, 1, "Event/reading type: %s", eti->desc); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_2e_evtype); + proto_tree_add_uint_format_value(s_tree, hf_ipmi_se_2e_evtype, tvb, 2, 1, + evtype, "%s (0x%02x)", eti->desc, evtype); +} + +/* Get Sensor Type. + */ +static void +rq2f(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_se_2f_sensor, tvb, 0, 1, TRUE); +} + +static void +rs2f(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 stype, evtype; + const struct sensor_info *si; + const struct evtype_info *eti; + proto_item *ti; + proto_tree *s_tree; + + stype = tvb_get_guint8(tvb, 0); + si = get_sensor_info(stype); + evtype = tvb_get_guint8(tvb, 1) & 0x7f; + eti = get_evtype_info(evtype); + + proto_tree_add_uint_format_value(tree, hf_ipmi_se_2f_stype, tvb, 0, 1, + stype, "%s (0x%02x)", si->desc, stype); + + ti = proto_tree_add_text(tree, tvb, 2, 1, "Event/reading type: %s", eti->desc); + s_tree = proto_item_add_subtree(ti, ett_ipmi_se_2f_evtype); + proto_tree_add_uint_format_value(s_tree, hf_ipmi_se_2f_evtype, tvb, 1, 1, + evtype, "%s (0x%02x)", eti->desc, evtype); +} + +static const value_string cc30[] = { + { 0x80, "Attempt to change not-settable reading/status bits" }, + { 0x81, "Setting Event Data Bytes not supported" }, + { 0, NULL } +}; + +static ipmi_cmd_t cmd_se[] = { + /* Event commands */ + { 0x00, rq00, NULL, NULL, NULL, "Set Event Receiver", 0 }, + { 0x01, NULL, rs01, NULL, NULL, "Get Event Receiver", 0 }, + { 0x02, rq02, NULL, NULL, NULL, "Platform Event", 0 }, + + /* PEF and Alerting Commands */ + { 0x10, NULL, rs10, NULL, NULL, "Get PEF Capabilities", 0 }, + { 0x11, rq11, rs11, NULL, NULL, "Arm PEF Postpone Timer", 0 }, + { 0x12, rq12, NULL, cc12, NULL, "Set PEF Configuration Parameters", 0 }, + { 0x13, rq13, rs13, cc13, NULL, "Get PEF Configuration Parameters", CMD_CALLRQ }, + { 0x14, rq14, NULL, cc14, NULL, "Set Last Processed Event ID", 0 }, + { 0x15, NULL, rs15, cc15, NULL, "Get Last Processed Event ID", 0 }, + { 0x16, rq16, rs16, cc16, NULL, "Alert Immediate", CMD_CALLRQ }, + { 0x17, rq17, NULL, NULL, NULL, "PET Acknowledge", 0 }, + + /* Sensor Device Commands */ + { 0x20, rq20, rs20, NULL, NULL, "Get Device SDR Info", CMD_CALLRQ }, + { 0x21, rq21, rs21, cc21, NULL, "Get Device SDR", 0 }, + { 0x22, NULL, rs22, NULL, NULL, "Reserve Device SDR Repository", 0 }, + { 0x23, rq23, rs23, NULL, NULL, "Get Sensor Reading Factors", 0 }, + { 0x24, rq24, NULL, NULL, NULL, "Set Sensor Hysteresis", 0 }, + { 0x25, rq25, rs25, NULL, NULL, "Get Sensor Hysteresis", 0 }, + { 0x26, rq26, NULL, NULL, NULL, "Set Sensor Threshold", 0 }, + { 0x27, rq27, rs27, NULL, NULL, "Get Sensor Threshold", 0 }, + { 0x28, rq28, NULL, NULL, NULL, "Set Sensor Event Enable", 0 }, + { 0x29, rq29, rs29, NULL, NULL, "Get Sensor Event Enable", 0 }, + { 0x2a, rq2a, NULL, NULL, NULL, "Re-arm Sensor Events", 0 }, + { 0x2b, rq2b, rs2b, NULL, NULL, "Get Sensor Event Status", 0 }, + { 0x2d, rq2d, rs2d, NULL, NULL, "Get Sensor Reading", 0 }, + { 0x2e, rq2e, NULL, NULL, NULL, "Set Sensor Type", 0 }, + { 0x2f, rq2f, rs2f, NULL, NULL, "Get Sensor Type", 0 }, + { 0x30, IPMI_TBD, cc30, NULL, "Set Sensor Reading and Event Status", 0 }, +}; + +void +ipmi_register_se(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_se_evt_rev, + { "Event Message Revision", + "ipmi.evt.evmrev", FT_UINT8, BASE_HEX, evt_evm_rev_vals, 0, "", HFILL }}, + { &hf_ipmi_se_evt_sensor_type, + { "Sensor Type", + "ipmi.evt.sensor_type", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_evt_sensor_num, + { "Sensor #", + "ipmi.evt.sensor_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_evt_byte3, + { "Event Dir/Type", + "ipmi.evt.byte3", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_evt_dir, + { "Event Direction", + "ipmi.evt.evdir", FT_BOOLEAN, 8, TFS(&evt_evdir_tfs), 0x80, "", HFILL }}, + { &hf_ipmi_se_evt_type, + { "Event Type", + "ipmi.evt.evtype", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_evt_data1, + { "Event Data 1", + "ipmi.evt.data1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_evt_data1_b2, + { "Byte 2", + "ipmi.evt.data1.b2", FT_UINT8, BASE_HEX, NULL, 0xc0, "", HFILL }}, + { &hf_ipmi_se_evt_data1_b3, + { "Byte 3", + "ipmi.evt.data1.b3", FT_UINT8, BASE_HEX, NULL, 0x30, "", HFILL }}, + { &hf_ipmi_se_evt_data1_offs, + { "Offset", + "ipmi.evt.data1.offs", FT_UINT8, BASE_HEX, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_se_evt_data2, + { "Event Data 2", + "ipmi.evt.data2", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_evt_data3, + { "Event Data 3", + "ipmi.evt.data3", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_cp00_sip, + { "Set In Progress", + "ipmi.cp00.sip", FT_UINT8, BASE_HEX, cp00_sip_vals, 0x03, "", HFILL }}, + { &hf_ipmi_se_cp01_alert_startup, + { "PEF Alert Startup Delay disable", + "ipmi.cp01.alert_startup", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_cp01_startup, + { "PEF Startup Delay disable", + "ipmi.cp01.startup", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_cp01_event_msg, + { "Enable Event Messages for PEF actions", + "ipmi.cp01.event_msg", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_cp01_pef, + { "Enable PEF", + "ipmi.cp01.pef", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_cp02_diag_intr, + { "Enable Diagnostic Interrupt", + "ipmi.cp02.diag_intr", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_cp02_oem_action, + { "Enable OEM action", + "ipmi.cp02.oem_action", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_cp02_pwr_cycle, + { "Enable Power Cycle action", + "ipmi.cp02.pwr_cycle", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_cp02_reset, + { "Enable Reset action", + "ipmi.cp02.reset", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_cp02_pwr_down, + { "Enable Power Down action", + "ipmi.cp02.pwr_down", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_cp02_alert, + { "Enable Alert action", + "ipmi.cp02.alert", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_cp03_startup, + { "PEF Startup delay", + "ipmi.cp03.startup", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_se_cp04_alert_startup, + { "PEF Alert Startup delay", + "ipmi.cp04.alert_startup", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_se_cp05_num_evfilters, + { "Number of Event Filters", + "ipmi.cp05.num_evfilters", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp06_filter, + { "Filter number (set selector)", + "ipmi.cp06.filter", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp06_data, + { "Filter data", + "ipmi.cp06.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp07_filter, + { "Filter number (set selector)", + "ipmi.cp07.filter", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp07_data, + { "Filter data (byte 1)", + "ipmi.cp07.data", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp08_policies, + { "Number of Alert Policy Entries", + "ipmi.cp08.policies", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp09_entry, + { "Entry number (set selector)", + "ipmi.cp09.entry", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp09_data, + { "Entry data", + "ipmi.cp09.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp10_useval, + { "Used to fill the GUID field in PET Trap", + "ipmi.cp10.useval", FT_BOOLEAN, 8, TFS(&cp10_use_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_se_cp10_guid, + { "GUID", + "ipmi.cp10.guid", FT_GUID, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp11_num_alertstr, + { "Number of Alert Strings", + "ipmi.cp11.num_alertstr", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp12_byte1, + { "Alert String Selector", + "ipmi.cp12.byte1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp12_alert_stringsel, + { "Alert String Selector (set selector)", + "ipmi.cp12.alert_stringsel", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp12_evfilter, + { "Filter Number", + "ipmi.cp12.evfilter", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp12_alert_stringset, + { "Set number for string", + "ipmi.cp12.alert_stringset", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp13_stringsel, + { "String selector (set selector)", + "ipmi.cp13.stringsel", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp13_blocksel, + { "Block selector", + "ipmi.cp13.blocksel", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp13_string, + { "String data", + "ipmi.cp13.string", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp14_num_gct, + { "Number of Group Control Table entries", + "ipmi.cp14.num_gct", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp15_gctsel, + { "Group control table entry selector (set selector)", + "ipmi.cp15.gctsel", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_cp15_force, + { "Request/Force", + "ipmi.cp15.force", FT_BOOLEAN, 8, TFS(&cp15_rq_frc_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_se_cp15_delayed, + { "Immediate/Delayed", + "ipmi.cp15.delayed", FT_BOOLEAN, 8, TFS(&cp15_imm_delay_tfs), 0x10, "", HFILL }}, + { &hf_ipmi_se_cp15_channel, + { "Channel", + "ipmi.cp15.channel", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_se_cp15_group, + { "Group ID", + "ipmi.cp15.group_id", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_cp15_member_check, + { "Member ID check disabled", + "ipmi.cp15.member_check", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_cp15_member_id, + { "Member ID", + "ipmi.cp15_member_id", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_se_cp15_retries, + { "Retries", + "ipmi.cp15.retries", FT_UINT8, BASE_DEC, NULL, 0x70, "", HFILL }}, + { &hf_ipmi_se_cp15_operation, + { "Operation", + "ipmi.cp15.operation", FT_UINT8, BASE_HEX, cp15_op_vals, 0x0f, "", HFILL }}, + + { &hf_ipmi_se_00_addr, + { "Event Receiver slave address", + "ipmi.se00.addr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_00_lun, + { "Event Receiver LUN", + "ipmi.se00.lun", FT_UINT8, BASE_HEX, NULL, 0x3, "", HFILL }}, + + { &hf_ipmi_se_01_addr, + { "Event Receiver slave address", + "ipmi.se01.addr", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_01_lun, + { "Event Receiver LUN", + "ipmi.se01.lun", FT_UINT8, BASE_HEX, NULL, 0x3, "", HFILL }}, + + { &hf_ipmi_se_10_pef_version, + { "PEF Version", + "ipmi.se10.pef_version", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + { &hf_ipmi_se_10_action_oem_filter, + { "OEM Event Record Filtering supported", + "ipmi.se10.action.oem_filter", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_10_action_diag_intr, + { "Diagnostic Interrupt", + "ipmi.se10.action.diag_intr", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_10_action_oem_action, + { "OEM Action", + "ipmi.se10.action.oem_action", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_10_action_pwr_cycle, + { "Power Cycle", + "ipmi.se10.action.pwr_cycle", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_10_action_reset, + { "Reset", + "ipmi.se10.action.reset", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_10_action_pwr_down, + { "Power Down", + "ipmi.se10.action.pwr_down", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_10_action_alert, + { "Alert", + "ipmi.se10.action.alert", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_10_entries, + { "Number of event filter table entries", + "ipmi.se10.entries", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_11_rq_timeout, + { "Timeout value", + "ipmi.se11.rq_timeout", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_11_rs_timeout, + { "Timeout value", + "ipmi.se11.rs_timeout", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_12_byte1, + { "Parameter selector", + "ipmi.se12.byte1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_12_param, + { "Parameter selector", + "ipmi.se12.param", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_12_data, + { "Parameter data", + "ipmi.se12.data", FT_NONE, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_13_byte1, + { "Parameter selector", + "ipmi.se13.byte1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_13_getrev, + { "Get Parameter Revision only", + "ipmi.se13.getrev", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_13_param, + { "Parameter selector", + "ipmi.se13.param", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_13_set, + { "Set Selector", + "ipmi.se13.set", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_13_block, + { "Block Selector", + "ipmi.se13.block", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_13_rev_present, + { "Present", + "ipmi.se13.rev.present", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_se_13_rev_compat, + { "Oldest forward-compatible", + "ipmi.se13.rev.compat", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_se_13_data, + { "Parameter data", + "ipmi.se13.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_14_processed_by, + { "Set Record ID for last record processed by", + "ipmi.se14.processed_by", FT_BOOLEAN, 8, TFS(&tfs_14_processed), 0x01, "", HFILL }}, + { &hf_ipmi_se_14_rid, + { "Record ID", + "ipmi.se14.rid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_15_tstamp, + { "Most recent addition timestamp", + "ipmi.se15.tstamp", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_15_lastrec, + { "Record ID for last record in SEL", + "ipmi.se15.lastrec", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_15_proc_sw, + { "Last SW Processed Event Record ID", + "ipmi.se15.proc_sw", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_15_proc_bmc, + { "Last BMC Processed Event Record ID", + "ipmi.se15.proc_bmc", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_16_chan, + { "Channel", + "ipmi.se16.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_se_16_op, + { "Operation", + "ipmi.se16.op", FT_UINT8, BASE_HEX, vals_16_op, 0xc0, "", HFILL }}, + { &hf_ipmi_se_16_dst, + { "Destination", + "ipmi.se16.dst", FT_UINT8, BASE_HEX, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_se_16_send_string, + { "Send Alert String", + "ipmi.se16.send_string", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_16_string_sel, + { "String selector", + "ipmi.se16.string_sel", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + { &hf_ipmi_se_16_gen, + { "Generator ID", + "ipmi.se16.gen", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_16_status, + { "Alert Immediate Status", + "ipmi.se16.status", FT_UINT8, BASE_HEX, vals_16_status, 0, "", HFILL }}, + + { &hf_ipmi_se_17_seq, + { "Sequence Number", + "ipmi.se17.seq", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_tstamp, + { "Local Timestamp", + "ipmi.se17.tstamp", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_evsrc, + { "Event Source Type", + "ipmi.se17.evsrc", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_sensor_dev, + { "Sensor Device", + "ipmi.se17.sensor_dev", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_sensor_num, + { "Sensor Number", + "ipmi.se17.sensor_num", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_evdata1, + { "Event Data 1", + "ipmi.se17.evdata1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_evdata2, + { "Event Data 2", + "ipmi.se17.evdata2", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_17_evdata3, + { "Event Data 3", + "ipmi.se17.evdata3", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_20_rq_op, + { "Operation", + "ipmi.se20.rq_op", FT_BOOLEAN, 8, TFS(&tfs_20_op), 0x01, "", HFILL }}, + { &hf_ipmi_se_20_rs_num, + { "Number of sensors in device for LUN", + "ipmi.se20.rs_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_20_rs_sdr, + { "Total Number of SDRs in the device", + "ipmi.se20.rs_sdr", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_20_rs_population, + { "Sensor population", + "ipmi.se20.rs_population", FT_BOOLEAN, 8, TFS(&tfs_20_pop), 0x80, "", HFILL }}, + { &hf_ipmi_se_20_rs_lun3, + { "LUN3 has sensors", + "ipmi.se20.rs_lun3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_20_rs_lun2, + { "LUN2 has sensors", + "ipmi.se20.rs_lun2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_20_rs_lun1, + { "LUN1 has sensors", + "ipmi.se20.rs_lun1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_20_rs_lun0, + { "LUN0 has sensors", + "ipmi.se20.rs_lun0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_20_rs_change, + { "Sensor Population Change Indicator", + "ipmi.se20.rs_change", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_21_rid, + { "Reservation ID", + "ipmi.se21.rid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_21_record, + { "Record ID", + "ipmi.se21.record", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_21_offset, + { "Offset into data", + "ipmi.se21.offset", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_21_len, + { "Bytes to read", + "ipmi.se21.len", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_21_next, + { "Next record ID", + "ipmi.se21.next", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_21_recdata, + { "Record data", + "ipmi.se21.recdata", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_22_resid, + { "Reservation ID", + "ipmi.se22.resid", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_23_rq_sensor, + { "Sensor Number", + "ipmi.se23.rq_sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_23_rq_reading, + { "Reading", + "ipmi.se23.rq_reading", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_23_rs_next_reading, + { "Next reading", + "ipmi.se23.rs_next_reading", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_24_sensor, + { "Sensor Number", + "ipmi.se24.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_24_mask, + { "Reserved for future 'hysteresis mask'", + "ipmi.se24.mask", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_24_hyst_pos, + { "Positive-going hysteresis", + "ipmi.se24.hyst_pos", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_24_hyst_neg, + { "Negative-going hysteresis", + "ipmi.se24.hyst_neg", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_25_sensor, + { "Sensor Number", + "ipmi.se25.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_25_mask, + { "Reserved for future 'hysteresis mask'", + "ipmi.se25.mask", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_25_hyst_pos, + { "Positive-going hysteresis", + "ipmi.se25.hyst_pos", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_25_hyst_neg, + { "Negative-going hysteresis", + "ipmi.se25.hyst_neg", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_26_sensor, + { "Sensor Number", + "ipmi.seXX.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_m_unr, + { "Upper Non-Recoverable", + "ipmi.seXX.mask.unr", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_XX_m_uc, + { "Upper Critical", + "ipmi.seXX.mask.uc", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_XX_m_unc, + { "Upper Non-Critical", + "ipmi.seXX.mask.unc", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_XX_m_lnr, + { "Lower Non-Recoverable", + "ipmi.seXX.mask.lnr", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_XX_m_lc, + { "Lower Critical", + "ipmi.seXX.mask.lc", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_XX_m_lnc, + { "Lower Non-Critical", + "ipmi.seXX.mask.lnc", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_XX_thr_lnc, + { "Lower Non-Critical Threshold", + "ipmi.seXX.lnc", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_thr_lc, + { "Lower Critical Threshold", + "ipmi.seXX.lc", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_thr_lnr, + { "Lower Non-Recoverable Threshold", + "ipmi.seXX.lnr", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_thr_unc, + { "Upper Non-Critical Threshold", + "ipmi.seXX.unc", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_thr_uc, + { "Upper Critical Threshold", + "ipmi.seXX.uc", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_XX_thr_unr, + { "Upper Non-Recoverable Threshold", + "ipmi.seXX.unr", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_27_sensor, + { "Sensor Number", + "ipmi.se27.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_se_XX_b1_7, + { "Assertion for UNC (going high) / state bit 7", + "ipmi.seXX.a_7", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_XX_b1_6, + { "Assertion for UNC (going low) / state bit 6", + "ipmi.seXX.a_6", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_XX_b1_5, + { "Assertion for LNR (going high) / state bit 5", + "ipmi.seXX.a_5", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_XX_b1_4, + { "Assertion for LNR (going low) / state bit 4", + "ipmi.seXX.a_4", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_XX_b1_3, + { "Assertion for LC (going high) / state bit 3", + "ipmi.seXX.a_3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_XX_b1_2, + { "Assertion for LC (going low) / state bit 2", + "ipmi.seXX.a_2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_XX_b1_1, + { "Assertion for LNC (going high) / state bit 1", + "ipmi.seXX.a_1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_XX_b1_0, + { "Assertion for LNC (going low) / state bit 0", + "ipmi.seXX.a_0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_XX_b2_6, + { "Reserved / Assertion for state bit 14", + "ipmi.seXX.a_14", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_XX_b2_5, + { "Reserved / Assertion for state bit 13", + "ipmi.seXX.a_13", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_XX_b2_4, + { "Reserved / Assertion for state bit 12", + "ipmi.seXX.a_12", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_XX_b2_3, + { "Assertion for UNR (going high) / state bit 11", + "ipmi.seXX.a_11", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_XX_b2_2, + { "Assertion for UNR (going low) / state bit 10", + "ipmi.seXX.a_10", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_XX_b2_1, + { "Assertion for UC (going high) / state bit 9", + "ipmi.seXX.a_9", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_XX_b2_0, + { "Assertion for UC (going low) / state bit 8", + "ipmi.seXX.a_8", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_XX_b3_7, + { "Deassertion for UNC (going high) / state bit 7", + "ipmi.seXX.d_7", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_XX_b3_6, + { "Deassertion for UNC (going low) / state bit 6", + "ipmi.seXX.d_6", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_XX_b3_5, + { "Deassertion for LNR (going high) / state bit 5", + "ipmi.seXX.d_5", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_XX_b3_4, + { "Deassertion for LNR (going low) / state bit 4", + "ipmi.seXX.d_4", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_XX_b3_3, + { "Deassertion for LC (going high) / state bit 3", + "ipmi.seXX.d_3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_XX_b3_2, + { "Deassertion for LC (going low) / state bit 2", + "ipmi.seXX.d_2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_XX_b3_1, + { "Deassertion for LNC (going high) / state bit 1", + "ipmi.seXX.d_1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_XX_b3_0, + { "Deassertion for LNC (going low) / state bit 0", + "ipmi.seXX.d_0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_XX_b4_6, + { "Reserved / Deassertion for state bit 14", + "ipmi.seXX.d_14", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_XX_b4_5, + { "Reserved / Deassertion for state bit 13", + "ipmi.seXX.d_13", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_XX_b4_4, + { "Reserved / Deassertion for state bit 12", + "ipmi.seXX.d_12", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_XX_b4_3, + { "Deassertion for UNR (going high) / state bit 11", + "ipmi.seXX.d_11", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_XX_b4_2, + { "Deassertion for UNR (going low) / state bit 10", + "ipmi.seXX.d_10", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_XX_b4_1, + { "Deassertion for UC (going high) / state bit 9", + "ipmi.seXX.d_9", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_XX_b4_0, + { "Deassertion for UC (going low) / state bit 8", + "ipmi.seXX.d_8", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_se_28_sensor, + { "Sensor Number", + "ipmi.se28.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_28_fl_evm, + { "Event Messages", + "ipmi.se28.fl_evm", FT_BOOLEAN, 8, TFS(&tfs_28_enable), 0x80, "", HFILL }}, + { &hf_ipmi_se_28_fl_scan, + { "Scanning", + "ipmi.se28.fl_scan", FT_BOOLEAN, 8, TFS(&tfs_28_enable), 0x40, "", HFILL }}, + { &hf_ipmi_se_28_fl_action, + { "Action", + "ipmi.se28.fl_action", FT_UINT8, BASE_HEX, vals_28_act, 0x30, "", HFILL }}, + + { &hf_ipmi_se_29_sensor, + { "Sensor Number", + "ipmi.se29.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_29_fl_evm, + { "Event Messages", + "ipmi.se29.fl_evm", FT_BOOLEAN, 8, TFS(&tfs_29_enabled), 0x80, "", HFILL }}, + { &hf_ipmi_se_29_fl_scan, + { "Scanning", + "ipmi.se29.fl_scan", FT_BOOLEAN, 8, TFS(&tfs_29_enabled), 0x40, "", HFILL }}, + + { &hf_ipmi_se_2a_sensor, + { "Sensor Number", + "ipmi.se2a.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2a_fl_sel, + { "Re-arm Events", + "ipmi.se2a.fl_sel", FT_BOOLEAN, 8, TFS(&tfs_2a_sel), 0x80, "", HFILL }}, + + { &hf_ipmi_se_2b_sensor, + { "Sensor Number", + "ipmi.se2b.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2b_fl_evm, + { "Event Messages", + "ipmi.se2b.fl_evm", FT_BOOLEAN, 8, TFS(&tfs_2b_enabled), 0x80, "", HFILL }}, + { &hf_ipmi_se_2b_fl_scan, + { "Sensor scanning", + "ipmi.se2b.fl_scan", FT_BOOLEAN, 8, TFS(&tfs_2b_enabled), 0x40, "", HFILL }}, + { &hf_ipmi_se_2b_fl_unavail, + { "Reading/status unavailable", + "ipmi.se2b.fl_unavail", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + + { &hf_ipmi_se_2d_sensor, + { "Sensor Number", + "ipmi.se2d.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2d_reading, + { "Sensor Reading", + "ipmi.se2d.reading", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2d_b1_7, + { "Reserved / State 7 asserted", + "ipmi.se2d.b1_7", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_se_2d_b1_6, + { "Reserved / State 6 asserted", + "ipmi.se2d.b1_6", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_2d_b1_5, + { "At or above UNR threshold / State 5 asserted", + "ipmi.se2d.b1_5", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_2d_b1_4, + { "At or above UC threshold / State 4 asserted", + "ipmi.se2d.b1_4", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_2d_b1_3, + { "At or above UNC threshold / State 3 asserted", + "ipmi.se2d.b1_3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_2d_b1_2, + { "At or below LNR threshold / State 2 asserted", + "ipmi.se2d.b1_2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_2d_b1_1, + { "At or below LC threshold / State 1 asserted", + "ipmi.se2d.b1_1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_2d_b1_0, + { "At or below LNC threshold / State 0 asserted", + "ipmi.se2d.b1_0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_se_2d_b2_6, + { "Reserved / State 14 asserted", + "ipmi.se2d.b1_6", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_se_2d_b2_5, + { "Reserved / State 13 asserted", + "ipmi.se2d.b1_5", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_se_2d_b2_4, + { "Reserved / State 12 asserted", + "ipmi.se2d.b1_4", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_se_2d_b2_3, + { "Reserved / State 11 asserted", + "ipmi.se2d.b1_3", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_se_2d_b2_2, + { "Reserved / State 10 asserted", + "ipmi.se2d.b1_2", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_se_2d_b2_1, + { "Reserved / State 9 asserted", + "ipmi.se2d.b1_1", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_se_2d_b2_0, + { "Reserved / State 8 asserted", + "ipmi.se2d.b1_0", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_se_2e_sensor, + { "Sensor number", + "ipmi.se2e.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2e_stype, + { "Sensor type", + "ipmi.se2e.stype", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2e_evtype, + { "Event/Reading type", + "ipmi.se2e.evtype", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + + { &hf_ipmi_se_2f_sensor, + { "Sensor number", + "ipmi.se2f.sensor", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2f_stype, + { "Sensor type", + "ipmi.se2f.stype", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_se_2f_evtype, + { "Event/Reading type", + "ipmi.se2f.evtype", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }}, + }; + static gint *ett[] = { + &ett_ipmi_se_evt_byte3, + &ett_ipmi_se_evt_evd_byte1, + &ett_ipmi_se_evt_evd_byte2, + &ett_ipmi_se_evt_evd_byte3, + &ett_ipmi_se_cp06_byte1, + &ett_ipmi_se_cp07_byte1, + &ett_ipmi_se_cp09_byte1, + &ett_ipmi_se_cp10_byte1, + &ett_ipmi_se_cp12_byte1, + &ett_ipmi_se_cp12_byte2, + &ett_ipmi_se_cp12_byte3, + &ett_ipmi_se_cp13_byte1, + &ett_ipmi_se_cp15_byte1, + &ett_ipmi_se_cp15_byte2, + &ett_ipmi_se_cp15_member, + &ett_ipmi_se_cp15_byte11, + &ett_ipmi_se_00_byte2, + &ett_ipmi_se_01_byte2, + &ett_ipmi_se_10_action, + &ett_ipmi_se_12_byte1, + &ett_ipmi_se_13_byte1, + &ett_ipmi_se_13_rev, + &ett_ipmi_se_14_byte1, + &ett_ipmi_se_16_byte1, + &ett_ipmi_se_16_byte2, + &ett_ipmi_se_16_byte3, + &ett_ipmi_se_20_rq_byte1, + &ett_ipmi_se_20_rs_byte2, + &ett_ipmi_se_23_readingfactors, + &ett_ipmi_se_23_byte1, + &ett_ipmi_se_23_byte2, + &ett_ipmi_se_23_byte3, + &ett_ipmi_se_23_byte4, + &ett_ipmi_se_23_byte5, + &ett_ipmi_se_23_byte6, + &ett_ipmi_se_XX_mask, + &ett_ipmi_se_XX_b1, + &ett_ipmi_se_XX_b2, + &ett_ipmi_se_XX_b3, + &ett_ipmi_se_XX_b4, + &ett_ipmi_se_28_byte2, + &ett_ipmi_se_29_byte1, + &ett_ipmi_se_2a_byte2, + &ett_ipmi_se_2b_byte1, + &ett_ipmi_se_2d_byte2, + &ett_ipmi_se_2d_b1, + &ett_ipmi_se_2d_b2, + &ett_ipmi_se_2e_evtype, + &ett_ipmi_se_2f_evtype, + }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_SE_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_se, array_length(cmd_se)); +} diff --git a/epan/dissectors/packet-ipmi-session.c b/epan/dissectors/packet-ipmi-session.c new file mode 100644 index 0000000000..8b961bb8d3 --- /dev/null +++ b/epan/dissectors/packet-ipmi-session.c @@ -0,0 +1,333 @@ +/* packet-ipmi-session.c + * Routines for dissection of IPMI session wrapper (v1.5 and v2.0) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * Copyright Duncan Laurie <duncan@sun.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Partially copied from packet-ipmi.c. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <epan/packet.h> + +#define RMCP_CLASS_IPMI 0x07 + +static int proto_ipmi_session = -1; + +static gint ett_ipmi_session = -1; +static gint ett_ipmi_session_payloadtype = -1; + +/* IPMI session header */ +static int hf_ipmi_session_id = -1; +static int hf_ipmi_session_authtype = -1; +static int hf_ipmi_session_payloadtype = -1; +static int hf_ipmi_session_payloadtype_auth = -1; +static int hf_ipmi_session_payloadtype_enc = -1; +static int hf_ipmi_session_oem_iana = -1; +static int hf_ipmi_session_oem_payload_id = -1; +static int hf_ipmi_session_sequence = -1; +static int hf_ipmi_session_authcode = -1; +static int hf_ipmi_session_msg_len_1b = -1; +static int hf_ipmi_session_msg_len_2b = -1; +static int hf_ipmi_session_trailer = -1; + +static dissector_handle_t ipmi_handle; +static dissector_handle_t data_handle; + +#define IPMI_AUTH_NONE 0x00 +#define IPMI_AUTH_MD2 0x01 +#define IPMI_AUTH_MD5 0x02 +#define IPMI_AUTH_PASSWORD 0x04 +#define IPMI_AUTH_OEM 0x05 +#define IPMI_AUTH_RMCPP 0x06 + +static const value_string ipmi_authtype_vals[] = { + { IPMI_AUTH_NONE, "NONE" }, + { IPMI_AUTH_MD2, "MD2" }, + { IPMI_AUTH_MD5, "MD5" }, + { IPMI_AUTH_PASSWORD, "PASSWORD" }, + { IPMI_AUTH_OEM, "OEM" }, + { IPMI_AUTH_RMCPP, "RMCP+"}, + { 0x00, NULL } +}; + +#define IPMI_IPMI_MESSAGE 0 +#define IPMI_OEM_EXPLICIT 2 + +static const value_string ipmi_payload_vals[] = { + { IPMI_IPMI_MESSAGE, "IPMI Message" }, + { 0x01, "SOL (serial over LAN)" }, + { IPMI_OEM_EXPLICIT, "OEM Explicit" }, + /* Session Setup Payload Types */ + { 0x10, "RMCP+ Open Session Request" }, + { 0x11, "RMCP+ Open Session Response" }, + { 0x12, "RAKP Message 1" }, + { 0x13, "RAKP Message 2" }, + { 0x14, "RAKP Message 3" }, + { 0x15, "RAKP Message 4" }, + /* OEM Payload Type Handles */ + { 0x20, "OEM0 (OEM Payload)" }, + { 0x21, "OEM1 (OEM Payload)" }, + { 0x22, "OEM2 (OEM Payload)" }, + { 0x23, "OEM3 (OEM Payload)" }, + { 0x24, "OEM4 (OEM Payload)" }, + { 0x25, "OEM5 (OEM Payload)" }, + { 0x26, "OEM6 (OEM Payload)" }, + { 0x27, "OEM7 (OEM Payload)" }, + { 0x00, NULL } +}; + +static const true_false_string ipmi_payload_aut_val = { + "Payload is authenticated", + "Payload is unauthenticated" +}; + +static const true_false_string ipmi_payload_enc_val = { + "Payload is encrypted", + "Payload is unencrypted" +}; + +static void +dissect_ipmi_session(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *sess_tree = NULL, *s_tree; + proto_item *ti = NULL; + tvbuff_t *next_tvb; + guint32 session_id; + guint8 authtype, payloadtype = 0; + guint32 msg_start, msg_len, offset = 0; + gboolean payloadtype_auth = 0, payloadtype_enc = 0; + + /* session authtype, 0=no authcode present, 6=RMCP+ */ + authtype = tvb_get_guint8(tvb, 0); + if (authtype == IPMI_AUTH_RMCPP) { + /* Fetch additional info before trying to interpret + the packet. It may not be IPMI at all! */ + payloadtype = tvb_get_guint8(tvb, 1); + payloadtype_auth = (payloadtype >> 6) & 1; + payloadtype_enc = (payloadtype >> 7); + payloadtype &= 0x3f; + + /* IPMI v2.0 packets have session ID BEFORE the session + sequence number; just after authentification and payload + types. The OEM Explicit payload type has 6 more bytes + (IANA + Payload ID) before the session ID. */ + if (payloadtype == IPMI_OEM_EXPLICIT) { + session_id = tvb_get_letohl(tvb, 8); + msg_start = 18; + msg_len = tvb_get_letohs(tvb, 16); + } else { + session_id = tvb_get_letohl(tvb, 2); + msg_start = 12; + msg_len = tvb_get_letohs(tvb, 10); + } + } else { + /* IPMI v1.5 packets have session ID AFTER the session + sequence number. They also have 1 byte for payload + message length. */ + session_id = tvb_get_letohl(tvb, 5); + if (authtype == IPMI_AUTH_NONE) { + msg_start = 10; + msg_len = tvb_get_guint8(tvb, 9); + } else { + msg_start = 26; + msg_len = tvb_get_guint8(tvb, 25); + } + } + + /* Later it will be overridden with sub-dissector, if any */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + if (authtype == IPMI_AUTH_RMCPP) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMCP+"); + } else { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPMI"); + } + } + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_clear(pinfo->cinfo, COL_INFO); + col_add_fstr(pinfo->cinfo, COL_INFO, "Session ID 0x%x", session_id); + if (authtype == IPMI_AUTH_RMCPP) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", payload type: %s", + val_to_str(payloadtype, ipmi_payload_vals, "Unknown")); + } + } + + if (tree) { + offset = 0; + ti = proto_tree_add_protocol_format(tree, proto_ipmi_session, + tvb, 0, tvb_length(tvb), + "IPMI v%s Session Wrapper, session ID 0x%x", + authtype == IPMI_AUTH_RMCPP ? "2.0+" : "1.5", + session_id); + sess_tree = proto_item_add_subtree(ti, ett_ipmi_session); + proto_tree_add_item(sess_tree, hf_ipmi_session_authtype, tvb, offset, 1, TRUE); + offset++; + + if (authtype == IPMI_AUTH_RMCPP) { + /* IPMI v2.0+ */ + ti = proto_tree_add_text(sess_tree, tvb, offset, 1, + "Payload type: %s (0x%02x), %sencrypted, %sauthenticated", + val_to_str(payloadtype, ipmi_payload_vals, "Unknown"), + payloadtype, + payloadtype_enc ? "" : "not ", + payloadtype_auth ? "" : "not "); + s_tree = proto_item_add_subtree(ti, ett_ipmi_session_payloadtype); + proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype_enc, tvb, offset, 1, TRUE); + proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype_auth, tvb, offset, 1, TRUE); + proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype, tvb, offset, 1, TRUE); + offset++; + + if (payloadtype == IPMI_OEM_EXPLICIT) { + proto_tree_add_item(sess_tree, hf_ipmi_session_oem_iana, tvb, offset, 4, TRUE); + offset += 4; + proto_tree_add_item(sess_tree, hf_ipmi_session_oem_payload_id, tvb, offset, 2, TRUE); + offset += 2; + } + proto_tree_add_item(sess_tree, hf_ipmi_session_id, tvb, offset, 4, TRUE); + offset += 4; + proto_tree_add_item(sess_tree, hf_ipmi_session_sequence, tvb, offset, 4, TRUE); + offset += 4; + proto_tree_add_item(sess_tree, hf_ipmi_session_msg_len_2b, tvb, offset, 2, TRUE); + offset += 2; + } else { + /* IPMI v1.5 */ + proto_tree_add_item(sess_tree, hf_ipmi_session_sequence, tvb, offset, 4, TRUE); + offset += 4; + proto_tree_add_item(sess_tree, hf_ipmi_session_id, tvb, offset, 4, TRUE); + offset += 4; + if (authtype != IPMI_AUTH_NONE) { + proto_tree_add_item(sess_tree, hf_ipmi_session_authcode, + tvb, offset, 16, TRUE); + offset += 16; + } + proto_tree_add_item(sess_tree, hf_ipmi_session_msg_len_1b, tvb, offset, 1, TRUE); + offset++; + } + } + + /* If we can parse the embedded message, do so */ + next_tvb = tvb_new_subset(tvb, msg_start, msg_len, -1); + if (payloadtype_enc) { + /* This is RMCP+, and payload is encrypted. In this case, + there is a 'confidentiality header/trailer', whose lengths + are unknown to us. These lengths are negotiated during + session open process and are retained over a session. + Since we are stateless (and more, we may have no session + open packet in the capture we parse), we cannot even + decipher where a message starts. Just print them as data. + */ + call_dissector(data_handle, next_tvb, pinfo, tree); + } else if (authtype != IPMI_AUTH_RMCPP || payloadtype == IPMI_IPMI_MESSAGE) { + /* This is an IPMI message, either v1.5 or v2.0+. For now, + we don't need to distinguish these kinds. */ + call_dissector(ipmi_handle, next_tvb, pinfo, tree); + } else { + /* All other RMCP+ payload types fall here: session open/close + requests, RAKP messages, SOL. We cannot parse them yet, thus + just output as data. */ + call_dissector(data_handle, next_tvb, pinfo, tree); + } + + if (tree) { + /* Account for the message we just parsed. */ + offset += msg_len; + + /* Show the rest of the session wrapper as binary data */ + if (offset < tvb_length(tvb)) { + proto_tree_add_item(sess_tree, hf_ipmi_session_trailer, + tvb, offset, tvb_length(tvb) - offset, TRUE); + } + } +} + +void +proto_register_ipmi_session(void) +{ + static hf_register_info hf[] = { + { &hf_ipmi_session_authtype, { + "Authentication Type", "ipmi.session.authtype", + FT_UINT8, BASE_HEX, VALS(ipmi_authtype_vals), 0, "", HFILL }}, + { &hf_ipmi_session_payloadtype,{ + "Payload Type", "ipmi.session.payloadtype", + FT_UINT8, BASE_HEX, VALS(ipmi_payload_vals), 0x3f, "", HFILL }}, + { &hf_ipmi_session_payloadtype_auth,{ + "Authenticated","ipmi.session.payloadtype.auth", + FT_BOOLEAN,8, TFS(&ipmi_payload_aut_val), 0x40, "", HFILL }}, + { &hf_ipmi_session_payloadtype_enc,{ + "Encryption","ipmi.session.payloadtype.enc", + FT_BOOLEAN,8, TFS(&ipmi_payload_enc_val), 0x80, "", HFILL }}, + { &hf_ipmi_session_oem_iana, { + "OEM IANA", "ipmi.session.oem.iana", + FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_oem_payload_id, { + "OEM Payload ID", "ipmi.session.oem.payloadid", + FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_sequence, { + "Session Sequence Number", "ipmi.session.sequence", + FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_id, { + "Session ID", "ipmi.session.id", + FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_authcode, { + "Authentication Code", "ipmi.session.authcode", + FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_msg_len_1b, { + "Message Length", "ipmi.msg.len", + FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_msg_len_2b, { + "Message Length", "ipmi.msg.len", + FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_session_trailer, { + "IPMI Session Wrapper (trailer)", "ipmi.sess.trailer", + FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + }; + + static gint *ett[] = { &ett_ipmi_session, &ett_ipmi_session_payloadtype }; + + proto_ipmi_session = proto_register_protocol( + "Intelligent Platform Management Interface (Session Wrapper)", "IPMI Session", + "ipmi-session"); + proto_register_field_array(proto_ipmi_session, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_ipmi_session(void) +{ + static gboolean inited = FALSE; + + if (!inited) { + dissector_handle_t ipmi_session_handle; + + ipmi_session_handle = create_dissector_handle(dissect_ipmi_session, proto_ipmi_session); + dissector_add("rmcp.class", RMCP_CLASS_IPMI, ipmi_session_handle); + + data_handle = find_dissector("data"); + ipmi_handle = find_dissector("ipmi"); + inited = TRUE; + } +} diff --git a/epan/dissectors/packet-ipmi-storage.c b/epan/dissectors/packet-ipmi-storage.c new file mode 100644 index 0000000000..a79a3fae3b --- /dev/null +++ b/epan/dissectors/packet-ipmi-storage.c @@ -0,0 +1,1117 @@ +/* packet-ipmi-storage.c + * Sub-dissectors for IPMI messages (netFn=Storage) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static gint ett_ipmi_stor_10_flags = -1; +static gint ett_ipmi_stor_20_ops = -1; +static gint ett_ipmi_stor_25_byte6 = -1; +static gint ett_ipmi_stor_27_status = -1; +static gint ett_ipmi_stor_2c_rq_byte1 = -1; +static gint ett_ipmi_stor_2c_rs_byte1 = -1; +static gint ett_ipmi_stor_40_ops = -1; +static gint ett_ipmi_stor_45_byte6 = -1; +static gint ett_ipmi_stor_47_status = -1; +static gint ett_ipmi_stor_5a_byte1 = -1; +static gint ett_ipmi_stor_5b_byte1 = -1; + +static gint hf_ipmi_stor_10_fruid = -1; +static gint hf_ipmi_stor_10_size = -1; +static gint hf_ipmi_stor_10_access = -1; + +static gint hf_ipmi_stor_11_fruid = -1; +static gint hf_ipmi_stor_11_offset = -1; +static gint hf_ipmi_stor_11_count = -1; +static gint hf_ipmi_stor_11_ret_count = -1; +static gint hf_ipmi_stor_11_data = -1; + +static gint hf_ipmi_stor_12_fruid = -1; +static gint hf_ipmi_stor_12_offset = -1; +static gint hf_ipmi_stor_12_data = -1; +static gint hf_ipmi_stor_12_ret_count = -1; + +static gint hf_ipmi_stor_20_sdr_version = -1; +static gint hf_ipmi_stor_20_rec_count = -1; +static gint hf_ipmi_stor_20_free_space = -1; +static gint hf_ipmi_stor_20_ts_add = -1; +static gint hf_ipmi_stor_20_ts_erase = -1; +static gint hf_ipmi_stor_20_op_overflow = -1; +static gint hf_ipmi_stor_20_op_update = -1; +static gint hf_ipmi_stor_20_op_delete = -1; +static gint hf_ipmi_stor_20_op_partial_add = -1; +static gint hf_ipmi_stor_20_op_reserve = -1; +static gint hf_ipmi_stor_20_op_allocinfo = -1; + +static gint hf_ipmi_stor_21_units = -1; +static gint hf_ipmi_stor_21_size = -1; +static gint hf_ipmi_stor_21_free = -1; +static gint hf_ipmi_stor_21_largest = -1; +static gint hf_ipmi_stor_21_maxrec = -1; + +static gint hf_ipmi_stor_22_rsrv_id = -1; + +static gint hf_ipmi_stor_23_rsrv_id = -1; +static gint hf_ipmi_stor_23_rec_id = -1; +static gint hf_ipmi_stor_23_offset = -1; +static gint hf_ipmi_stor_23_count = -1; +static gint hf_ipmi_stor_23_next = -1; +static gint hf_ipmi_stor_23_data = -1; + +static gint hf_ipmi_stor_24_data = -1; +static gint hf_ipmi_stor_24_added_rec_id = -1; + +static gint hf_ipmi_stor_25_rsrv_id = -1; +static gint hf_ipmi_stor_25_rec_id = -1; +static gint hf_ipmi_stor_25_offset = -1; +static gint hf_ipmi_stor_25_inprogress = -1; +static gint hf_ipmi_stor_25_data = -1; +static gint hf_ipmi_stor_25_added_rec_id = -1; + +static gint hf_ipmi_stor_26_rsrv_id = -1; +static gint hf_ipmi_stor_26_rec_id = -1; +static gint hf_ipmi_stor_26_del_rec_id = -1; + +static gint hf_ipmi_stor_27_rsrv_id = -1; +static gint hf_ipmi_stor_27_clr = -1; +static gint hf_ipmi_stor_27_action = -1; +static gint hf_ipmi_stor_27_status = -1; + +static gint hf_ipmi_stor_28_time = -1; + +static gint hf_ipmi_stor_29_time = -1; + +static gint hf_ipmi_stor_2c_init_agent = -1; +static gint hf_ipmi_stor_2c_init_state = -1; + +static gint hf_ipmi_stor_40_sel_version = -1; +static gint hf_ipmi_stor_40_entries = -1; +static gint hf_ipmi_stor_40_free_space = -1; +static gint hf_ipmi_stor_40_ts_add = -1; +static gint hf_ipmi_stor_40_ts_erase = -1; +static gint hf_ipmi_stor_40_op_overflow = -1; +static gint hf_ipmi_stor_40_op_delete = -1; +static gint hf_ipmi_stor_40_op_partial_add = -1; +static gint hf_ipmi_stor_40_op_reserve = -1; +static gint hf_ipmi_stor_40_op_allocinfo = -1; + +static gint hf_ipmi_stor_41_units = -1; +static gint hf_ipmi_stor_41_size = -1; +static gint hf_ipmi_stor_41_free = -1; +static gint hf_ipmi_stor_41_largest = -1; +static gint hf_ipmi_stor_41_maxrec = -1; + +static gint hf_ipmi_stor_42_rsrv_id = -1; + +static gint hf_ipmi_stor_43_rsrv_id = -1; +static gint hf_ipmi_stor_43_rec_id = -1; +static gint hf_ipmi_stor_43_offset = -1; +static gint hf_ipmi_stor_43_count = -1; +static gint hf_ipmi_stor_43_next = -1; +static gint hf_ipmi_stor_43_data = -1; + +static gint hf_ipmi_stor_44_data = -1; +static gint hf_ipmi_stor_44_added_rec_id = -1; + +static gint hf_ipmi_stor_45_rsrv_id = -1; +static gint hf_ipmi_stor_45_rec_id = -1; +static gint hf_ipmi_stor_45_offset = -1; +static gint hf_ipmi_stor_45_inprogress = -1; +static gint hf_ipmi_stor_45_data = -1; +static gint hf_ipmi_stor_45_added_rec_id = -1; + +static gint hf_ipmi_stor_46_rsrv_id = -1; +static gint hf_ipmi_stor_46_rec_id = -1; +static gint hf_ipmi_stor_46_del_rec_id = -1; + +static gint hf_ipmi_stor_47_rsrv_id = -1; +static gint hf_ipmi_stor_47_clr = -1; +static gint hf_ipmi_stor_47_action = -1; +static gint hf_ipmi_stor_47_status = -1; + +static gint hf_ipmi_stor_48_time = -1; + +static gint hf_ipmi_stor_49_time = -1; + +static gint hf_ipmi_stor_5a_log_type = -1; +static gint hf_ipmi_stor_5a_ts_add = -1; +static gint hf_ipmi_stor_5a_num_entries = -1; +static gint hf_ipmi_stor_5a_iana = -1; +static gint hf_ipmi_stor_5a_bytes = -1; +static gint hf_ipmi_stor_5a_unknown = -1; + +static gint hf_ipmi_stor_5b_log_type = -1; +static gint hf_ipmi_stor_5b_ts_add = -1; +static gint hf_ipmi_stor_5b_num_entries = -1; +static gint hf_ipmi_stor_5b_iana = -1; +static gint hf_ipmi_stor_5b_bytes = -1; +static gint hf_ipmi_stor_5b_unknown = -1; + +static const struct true_false_string tfs_10_access = { + "by words", "by bytes" +}; + +static const value_string vals_20_update[] = { + { 0x00, "Unspecified" }, + { 0x01, "Supported non-modal" }, + { 0x02, "Supported modal" }, + { 0x03, "Supported both modal and non-modal" }, + { 0, NULL } +}; + +static const value_string vals_25_inprogress[] = { + { 0x00, "Partial add in progress" }, + { 0x01, "Last record data being transferred" }, + { 0, NULL } +}; + +static const value_string vals_27_action[] = { + { 0x00, "Get Erasure Status" }, + { 0xaa, "Initiate Erase" }, + { 0, NULL } +}; + +static const value_string vals_27_status[] = { + { 0x00, "Erasure in progress" }, + { 0x01, "Erase completed" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_2c_init_agent = { + "Run", "Get status" +}; + +static const struct true_false_string tfs_2c_init_state = { + "Completed", "In progress" +}; + +static const value_string vals_45_inprogress[] = { + { 0x00, "Partial add in progress" }, + { 0x01, "Last record data being transferred" }, + { 0, NULL } +}; + +static const value_string vals_47_action[] = { + { 0x00, "Get Erasure Status" }, + { 0xaa, "Initiate Erase" }, + { 0, NULL } +}; + +static const value_string vals_47_status[] = { + { 0x00, "Erasure in progress" }, + { 0x01, "Erase completed" }, + { 0, NULL } +}; + +static const value_string log_type_vals[] = { + { 0x00, "MCA Log" }, + { 0x01, "OEM 1" }, + { 0x02, "OEM 2" }, + { 0, NULL } +}; + +/* Get FRU Inventory Area Info + */ +static void +rq10(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_10_fruid, tvb, 0, 1, TRUE); +} + +static void +rs10(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *flags[] = { &hf_ipmi_stor_10_access, NULL }; + + proto_tree_add_item(tree, hf_ipmi_stor_10_size, tvb, 0, 2, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_stor_10_flags, flags, TRUE, 0); +} + +/* Read FRU Data + */ +static void +rq11(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_11_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_11_offset, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_11_count, tvb, 3, 1, TRUE); +} + +static void +rs11(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_11_ret_count, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_11_data, tvb, 1, tvb_length(tvb) - 1, TRUE); +} + +static const value_string cc11[] = { + { 0x81, "FRU Device Busy" }, + { 0, NULL } +}; + +/* Write FRU Data + */ +static void +rq12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_12_fruid, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_12_offset, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_12_data, tvb, 1, tvb_length(tvb) - 1, TRUE); +} + +static void +rs12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_12_ret_count, tvb, 0, 1, TRUE); +} + +static const value_string cc12[] = { + { 0x80, "Write-protected offset" }, + { 0x81, "FRU Device Busy" }, + { 0, NULL } +}; + +/* Get SDR Repository Info + */ +static void +rs20(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *ops[] = { &hf_ipmi_stor_20_op_overflow, &hf_ipmi_stor_20_op_update, + &hf_ipmi_stor_20_op_delete, &hf_ipmi_stor_20_op_partial_add, &hf_ipmi_stor_20_op_reserve, + &hf_ipmi_stor_20_op_allocinfo, NULL }; + guint8 v; + + v = tvb_get_guint8(tvb, 0); + proto_tree_add_item(tree, hf_ipmi_stor_20_sdr_version, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_20_rec_count, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_20_free_space, tvb, 3, 2, TRUE); + ipmi_add_timestamp(tree, hf_ipmi_stor_20_ts_add, tvb, 5); + ipmi_add_timestamp(tree, hf_ipmi_stor_20_ts_erase, tvb, 9); + proto_tree_add_bitmask_text(tree, tvb, 13, 1, "Operation Support: ", NULL, + ett_ipmi_stor_20_ops, ops, TRUE, 0); +} + +/* Get SDR Repository Allocation Info + */ +static void +rs21(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_21_units, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_21_size, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_21_free, tvb, 4, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_21_largest, tvb, 6, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_21_maxrec, tvb, 8, 1, TRUE); +} + +/* Reserve SDR Repository + */ +static void +rs22(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_22_rsrv_id, tvb, 0, 2, TRUE); +} + +/* Get SDR + */ +static void +rq23(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 v = tvb_get_guint8(tvb, 5); + + proto_tree_add_item(tree, hf_ipmi_stor_23_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_23_rec_id, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_23_offset, tvb, 4, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_stor_23_count, tvb, 5, 1, + v, "%d%s", v, v == 0xff ? " (entire record)" : ""); +} + +static void +rs23(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_23_next, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_23_data, tvb, 2, tvb_length(tvb) - 2, TRUE); +} + +/* Add SDR + */ +static void +rq24(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_24_data, tvb, 0, tvb_length(tvb), TRUE); +} + +static void +rs24(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_24_added_rec_id, tvb, 0, 2, TRUE); +} + +/* Partial Add SDR + */ +static void +rq25(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte6[] = { &hf_ipmi_stor_25_inprogress, NULL }; + + proto_tree_add_item(tree, hf_ipmi_stor_25_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_25_rec_id, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_25_offset, tvb, 4, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 5, 1, NULL, NULL, + ett_ipmi_stor_25_byte6, byte6, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_stor_25_data, tvb, 6, tvb_length(tvb) - 6, TRUE); +} + +static void +rs25(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_25_added_rec_id, tvb, 0, 2, TRUE); +} + +static const value_string cc25[] = { + { 0x80, "Record rejected due to length mismatch" }, + { 0, NULL } +}; + +/* Delete SDR + */ +static void +rq26(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_25_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_25_rec_id, tvb, 2, 2, TRUE); +} + +static void +rs26(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_26_del_rec_id, tvb, 0, 2, TRUE); +} + +/* Clear SDR Repository + */ +static void +rq27(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_27_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_27_clr, tvb, 2, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_27_action, tvb, 5, 1, TRUE); +} + +static void +rs27(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *status[] = { &hf_ipmi_stor_27_status, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_27_status, status, TRUE, 0); +} + +/* Get SDR Repository Time + */ +static void +rs28(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_timestamp(tree, hf_ipmi_stor_28_time, tvb, 0); +} + +/* Set SDR Repository Time + */ +static void +rq29(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_timestamp(tree, hf_ipmi_stor_29_time, tvb, 0); +} + +/* Run Initialization Agent + */ +static void +rq2c(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_stor_2c_init_agent, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_2c_rq_byte1, byte1, TRUE, 0); +} + +static void +rs2c(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_stor_2c_init_state, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_2c_rs_byte1, byte1, TRUE, 0); +} + +/* Get SEL Info + */ +static void +rs40(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *ops[] = { &hf_ipmi_stor_40_op_overflow, &hf_ipmi_stor_40_op_delete, + &hf_ipmi_stor_40_op_partial_add, &hf_ipmi_stor_40_op_reserve, &hf_ipmi_stor_40_op_allocinfo, NULL }; + guint8 v; + + v = tvb_get_guint8(tvb, 0); + proto_tree_add_item(tree, hf_ipmi_stor_40_sel_version, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_40_entries, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_40_free_space, tvb, 3, 2, TRUE); + ipmi_add_timestamp(tree, hf_ipmi_stor_40_ts_add, tvb, 5); + ipmi_add_timestamp(tree, hf_ipmi_stor_40_ts_erase, tvb, 9); + proto_tree_add_bitmask_text(tree, tvb, 13, 1, "Operation Support: ", NULL, + ett_ipmi_stor_40_ops, ops, TRUE, 0); +} + +static const value_string cc40[] = { + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Get SEL Allocation Info + */ +static void +rs41(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_41_units, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_41_size, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_41_free, tvb, 4, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_41_largest, tvb, 6, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_41_maxrec, tvb, 8, 1, TRUE); +} + +/* Reserve SEL + */ +static void +rs42(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_42_rsrv_id, tvb, 0, 2, TRUE); +} + +static const value_string cc42[] = { + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Get SEL Entry + */ +static void +rq43(tvbuff_t *tvb, proto_tree *tree) +{ + guint8 v = tvb_get_guint8(tvb, 5); + + proto_tree_add_item(tree, hf_ipmi_stor_43_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_43_rec_id, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_43_offset, tvb, 4, 1, TRUE); + proto_tree_add_uint_format_value(tree, hf_ipmi_stor_43_count, tvb, 5, 1, + v, "%d%s", v, v == 0xff ? " (entire record)" : ""); +} + +static void +rs43(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_43_next, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_43_data, tvb, 2, tvb_length(tvb) - 2, TRUE); +} + +static const value_string cc43[] = { + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Add SEL Entry + */ + +static void +rq44(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_44_data, tvb, 0, tvb_length(tvb), TRUE); +} + +static void +rs44(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_44_added_rec_id, tvb, 0, 2, TRUE); +} + +static const value_string cc44[] = { + { 0x80, "Operation not supported for this Record Type" }, + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Partial Add SEL Entry + */ +static void +rq45(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte6[] = { &hf_ipmi_stor_45_inprogress, NULL }; + + proto_tree_add_item(tree, hf_ipmi_stor_45_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_45_rec_id, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_45_offset, tvb, 4, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 5, 1, NULL, NULL, + ett_ipmi_stor_45_byte6, byte6, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_stor_45_data, tvb, 6, tvb_length(tvb) - 6, TRUE); +} + +static void +rs45(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_45_added_rec_id, tvb, 0, 2, TRUE); +} + +static const value_string cc45[] = { + { 0x80, "Record rejected due to length mismatch" }, + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Delete SEL Entry + */ +static void +rq46(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_45_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_45_rec_id, tvb, 2, 2, TRUE); +} + +static void +rs46(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_46_del_rec_id, tvb, 0, 2, TRUE); +} + +static const value_string cc46[] = { + { 0x80, "Operation not supported for this Record Type" }, + { 0x81, "Cannot execute command, SEL erase in progress" }, + { 0, NULL } +}; + +/* Clear SEL + */ +static void +rq47(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_stor_47_rsrv_id, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_47_clr, tvb, 2, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_47_action, tvb, 5, 1, TRUE); +} + +static void +rs47(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *status[] = { &hf_ipmi_stor_47_status, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_47_status, status, TRUE, 0); +} + +/* Get SEL Time + */ +static void +rs48(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_timestamp(tree, hf_ipmi_stor_48_time, tvb, 0); +} + +/* Set SEL Time + */ +static void +rq49(tvbuff_t *tvb, proto_tree *tree) +{ + ipmi_add_timestamp(tree, hf_ipmi_stor_49_time, tvb, 0); +} + +/* Get Auxiliary Log Status + */ +static void +rq5a(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_stor_5a_log_type, NULL }; + + if (!tree) { + ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0) & 0x0f); + return; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_5a_byte1, byte1, TRUE, 0); +} + +static void +rs5a(tvbuff_t *tvb, proto_tree *tree) +{ + guint32 v; + + if (!ipmi_getsaveddata(0, &v) || v > 2) { + proto_tree_add_item(tree, hf_ipmi_stor_5a_unknown, tvb, 0, tvb_length(tvb), TRUE); + return; + } + + ipmi_add_timestamp(tree, hf_ipmi_stor_5a_ts_add, tvb, 0); + if (v == 0) { + proto_tree_add_item(tree, hf_ipmi_stor_5a_num_entries, tvb, 4, 4, TRUE); + } else if (v == 1 || v == 2) { + proto_tree_add_item(tree, hf_ipmi_stor_5a_iana, tvb, 4, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_5a_bytes, tvb, 7, 7, TRUE); + } +} + +/* Set Auxiliary Log Status + */ +static void +rq5b(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_stor_5b_log_type, NULL }; + guint8 v = tvb_get_guint8(tvb, 0); + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_stor_5b_byte1, byte1, TRUE, 0); + + if (v > 2) { + proto_tree_add_item(tree, hf_ipmi_stor_5b_unknown, tvb, 1, tvb_length(tvb) - 1, TRUE); + return; + } + + ipmi_add_timestamp(tree, hf_ipmi_stor_5b_ts_add, tvb, 1); + if (v == 0) { + proto_tree_add_item(tree, hf_ipmi_stor_5b_num_entries, tvb, 5, 4, TRUE); + } else if (v == 1 || v == 2) { + proto_tree_add_item(tree, hf_ipmi_stor_5b_iana, tvb, 5, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_stor_5b_bytes, tvb, 8, 8, TRUE); + } +} + +static ipmi_cmd_t cmd_storage[] = { + /* FRU Device Commands */ + { 0x10, rq10, rs10, NULL, NULL, "Get FRU Inventory Area Info", 0 }, + { 0x11, rq11, rs11, cc11, NULL, "Read FRU Data", 0 }, + { 0x12, rq12, rs12, cc12, NULL, "Write FRU Data", 0 }, + + /* SDR Device Commands */ + { 0x20, NULL, rs20, NULL, NULL, "Get SDR Repository Info", 0 }, + { 0x21, NULL, rs21, NULL, NULL, "Get SDR Repository Allocation Info", 0 }, + { 0x22, NULL, rs22, NULL, NULL, "Reserve SDR Repository", 0 }, + { 0x23, rq23, rs23, NULL, NULL, "Get SDR", 0 }, + { 0x24, rq24, rs24, NULL, NULL, "Add SDR", 0 }, + { 0x25, rq25, rs25, cc25, NULL, "Partial Add SDR", 0 }, + { 0x26, rq26, rs26, NULL, NULL, "Delete SDR", 0 }, + { 0x27, rq27, rs27, NULL, NULL, "Clear SDR Repository", 0 }, + { 0x28, NULL, rs28, NULL, NULL, "Get SDR Repository Time", 0 }, + { 0x29, rq29, NULL, NULL, NULL, "Set SDR Repository Time", 0 }, + { 0x2a, NULL, NULL, NULL, NULL, "Enter SDR Repository Update Mode", 0 }, + { 0x2b, NULL, NULL, NULL, NULL, "Exit SDR Repository Update Mode", 0 }, + { 0x2c, rq2c, rs2c, NULL, NULL, "Run Initialization Agent", 0 }, + + /* SEL Device Commands */ + { 0x40, NULL, rs40, cc40, NULL, "Get SEL Info", 0 }, + { 0x41, NULL, rs41, NULL, NULL, "Get SEL Allocation Info", 0 }, + { 0x42, NULL, rs42, cc42, NULL, "Reserve SEL", 0 }, + { 0x43, rq43, rs43, cc43, NULL, "Get SEL Entry", 0 }, + { 0x44, rq44, rs44, cc44, NULL, "Add SEL Entry", 0 }, + { 0x45, rq45, rs45, cc45, NULL, "Partial Add SEL Entry", 0 }, + { 0x46, rq46, rs46, cc46, NULL, "Delete SEL Entry", 0 }, + { 0x47, rq47, rs47, NULL, NULL, "Clear SEL", 0 }, + { 0x48, NULL, rs48, NULL, NULL, "Get SEL Time", 0 }, + { 0x49, rq49, NULL, NULL, NULL, "Set SEL Time", 0 }, + { 0x5a, rq5a, rs5a, NULL, NULL, "Get Auxiliary Log Status", CMD_CALLRQ }, + { 0x5b, rq5b, NULL, NULL, NULL, "Set Auxiliary Log Status", 0 }, + { 0x5c, IPMI_TBD, NULL, NULL, "Get SEL Time UTC Offset", 0 }, + { 0x5d, IPMI_TBD, NULL, NULL, "Set SEL Time UTC Offset", 0 }, +}; + +void +ipmi_register_storage(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_stor_10_fruid, + { "FRU ID", + "ipmi.st10.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_10_size, + { "FRU Inventory area size", + "ipmi.st10.size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_10_access, + { "Device is accessed", + "ipmi.st10.access", FT_BOOLEAN, 8, TFS(&tfs_10_access), 0x01, "", HFILL }}, + + { &hf_ipmi_stor_11_fruid, + { "FRU ID", + "ipmi.st11.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_11_offset, + { "Offset to read", + "ipmi.st11.offset", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_11_count, + { "Count to read", + "ipmi.st11.count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_11_ret_count, + { "Returned count", + "ipmi.st11.ret_count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_11_data, + { "Requested data", + "ipmi.st11.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_12_fruid, + { "FRU ID", + "ipmi.st12.fruid", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_12_offset, + { "Offset to read", + "ipmi.st12.offset", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_12_data, + { "Requested data", + "ipmi.st12.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_12_ret_count, + { "Returned count", + "ipmi.st12.ret_count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_20_sdr_version, + { "SDR Version", + "ipmi.st20.sdr_version", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + { &hf_ipmi_stor_20_rec_count, + { "Record Count", + "ipmi.st20.rec_count", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_20_free_space, + { "Free Space", + "ipmi.st20.free_space", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_20_ts_add, + { "Most recent addition timestamp", + "ipmi.st20.ts_add", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_20_ts_erase, + { "Most recent erase timestamp", + "ipmi.st20.ts_erase", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_20_op_overflow, + { "Overflow", + "ipmi.st20.op_overflow", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_stor_20_op_update, + { "SDR Repository Update", + "ipmi.st20.op_update", FT_UINT8, BASE_HEX, vals_20_update, 0x60, "", HFILL }}, + { &hf_ipmi_stor_20_op_delete, + { "Delete SDR", + "ipmi.st20.op_delete", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_stor_20_op_partial_add, + { "Partial Add SDR", + "ipmi.st20.op_partial_add", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_stor_20_op_reserve, + { "Reserve SDR Repository", + "ipmi.st20.op_reserve", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_stor_20_op_allocinfo, + { "Get SDR Repository Allocation Info", + "ipmi.st20.op_allocinfo", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_stor_21_units, + { "Number of allocation units", + "ipmi.st21.units", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_21_size, + { "Allocation unit size", + "ipmi.st21.size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_21_free, + { "Number of free units", + "ipmi.st21.free", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_21_largest, + { "Largest free block (in units)", + "ipmi.st21.largest", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_21_maxrec, + { "Maximum record size (in units)", + "ipmi.st21.maxrec", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_22_rsrv_id, + { "Reservation ID", + "ipmi.st22.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_23_rsrv_id, + { "Reservation ID", + "ipmi.st23.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_23_rec_id, + { "Record ID", + "ipmi.st23.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_23_offset, + { "Offset into record", + "ipmi.st23.offset", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_23_count, + { "Bytes to read", + "ipmi.st23.count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_23_next, + { "Next Record ID", + "ipmi.st23.next", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_23_data, + { "Record Data", + "ipmi.st23.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_24_data, + { "SDR Data", + "ipmi.st24.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_24_added_rec_id, + { "Record ID for added record", + "ipmi.st23.added_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_25_rsrv_id, + { "Reservation ID", + "ipmi.st25.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_25_rec_id, + { "Record ID", + "ipmi.st25.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_25_offset, + { "Offset into record", + "ipmi.st25.offset", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_25_inprogress, + { "In progress", + "ipmi.st25.inprogress", FT_UINT8, BASE_HEX, vals_25_inprogress, 0x0f, "", HFILL }}, + { &hf_ipmi_stor_25_data, + { "SDR Data", + "ipmi.st25.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_25_added_rec_id, + { "Record ID for added record", + "ipmi.st25.added_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_26_rsrv_id, + { "Reservation ID", + "ipmi.st26.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_26_rec_id, + { "Record ID", + "ipmi.st26.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_26_del_rec_id, + { "Deleted Record ID", + "ipmi.st26.del_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_27_rsrv_id, + { "Reservation ID", + "ipmi.st27.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_27_clr, + { "Confirmation (should be CLR)", + "ipmi.st27.clr", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_27_action, + { "Action", + "ipmi.st27.action", FT_UINT8, BASE_HEX, vals_27_action, 0, "", HFILL }}, + { &hf_ipmi_stor_27_status, + { "Erasure Status", + "ipmi.st27.status", FT_UINT8, BASE_HEX, vals_27_status, 0x0f, "", HFILL }}, + + { &hf_ipmi_stor_28_time, + { "Time", + "ipmi.st28.time", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_29_time, + { "Time", + "ipmi.st29.time", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_2c_init_agent, + { "Initialization agent", + "ipmi.st2c.init_agent", FT_BOOLEAN, 8, TFS(&tfs_2c_init_agent), 0x01, "", HFILL }}, + { &hf_ipmi_stor_2c_init_state, + { "Initialization", + "ipmi.st2c.init_state", FT_BOOLEAN, 8, TFS(&tfs_2c_init_state), 0x01, "", HFILL }}, + + { &hf_ipmi_stor_40_sel_version, + { "SEL Version", + "ipmi.st40.sel_version", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + { &hf_ipmi_stor_40_entries, + { "Entries", + "ipmi.st40.rec_count", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_40_free_space, + { "Free Space", + "ipmi.st40.free_space", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_40_ts_add, + { "Most recent addition timestamp", + "ipmi.st40.ts_add", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_40_ts_erase, + { "Most recent erase timestamp", + "ipmi.st40.ts_erase", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_40_op_overflow, + { "Overflow", + "ipmi.st40.op_overflow", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_stor_40_op_delete, + { "Delete SEL", + "ipmi.st40.op_delete", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_stor_40_op_partial_add, + { "Partial Add SEL Entry", + "ipmi.st40.op_partial_add", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_stor_40_op_reserve, + { "Reserve SEL", + "ipmi.st40.op_reserve", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_stor_40_op_allocinfo, + { "Get SEL Allocation Info", + "ipmi.st40.op_allocinfo", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_stor_41_units, + { "Number of allocation units", + "ipmi.st41.units", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_41_size, + { "Allocation unit size", + "ipmi.st41.size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_41_free, + { "Number of free units", + "ipmi.st41.free", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_41_largest, + { "Largest free block (in units)", + "ipmi.st41.largest", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_41_maxrec, + { "Maximum record size (in units)", + "ipmi.st41.maxrec", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_42_rsrv_id, + { "Reservation ID", + "ipmi.st42.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_43_rsrv_id, + { "Reservation ID", + "ipmi.st43.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_43_rec_id, + { "Record ID", + "ipmi.st43.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_43_offset, + { "Offset into record", + "ipmi.st43.offset", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_43_count, + { "Bytes to read", + "ipmi.st43.count", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_43_next, + { "Next Record ID", + "ipmi.st43.next", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_43_data, + { "Record Data", + "ipmi.st43.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_44_data, + { "SDR Data", + "ipmi.st44.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_44_added_rec_id, + { "Record ID for added record", + "ipmi.st43.added_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_45_rsrv_id, + { "Reservation ID", + "ipmi.st45.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_45_rec_id, + { "Record ID", + "ipmi.st45.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_45_offset, + { "Offset into record", + "ipmi.st45.offset", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_45_inprogress, + { "In progress", + "ipmi.st45.inprogress", FT_UINT8, BASE_HEX, vals_45_inprogress, 0x0f, "", HFILL }}, + { &hf_ipmi_stor_45_data, + { "Record Data", + "ipmi.st45.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_45_added_rec_id, + { "Record ID for added record", + "ipmi.st45.added_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_46_rsrv_id, + { "Reservation ID", + "ipmi.st46.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_46_rec_id, + { "Record ID", + "ipmi.st46.rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_46_del_rec_id, + { "Deleted Record ID", + "ipmi.st46.del_rec_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_47_rsrv_id, + { "Reservation ID", + "ipmi.st47.rsrv_id", FT_UINT16, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_47_clr, + { "Confirmation (should be CLR)", + "ipmi.st47.clr", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_47_action, + { "Action", + "ipmi.st47.action", FT_UINT8, BASE_HEX, vals_47_action, 0, "", HFILL }}, + { &hf_ipmi_stor_47_status, + { "Erasure Status", + "ipmi.st47.status", FT_UINT8, BASE_HEX, vals_47_status, 0x0f, "", HFILL }}, + + { &hf_ipmi_stor_48_time, + { "Time", + "ipmi.st48.time", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_49_time, + { "Time", + "ipmi.st49.time", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_5a_log_type, + { "Log type", + "ipmi.st5a.log_type", FT_UINT8, BASE_HEX, log_type_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_stor_5a_ts_add, + { "Last addition timestamp", + "ipmi.st5a.ts_add", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5a_num_entries, + { "Number of entries in MCA Log", + "ipmi.st5a.num_entries", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5a_iana, + { "OEM IANA", + "ipmi.st5a.iana", FT_UINT24, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5a_bytes, + { "Log status bytes", + "ipmi.st5a.bytes", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5a_unknown, + { "Unknown log format (cannot parse data)", + "ipmi.st5a.unknown", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_stor_5b_log_type, + { "Log type", + "ipmi.st5b.log_type", FT_UINT8, BASE_HEX, log_type_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_stor_5b_ts_add, + { "Last addition timestamp", + "ipmi.st5b.ts_add", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5b_num_entries, + { "Number of entries in MCA Log", + "ipmi.st5b.num_entries", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5b_iana, + { "OEM IANA", + "ipmi.st5b.iana", FT_UINT24, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5b_bytes, + { "Log status bytes", + "ipmi.st5b.bytes", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_stor_5b_unknown, + { "Unknown log format (cannot parse data)", + "ipmi.st5b.unknown", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + }; + static gint *ett[] = { + &ett_ipmi_stor_10_flags, + &ett_ipmi_stor_20_ops, + &ett_ipmi_stor_25_byte6, + &ett_ipmi_stor_27_status, + &ett_ipmi_stor_2c_rq_byte1, + &ett_ipmi_stor_2c_rs_byte1, + &ett_ipmi_stor_40_ops, + &ett_ipmi_stor_45_byte6, + &ett_ipmi_stor_47_status, + &ett_ipmi_stor_5a_byte1, + &ett_ipmi_stor_5b_byte1, + }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_STORAGE_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_storage, array_length(cmd_storage)); +} diff --git a/epan/dissectors/packet-ipmi-transport.c b/epan/dissectors/packet-ipmi-transport.c new file mode 100644 index 0000000000..a2694b5b00 --- /dev/null +++ b/epan/dissectors/packet-ipmi-transport.c @@ -0,0 +1,3197 @@ +/* packet-ipmi-transport.c + * Sub-dissectors for IPMI messages (netFn=Transport) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static gint ett_ipmi_trn_lan00_byte1 = -1; +static gint ett_ipmi_trn_lan01_byte1 = -1; +static gint ett_ipmi_trn_lan02_byte1 = -1; +static gint ett_ipmi_trn_lan02_byte2 = -1; +static gint ett_ipmi_trn_lan02_byte3 = -1; +static gint ett_ipmi_trn_lan02_byte4 = -1; +static gint ett_ipmi_trn_lan02_byte5 = -1; +static gint ett_ipmi_trn_lan04_byte1 = -1; +static gint ett_ipmi_trn_lan07_byte2 = -1; +static gint ett_ipmi_trn_lan07_byte3 = -1; +static gint ett_ipmi_trn_lan10_byte1 = -1; +static gint ett_ipmi_trn_lan17_byte1 = -1; +static gint ett_ipmi_trn_lan18_byte1 = -1; +static gint ett_ipmi_trn_lan18_byte2 = -1; +static gint ett_ipmi_trn_lan18_byte4 = -1; +static gint ett_ipmi_trn_lan19_byte1 = -1; +static gint ett_ipmi_trn_lan19_byte2 = -1; +static gint ett_ipmi_trn_lan19_byte3 = -1; +static gint ett_ipmi_trn_lan20_byte12 = -1; +static gint ett_ipmi_trn_lan21_byte1 = -1; +static gint ett_ipmi_trn_lan22_byte1 = -1; +static gint ett_ipmi_trn_lan24_byte1 = -1; +static gint ett_ipmi_trn_lan24_byte2 = -1; +static gint ett_ipmi_trn_lan24_byte3 = -1; +static gint ett_ipmi_trn_lan24_byte4 = -1; +static gint ett_ipmi_trn_lan24_byte5 = -1; +static gint ett_ipmi_trn_lan24_byte6 = -1; +static gint ett_ipmi_trn_lan24_byte7 = -1; +static gint ett_ipmi_trn_lan24_byte8 = -1; +static gint ett_ipmi_trn_lan25_byte1 = -1; +static gint ett_ipmi_trn_lan25_byte2 = -1; +static gint ett_ipmi_trn_lan25_byte34 = -1; +static gint ett_ipmi_trn_serial03_byte1 = -1; +static gint ett_ipmi_trn_serial04_byte1 = -1; +static gint ett_ipmi_trn_serial05_byte1 = -1; +static gint ett_ipmi_trn_serial05_byte2 = -1; +static gint ett_ipmi_trn_serial06_byte1 = -1; +static gint ett_ipmi_trn_serial07_byte1 = -1; +static gint ett_ipmi_trn_serial07_byte2 = -1; +static gint ett_ipmi_trn_serial08_byte1 = -1; +static gint ett_ipmi_trn_serial08_byte2 = -1; +static gint ett_ipmi_trn_serial09_byte1 = -1; +static gint ett_ipmi_trn_serial09_byte2 = -1; +static gint ett_ipmi_trn_serial16_byte1 = -1; +static gint ett_ipmi_trn_serial17_byte1 = -1; +static gint ett_ipmi_trn_serial17_byte2 = -1; +static gint ett_ipmi_trn_serial17_byte4 = -1; +static gint ett_ipmi_trn_serial17_byte5 = -1; +static gint ett_ipmi_trn_serial19_byte1 = -1; +static gint ett_ipmi_trn_serial19_byte2 = -1; +static gint ett_ipmi_trn_serial19_byte3 = -1; +static gint ett_ipmi_trn_serial20_byte1 = -1; +static gint ett_ipmi_trn_serial21_byte1 = -1; +static gint ett_ipmi_trn_serial22_byte1 = -1; +static gint ett_ipmi_trn_serial23_byte1 = -1; +static gint ett_ipmi_trn_serial24_byte1 = -1; +static gint ett_ipmi_trn_serial25_byte2 = -1; +static gint ett_ipmi_trn_serial28_byte1 = -1; +static gint ett_ipmi_trn_serial28_byte2 = -1; +static gint ett_ipmi_trn_serial28_byte10 = -1; +static gint ett_ipmi_trn_serial28_byte11 = -1; +static gint ett_ipmi_trn_serial28_byte12 = -1; +static gint ett_ipmi_trn_serial28_byte13 = -1; +static gint ett_ipmi_trn_serial28_byte14 = -1; +static gint ett_ipmi_trn_serial29_byte1 = -1; +static gint ett_ipmi_trn_serial29_byte2 = -1; +static gint ett_ipmi_trn_serial30_byte1 = -1; +static gint ett_ipmi_trn_serial30_byte2 = -1; +static gint ett_ipmi_trn_serial30_byte3 = -1; +static gint ett_ipmi_trn_serial33_byte1 = -1; +static gint ett_ipmi_trn_serial37_byte1 = -1; +static gint ett_ipmi_trn_serial43_byte1 = -1; +static gint ett_ipmi_trn_serial50_byte1 = -1; +static gint ett_ipmi_trn_serial51_byte2 = -1; +static gint ett_ipmi_trn_serial51_byte3 = -1; +static gint ett_ipmi_trn_01_byte1 = -1; +static gint ett_ipmi_trn_02_byte1 = -1; +static gint ett_ipmi_trn_02_rev = -1; +static gint ett_ipmi_trn_03_rq_byte1 = -1; +static gint ett_ipmi_trn_03_rq_byte2 = -1; +static gint ett_ipmi_trn_03_rs_byte1 = -1; +static gint ett_ipmi_trn_04_byte1 = -1; +static gint ett_ipmi_trn_04_byte2 = -1; +static gint ett_ipmi_trn_10_byte1 = -1; +static gint ett_ipmi_trn_11_byte1 = -1; +static gint ett_ipmi_trn_11_rev = -1; +static gint ett_ipmi_trn_12_rq_byte1 = -1; +static gint ett_ipmi_trn_12_rq_byte2 = -1; +static gint ett_ipmi_trn_12_rs_byte1 = -1; +static gint ett_ipmi_trn_13_byte1 = -1; +static gint ett_ipmi_trn_14_byte1 = -1; +static gint ett_ipmi_trn_15_byte1 = -1; +static gint ett_ipmi_trn_16_byte1 = -1; +static gint ett_ipmi_trn_17_byte1 = -1; +static gint ett_ipmi_trn_17_byte2 = -1; +static gint ett_ipmi_trn_18_byte1 = -1; +static gint ett_ipmi_trn_19_byte1 = -1; +static gint ett_ipmi_trn_19_byte2 = -1; +static gint ett_ipmi_trn_XX_usercap = -1; +static gint ett_ipmi_trn_XX_cbcp = -1; +static gint ett_ipmi_trn_1a_byte1 = -1; +static gint ett_ipmi_trn_1a_byte2 = -1; +static gint ett_ipmi_trn_1b_byte1 = -1; +static gint ett_ipmi_trn_1b_byte2 = -1; + +static gint hf_ipmi_trn_lan00_sip = -1; + +static gint hf_ipmi_trn_lanXX_oem = -1; +static gint hf_ipmi_trn_lanXX_passwd = -1; +static gint hf_ipmi_trn_lanXX_md5 = -1; +static gint hf_ipmi_trn_lanXX_md2 = -1; +static gint hf_ipmi_trn_lanXX_none = -1; + +static gint hf_ipmi_trn_lan03_ip = -1; + +static gint hf_ipmi_trn_lan04_ipsrc = -1; + +static gint hf_ipmi_trn_lan05_ether = -1; + +static gint hf_ipmi_trn_lan06_subnet = -1; + +static gint hf_ipmi_trn_lan07_ttl = -1; +static gint hf_ipmi_trn_lan07_flags = -1; +static gint hf_ipmi_trn_lan07_precedence = -1; +static gint hf_ipmi_trn_lan07_tos = -1; + +static gint hf_ipmi_trn_lan08_rmcp_port = -1; + +static gint hf_ipmi_trn_lan09_rmcp_port = -1; + +static gint hf_ipmi_trn_lan10_responses = -1; +static gint hf_ipmi_trn_lan10_gratuitous = -1; + +static gint hf_ipmi_trn_lan11_arp_interval = -1; + +static gint hf_ipmi_trn_lan12_def_gw_ip = -1; + +static gint hf_ipmi_trn_lan13_def_gw_mac = -1; + +static gint hf_ipmi_trn_lan14_bkp_gw_ip = -1; + +static gint hf_ipmi_trn_lan15_bkp_gw_mac = -1; + +static gint hf_ipmi_trn_lan16_comm_string = -1; + +static gint hf_ipmi_trn_lan17_num_dst = -1; + +static gint hf_ipmi_trn_lan18_dst_selector = -1; +static gint hf_ipmi_trn_lan18_ack = -1; +static gint hf_ipmi_trn_lan18_dst_type = -1; +static gint hf_ipmi_trn_lan18_tout = -1; +static gint hf_ipmi_trn_lan18_retries = -1; + +static gint hf_ipmi_trn_lan19_dst_selector = -1; +static gint hf_ipmi_trn_lan19_addr_format = -1; +static gint hf_ipmi_trn_lan19_address = -1; +static gint hf_ipmi_trn_lan19_gw_sel = -1; +static gint hf_ipmi_trn_lan19_ip = -1; +static gint hf_ipmi_trn_lan19_mac = -1; + +static gint hf_ipmi_trn_lan20_vlan_id_enable = -1; +static gint hf_ipmi_trn_lan20_vlan_id = -1; + +static gint hf_ipmi_trn_lan21_vlan_prio = -1; + +static gint hf_ipmi_trn_lan22_num_cs_entries = -1; + +static gint hf_ipmi_trn_lan23_cs_entry = -1; + +static gint hf_ipmi_trn_lan24_priv = -1; + +static gint hf_ipmi_trn_lan25_dst_selector = -1; +static gint hf_ipmi_trn_lan25_addr_format = -1; +static gint hf_ipmi_trn_lan25_address = -1; +static gint hf_ipmi_trn_lan25_uprio = -1; +static gint hf_ipmi_trn_lan25_cfi = -1; +static gint hf_ipmi_trn_lan25_vlan_id = -1; + +static gint hf_ipmi_trn_serial03_connmode = -1; +static gint hf_ipmi_trn_serial03_terminal = -1; +static gint hf_ipmi_trn_serial03_ppp = -1; +static gint hf_ipmi_trn_serial03_basic = -1; + +static gint hf_ipmi_trn_serial04_timeout = -1; + +static gint hf_ipmi_trn_serial05_cbcp_callback = -1; +static gint hf_ipmi_trn_serial05_ipmi_callback = -1; +static gint hf_ipmi_trn_serial05_cb_list = -1; +static gint hf_ipmi_trn_serial05_cb_user = -1; +static gint hf_ipmi_trn_serial05_cb_prespec = -1; +static gint hf_ipmi_trn_serial05_no_cb = -1; +static gint hf_ipmi_trn_serial05_cb_dest1 = -1; +static gint hf_ipmi_trn_serial05_cb_dest2 = -1; +static gint hf_ipmi_trn_serial05_cb_dest3 = -1; + +static gint hf_ipmi_trn_serial06_inactivity = -1; +static gint hf_ipmi_trn_serial06_dcd = -1; + +static gint hf_ipmi_trn_serial07_flowctl = -1; +static gint hf_ipmi_trn_serial07_dtrhangup = -1; +static gint hf_ipmi_trn_serial07_bitrate = -1; + +static gint hf_ipmi_trn_serial08_esc_powerup = -1; +static gint hf_ipmi_trn_serial08_esc_reset = -1; +static gint hf_ipmi_trn_serial08_switch_authcap = -1; +static gint hf_ipmi_trn_serial08_switch_rmcp = -1; +static gint hf_ipmi_trn_serial08_esc_switch1 = -1; +static gint hf_ipmi_trn_serial08_esc_switch2 = -1; +static gint hf_ipmi_trn_serial08_switch_dcdloss = -1; +static gint hf_ipmi_trn_serial08_sharing = -1; +static gint hf_ipmi_trn_serial08_ping_callback = -1; +static gint hf_ipmi_trn_serial08_ping_direct = -1; +static gint hf_ipmi_trn_serial08_ping_retry = -1; + +static gint hf_ipmi_trn_serial09_ring_duration = -1; +static gint hf_ipmi_trn_serial09_ring_dead = -1; + +static gint hf_ipmi_trn_serial10_set_sel = -1; +static gint hf_ipmi_trn_serial10_init_str = -1; +static gint hf_ipmi_trn_serial11_esc_seq = -1; +static gint hf_ipmi_trn_serial12_hangup_seq = -1; +static gint hf_ipmi_trn_serial13_dial_cmd = -1; +static gint hf_ipmi_trn_serial14_page_blackout = -1; +static gint hf_ipmi_trn_serial15_comm_string = -1; + +static gint hf_ipmi_trn_serial16_ndest = -1; + +static gint hf_ipmi_trn_serial17_dest_sel = -1; +static gint hf_ipmi_trn_serial17_ack = -1; +static gint hf_ipmi_trn_serial17_dest_type = -1; +static gint hf_ipmi_trn_serial17_ack_timeout = -1; +static gint hf_ipmi_trn_serial17_alert_retries = -1; +static gint hf_ipmi_trn_serial17_call_retries = -1; +static gint hf_ipmi_trn_serial17_alert_ack_timeout = -1; +static gint hf_ipmi_trn_serial17_dialstr_sel = -1; +static gint hf_ipmi_trn_serial17_tap_sel = -1; +static gint hf_ipmi_trn_serial17_ipaddr_sel = -1; +static gint hf_ipmi_trn_serial17_ppp_sel = -1; +static gint hf_ipmi_trn_serial17_unknown = -1; + +static gint hf_ipmi_trn_serial18_call_retry = -1; + +static gint hf_ipmi_trn_serial19_destsel = -1; +static gint hf_ipmi_trn_serial19_flowctl = -1; +static gint hf_ipmi_trn_serial19_dtrhangup = -1; +static gint hf_ipmi_trn_serial19_stopbits = -1; +static gint hf_ipmi_trn_serial19_charsize = -1; +static gint hf_ipmi_trn_serial19_parity = -1; +static gint hf_ipmi_trn_serial19_bitrate = -1; + +static gint hf_ipmi_trn_serial20_num_dial_strings = -1; +static gint hf_ipmi_trn_serial21_dialsel = -1; +static gint hf_ipmi_trn_serial21_blockno = -1; +static gint hf_ipmi_trn_serial21_dialstr = -1; +static gint hf_ipmi_trn_serial22_num_ipaddrs = -1; +static gint hf_ipmi_trn_serial23_destsel = -1; +static gint hf_ipmi_trn_serial23_ipaddr = -1; +static gint hf_ipmi_trn_serial24_num_tap_accounts = -1; +static gint hf_ipmi_trn_serial25_tap_acct = -1; +static gint hf_ipmi_trn_serial25_dialstr_sel = -1; +static gint hf_ipmi_trn_serial25_tapsrv_sel = -1; +static gint hf_ipmi_trn_serial26_tap_acct = -1; +static gint hf_ipmi_trn_serial26_tap_passwd = -1; +static gint hf_ipmi_trn_serial27_tap_acct = -1; +static gint hf_ipmi_trn_serial27_tap_pager_id = -1; + +static gint hf_ipmi_trn_serial28_tapsrv_sel = -1; +static gint hf_ipmi_trn_serial28_confirm = -1; +static gint hf_ipmi_trn_serial28_srvtype = -1; +static gint hf_ipmi_trn_serial28_ctrl_esc = -1; +static gint hf_ipmi_trn_serial28_t2 = -1; +static gint hf_ipmi_trn_serial28_t1 = -1; +static gint hf_ipmi_trn_serial28_t4 = -1; +static gint hf_ipmi_trn_serial28_t3 = -1; +static gint hf_ipmi_trn_serial28_t6 = -1; +static gint hf_ipmi_trn_serial28_t5 = -1; +static gint hf_ipmi_trn_serial28_n2 = -1; +static gint hf_ipmi_trn_serial28_n1 = -1; +static gint hf_ipmi_trn_serial28_n4 = -1; +static gint hf_ipmi_trn_serial28_n3 = -1; + +static gint hf_ipmi_trn_serial29_op = -1; +static gint hf_ipmi_trn_serial29_lineedit = -1; +static gint hf_ipmi_trn_serial29_deletectl = -1; +static gint hf_ipmi_trn_serial29_echo = -1; +static gint hf_ipmi_trn_serial29_handshake = -1; +static gint hf_ipmi_trn_serial29_o_newline = -1; +static gint hf_ipmi_trn_serial29_i_newline = -1; +static gint hf_ipmi_trn_serial30_snooping = -1; +static gint hf_ipmi_trn_serial30_snoopctl = -1; +static gint hf_ipmi_trn_serial30_negot_ctl = -1; +static gint hf_ipmi_trn_serial30_use_xmit_accm = -1; +static gint hf_ipmi_trn_serial30_xmit_addr_comp = -1; +static gint hf_ipmi_trn_serial30_xmit_proto_comp = -1; +static gint hf_ipmi_trn_serial30_ipaddr = -1; +static gint hf_ipmi_trn_serial30_accm = -1; +static gint hf_ipmi_trn_serial30_addr_comp = -1; +static gint hf_ipmi_trn_serial30_proto_comp = -1; +static gint hf_ipmi_trn_serial31_port = -1; +static gint hf_ipmi_trn_serial32_port = -1; +static gint hf_ipmi_trn_serial33_auth_proto = -1; +static gint hf_ipmi_trn_serial34_chap_name = -1; + +static gint hf_ipmi_trn_serial35_recv_accm = -1; +static gint hf_ipmi_trn_serial35_xmit_accm = -1; +static gint hf_ipmi_trn_serial36_snoop_accm = -1; +static gint hf_ipmi_trn_serial37_num_ppp = -1; +static gint hf_ipmi_trn_serial38_acct_sel = -1; +static gint hf_ipmi_trn_serial38_dialstr_sel = -1; +static gint hf_ipmi_trn_serial39_acct_sel = -1; +static gint hf_ipmi_trn_serial39_ipaddr = -1; +static gint hf_ipmi_trn_serial40_acct_sel = -1; +static gint hf_ipmi_trn_serial40_username = -1; +static gint hf_ipmi_trn_serial41_acct_sel = -1; +static gint hf_ipmi_trn_serial41_userdomain = -1; +static gint hf_ipmi_trn_serial42_acct_sel = -1; +static gint hf_ipmi_trn_serial42_userpass = -1; +static gint hf_ipmi_trn_serial43_acct_sel = -1; +static gint hf_ipmi_trn_serial43_auth_proto = -1; +static gint hf_ipmi_trn_serial44_acct_sel = -1; +static gint hf_ipmi_trn_serial44_hold_time = -1; + +static gint hf_ipmi_trn_serial45_src_ipaddr = -1; +static gint hf_ipmi_trn_serial45_dst_ipaddr = -1; +static gint hf_ipmi_trn_serial46_tx_bufsize = -1; +static gint hf_ipmi_trn_serial47_rx_bufsize = -1; +static gint hf_ipmi_trn_serial48_ipaddr = -1; +static gint hf_ipmi_trn_serial49_blockno = -1; +static gint hf_ipmi_trn_serial49_dialstr = -1; +static gint hf_ipmi_trn_serial50_115200 = -1; +static gint hf_ipmi_trn_serial50_57600 = -1; +static gint hf_ipmi_trn_serial50_38400 = -1; +static gint hf_ipmi_trn_serial50_19200 = -1; +static gint hf_ipmi_trn_serial50_9600 = -1; + +static gint hf_ipmi_trn_serial51_port_assoc_sel = -1; +static gint hf_ipmi_trn_serial51_ipmi_channel = -1; +static gint hf_ipmi_trn_serial51_conn_num = -1; +static gint hf_ipmi_trn_serial51_ipmi_sharing = -1; +static gint hf_ipmi_trn_serial51_ipmi_sol = -1; +static gint hf_ipmi_trn_serial51_chan_num = -1; +static gint hf_ipmi_trn_serial52_port_assoc_sel = -1; +static gint hf_ipmi_trn_serial52_conn_name = -1; +static gint hf_ipmi_trn_serial53_port_assoc_sel = -1; +static gint hf_ipmi_trn_serial53_chan_name = -1; + +static gint hf_ipmi_trn_01_chan = -1; +static gint hf_ipmi_trn_01_param = -1; +static gint hf_ipmi_trn_01_param_data = -1; + +static gint hf_ipmi_trn_02_getrev = -1; +static gint hf_ipmi_trn_02_chan = -1; +static gint hf_ipmi_trn_02_param = -1; +static gint hf_ipmi_trn_02_set = -1; +static gint hf_ipmi_trn_02_block = -1; +static gint hf_ipmi_trn_02_rev_present = -1; +static gint hf_ipmi_trn_02_rev_compat = -1; +static gint hf_ipmi_trn_02_param_data = -1; + +static gint hf_ipmi_trn_03_chan = -1; +static gint hf_ipmi_trn_03_arp_resp = -1; +static gint hf_ipmi_trn_03_gratuitous_arp = -1; +static gint hf_ipmi_trn_03_status_arp_resp = -1; +static gint hf_ipmi_trn_03_status_gratuitous_arp = -1; + +static gint hf_ipmi_trn_04_chan = -1; +static gint hf_ipmi_trn_04_clear = -1; +static gint hf_ipmi_trn_04_rx_ippkts = -1; +static gint hf_ipmi_trn_04_rx_iphdr_err = -1; +static gint hf_ipmi_trn_04_rx_ipaddr_err = -1; +static gint hf_ipmi_trn_04_rx_ippkts_frag = -1; +static gint hf_ipmi_trn_04_tx_ippkts = -1; +static gint hf_ipmi_trn_04_rx_udppkts = -1; +static gint hf_ipmi_trn_04_rx_validrmcp = -1; +static gint hf_ipmi_trn_04_rx_udpproxy = -1; +static gint hf_ipmi_trn_04_dr_udpproxy = -1; + +static gint hf_ipmi_trn_10_chan = -1; +static gint hf_ipmi_trn_10_param = -1; +static gint hf_ipmi_trn_10_param_data = -1; + +static gint hf_ipmi_trn_11_getrev = -1; +static gint hf_ipmi_trn_11_chan = -1; +static gint hf_ipmi_trn_11_param = -1; +static gint hf_ipmi_trn_11_set = -1; +static gint hf_ipmi_trn_11_block = -1; +static gint hf_ipmi_trn_11_rev_present = -1; +static gint hf_ipmi_trn_11_rev_compat = -1; +static gint hf_ipmi_trn_11_param_data = -1; + +static gint hf_ipmi_trn_12_chan = -1; +static gint hf_ipmi_trn_12_mux_setting = -1; +static gint hf_ipmi_trn_12_sw_to_sys = -1; +static gint hf_ipmi_trn_12_sw_to_bmc = -1; +static gint hf_ipmi_trn_12_alert = -1; +static gint hf_ipmi_trn_12_msg = -1; +static gint hf_ipmi_trn_12_req = -1; +static gint hf_ipmi_trn_12_mux_state = -1; + +static gint hf_ipmi_trn_13_chan = -1; +static gint hf_ipmi_trn_13_code1 = -1; +static gint hf_ipmi_trn_13_code2 = -1; +static gint hf_ipmi_trn_13_code3 = -1; +static gint hf_ipmi_trn_13_code4 = -1; +static gint hf_ipmi_trn_13_code5 = -1; + +static gint hf_ipmi_trn_14_chan = -1; +static gint hf_ipmi_trn_14_block = -1; +static gint hf_ipmi_trn_14_data = -1; + +static gint hf_ipmi_trn_15_chan = -1; +static gint hf_ipmi_trn_15_block = -1; +static gint hf_ipmi_trn_15_data = -1; + +static gint hf_ipmi_trn_16_chan = -1; +static gint hf_ipmi_trn_16_src_port = -1; +static gint hf_ipmi_trn_16_dst_port = -1; +static gint hf_ipmi_trn_16_src_addr = -1; +static gint hf_ipmi_trn_16_dst_addr = -1; +static gint hf_ipmi_trn_16_bytes = -1; + +static gint hf_ipmi_trn_17_chan = -1; +static gint hf_ipmi_trn_17_clear = -1; +static gint hf_ipmi_trn_17_block_num = -1; +static gint hf_ipmi_trn_17_size = -1; +static gint hf_ipmi_trn_17_data = -1; + +static gint hf_ipmi_trn_18_state = -1; +static gint hf_ipmi_trn_18_ipmi_ver = -1; + +static gint hf_ipmi_trn_19_chan = -1; +static gint hf_ipmi_trn_19_dest_sel = -1; + +static gint hf_ipmi_trn_XX_cap_cbcp = -1; +static gint hf_ipmi_trn_XX_cap_ipmi = -1; +static gint hf_ipmi_trn_XX_cbcp_from_list = -1; +static gint hf_ipmi_trn_XX_cbcp_user = -1; +static gint hf_ipmi_trn_XX_cbcp_prespec = -1; +static gint hf_ipmi_trn_XX_cbcp_nocb = -1; +static gint hf_ipmi_trn_XX_dst1 = -1; +static gint hf_ipmi_trn_XX_dst2 = -1; +static gint hf_ipmi_trn_XX_dst3 = -1; + +static gint hf_ipmi_trn_1a_user = -1; +static gint hf_ipmi_trn_1a_chan = -1; + +static gint hf_ipmi_trn_1b_user = -1; +static gint hf_ipmi_trn_1b_chan = -1; + +static const struct true_false_string enabled_tfs = { + "Enabled", "Disabled" +}; + +static const value_string lan00_sip_vals[] = { + { 0x00, "Set complete" }, + { 0x01, "Set in progress" }, + { 0x02, "Commit write" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const value_string lan04_ipsrc_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "Static address (manually configured)" }, + { 0x02, "Address obtained by BMC running DHCP" }, + { 0x03, "Address loaded by BIOS or system software" }, + { 0x04, "Address obtained by BMC running other address assignment protocol" }, + { 0, NULL } +}; + +static const struct true_false_string lan18_ack_tfs = { + "Acknowledged", "Unacknowledged" +}; + +static const value_string lan18_dst_type_vals[] = { + { 0x00, "PET Trap destination" }, + { 0x06, "OEM 1" }, + { 0x07, "OEM 2" }, + { 0, NULL } +}; + +static const value_string lan19_af_vals[] = { + { 0x00, "IPv4 Address followed by Ethernet/802.3 MAC Address" }, + { 0, NULL } +}; + +static const struct true_false_string lan19_gw_sel_tfs = { + "Use backup gateway", "Use default gateway" +}; + +static const struct true_false_string lan20_enable_tfs = { + "Enabled", "Disabled" +}; + +static const value_string lan24_priv_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "Callback" }, + { 0x02, "User" }, + { 0x03, "Operator" }, + { 0x04, "Administrator" }, + { 0x05, "OEM" }, + { 0, NULL } +}; + +static const value_string lan25_af_vals[] = { + { 0x00, "VLAN ID not used" }, + { 0x01, "802.1q VLAN TAG" }, + { 0, NULL } +}; + +static const value_string serialXX_flowctl_vals[] = { + { 0x00, "No flow control" }, + { 0x01, "RTS/CTS flow control" }, + { 0x02, "XON/XOFF flow control" }, + { 0x03, "Reserved" }, + { 0, NULL } +}; + +static const value_string serialXX_bitrate_vals[] = { + { 0x06, "9600 bps" }, + { 0x07, "19.2 kbps" }, + { 0x08, "38.4 kbps" }, + { 0x09, "57.6 kbps" }, + { 0x0A, "115.2 kbps" }, + { 0, NULL } +}; + +static const struct true_false_string serial03_connmode_tfs = { + "Direct Connect", "Modem Connect" +}; + +static const value_string serial17_dest_type_vals[] = { + { 0x00, "Dial Page" }, + { 0x01, "TAP Page" }, + { 0x02, "PPP Alert" }, + { 0x03, "Basic Mode Callback" }, + { 0x04, "PPP Mode Callback" }, + { 0x0e, "OEM 1" }, + { 0x0f, "OEM 2" }, + { 0, NULL } +}; + +static const struct true_false_string serial19_stopbits_tfs = { + "2 stop bits", "1 stop bit" +}; + +static const struct true_false_string serial19_charsize_tfs = { + "7-bit", "8-bit" +}; + +static const value_string serial19_parity_vals[] = { + { 0x00, "No" }, + { 0x01, "Odd" }, + { 0x02, "Even" }, + { 0, NULL } +}; + +static const value_string serial28_confirm_vals[] = { + { 0x00, "ACK received after end-of-transaction only" }, + { 0x01, "Code 211 and ACK received after ETX" }, + { 0x02, "Code 211 or 213, and ACK received after ETX" }, + { 0, NULL } +}; + +static const value_string serial29_op_vals[] = { + { 0x00, "Set volatile settings" }, + { 0x01, "Set non-volatile settings" }, + { 0x02, "Restore default" }, + { 0, NULL } +}; + +static const value_string serial29_delete_vals[] = { + { 0x00, "<del>" }, + { 0x01, "<bksp><sp><bksp>" }, + { 0, NULL } +}; + +static const value_string serial29_o_nl_vals[] = { + { 0x00, "None" }, + { 0x01, "<CR><LF>" }, + { 0x02, "<NUL>" }, + { 0x03, "<CR>" }, + { 0x04, "<LF><CR>" }, + { 0x05, "<LF>" }, + { 0, NULL } +}; + +static const value_string serial29_i_nl_vals[] = { + { 0x01, "<CR>" }, + { 0x02, "<NUL>" }, + { 0, NULL } +}; + +static const value_string serial30_snoopctl_vals[] = { + { 0x00, "BMC uses Transmit ACCM" }, + { 0x01, "BMC uses Snoop ACCM" }, + { 0, NULL } +}; + +static const value_string serial30_negoctl_vals[] = { + { 0x00, "On initial connection and mux switch" }, + { 0x01, "On initial connection" }, + { 0x02, "Never" }, + { 0, NULL } +}; + +static const struct true_false_string serial30_filter_tfs = { + "Using Transmit ACCM", "Assuming all control chars escaped" +}; + +static const value_string serial30_ipaddr_val[] = { + { 0x00, "Request IP Address" }, + { 0x01, "Request Fixed IP Address" }, + { 0x02, "No Negotiation" }, + { 0, NULL } +}; + +static const value_string serialXX_proto_vals[] = { + { 0x00, "None" }, + { 0x01, "CHAP" }, + { 0x02, "PAP" }, + { 0x03, "MS-CHAP v1, Windows NT" }, + { 0x04, "MS-CHAP v1, Lan Manager" }, + { 0x05, "MS-CHAP v2" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_03_suspend = { + "Suspend", "Do not suspend" +}; + +static const struct true_false_string tfs_03_arp_status = { + "Occurring", "Suspended" +}; + +static const struct true_false_string tfs_04_clear = { + "Clear", "Do not clear" +}; + +static const value_string vals_12_mux[] = { + { 0x00, "Get present status" }, + { 0x01, "Request switch to system" }, + { 0x02, "Request switch to BMC" }, + { 0x03, "Force switch to system" }, + { 0x04, "Force switch to BMC" }, + { 0x05, "Block requests to switch to system" }, + { 0x06, "Allow requests to switch to system" }, + { 0x07, "Block requests to switch to BMC" }, + { 0x08, "Allow requests to switch to BMC" }, + { 0, NULL } +}; + +static const struct true_false_string tfs_12_blocked = { + "blocked", "allowed" +}; + +static const struct true_false_string tfs_12_req = { + "accepted/forced", "rejected" +}; + +static const struct true_false_string tfs_12_mux_state = { + "BMC", "system" +}; + +static const value_string vals_18_state[] = { + { 0x00, "No session active" }, + { 0x01, "Session active (mux switched to BMC)" }, + { 0x02, "Switching mux to system" }, + { 0, NULL } +}; + +static const int *lanXX_authtypes_byte[] = { &hf_ipmi_trn_lanXX_oem, &hf_ipmi_trn_lanXX_passwd, &hf_ipmi_trn_lanXX_md5, + &hf_ipmi_trn_lanXX_md2, &hf_ipmi_trn_lanXX_none, NULL }; + +static void +lan_serial_00(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan00_sip, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan00_byte1, + byte1, TRUE, 0); +} + +static void +lan_serial_01(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Authentication types supported: ", + "No authentication types supported for this channel", ett_ipmi_trn_lan01_byte1, + lanXX_authtypes_byte, TRUE, 0); +} + +static void +lan_serial_02(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Authentication types for Callback level: ", + "No authentication types enabled", ett_ipmi_trn_lan02_byte1, + lanXX_authtypes_byte, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Authentication types for User level: ", + "No authentication types enabled", ett_ipmi_trn_lan02_byte2, + lanXX_authtypes_byte, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, "Authentication types for Operator level: ", + "No authentication types enabled", ett_ipmi_trn_lan02_byte3, + lanXX_authtypes_byte, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Authentication types for Administrator level: ", + "No authentication types enabled", ett_ipmi_trn_lan02_byte4, + lanXX_authtypes_byte, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 4, 1, "Authentication types for OEM level: ", + "No authentication types enabled", ett_ipmi_trn_lan02_byte5, + lanXX_authtypes_byte, TRUE, 0); +} + +static void +lan_03(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan03_ip, tvb, 0, 4, FALSE); +} + +static void +lan_04(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan04_ipsrc, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan04_byte1, + byte1, TRUE, 0); +} + +static void +lan_05(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan05_ether, tvb, 0, 6, FALSE); +} + +static void +lan_06(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan06_subnet, tvb, 0, 4, FALSE); +} + +static void +lan_07(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte2[] = { &hf_ipmi_trn_lan07_flags, NULL }; + static const int *byte3[] = { &hf_ipmi_trn_lan07_precedence, &hf_ipmi_trn_lan07_tos, NULL }; + + proto_tree_add_item(tree, hf_ipmi_trn_lan07_ttl, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_trn_lan07_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_trn_lan07_byte3, byte3, TRUE, 0); +} + +static void +lan_08(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan08_rmcp_port, tvb, 0, 2, TRUE); +} + +static void +lan_09(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan09_rmcp_port, tvb, 0, 2, TRUE); +} + +static void +lan_10(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan10_responses, &hf_ipmi_trn_lan10_gratuitous, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan10_byte1, byte1, TRUE, 0); +} + +static void +lan_11(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan11_arp_interval, tvb, 0, 1, TRUE); +} + +static void +lan_12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan12_def_gw_ip, tvb, 0, 4, FALSE); +} + +static void +lan_13(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan13_def_gw_mac, tvb, 0, 6, FALSE); +} + +static void +lan_14(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan14_bkp_gw_ip, tvb, 0, 4, FALSE); +} + +static void +lan_15(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan15_bkp_gw_mac, tvb, 0, 6, FALSE); +} + +static void +lan_16(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_lan16_comm_string, tvb, 0, 18, TRUE); +} + +static void +lan_17(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan17_num_dst, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan17_byte1, byte1, TRUE, 0); +} + +static void +lan_18(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan18_dst_selector, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_lan18_ack, &hf_ipmi_trn_lan18_dst_type, NULL }; + static const int *byte4[] = { &hf_ipmi_trn_lan18_retries, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan18_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_trn_lan18_byte2, byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_lan18_tout, tvb, 2, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_trn_lan18_byte4, byte4, TRUE, 0); +} + +static void +lan_19(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan19_dst_selector, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_lan19_addr_format, NULL }; + static const int *byte3[] = { &hf_ipmi_trn_lan19_gw_sel, NULL }; + guint8 v; + + v = tvb_get_guint8(tvb, 1) >> 4; + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan19_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_trn_lan19_byte2, byte2, TRUE, 0); + + if (v == 0) { + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_trn_lan19_byte3, byte3, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_lan19_ip, tvb, 3, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_trn_lan19_mac, tvb, 7, 6, FALSE); + return; + } + + proto_tree_add_item(tree, hf_ipmi_trn_lan19_address, tvb, 2, tvb_length(tvb) - 2, TRUE); +} + +static void +lan_20(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte12[] = { &hf_ipmi_trn_lan20_vlan_id_enable, &hf_ipmi_trn_lan20_vlan_id, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 2, NULL, NULL, ett_ipmi_trn_lan20_byte12, byte12, TRUE, 0); +} + +static void +lan_21(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan21_vlan_prio, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan21_byte1, byte1, TRUE, 0); +} + +static void +lan_22(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan22_num_cs_entries, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan22_byte1, byte1, TRUE, 0); +} + +static void +lan_23(tvbuff_t *tvb, proto_tree *tree) +{ + guint i; + guint8 v; + + for (i = 0; i < 16; i++) { + v = tvb_get_guint8(tvb, i + 1); + proto_tree_add_uint_format(tree, hf_ipmi_trn_lan23_cs_entry, tvb, i + 1, 1, + v, "Cipher Suite ID entry %c: %u", 'A' + i, v); + } +} + +static void +lan_24(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *ett[] = { &ett_ipmi_trn_lan24_byte1, &ett_ipmi_trn_lan24_byte2, &ett_ipmi_trn_lan24_byte3, + &ett_ipmi_trn_lan24_byte4, &ett_ipmi_trn_lan24_byte5, &ett_ipmi_trn_lan24_byte6, &ett_ipmi_trn_lan24_byte7, + &ett_ipmi_trn_lan24_byte8 }; + proto_tree *s_tree; + proto_item *ti; + guint i; + guint8 v, v1, v2; + + for (i = 0; i < 8; i++) { + v = tvb_get_guint8(tvb, i + 1); + v1 = v & 0x0f; + v2 = v >> 4; + ti = proto_tree_add_text(tree, tvb, i + 1, 1, + "Cipher Suite #%d: %s (0x%02x), Cipher Suite #%d: %s (0x%02x)", + i * 2 + 1, val_to_str(v1, lan24_priv_vals, "Reserved"), v1, + i * 2 + 2, val_to_str(v2, lan24_priv_vals, "Reserved"), v2); + s_tree = proto_item_add_subtree(ti, *ett[i]); + proto_tree_add_uint_format(s_tree, hf_ipmi_trn_lan24_priv, tvb, i + 1, 1, + v2 << 4, "%sMaximum Privilege Level for Cipher Suite #%d: %s (0x%02x)", + ipmi_dcd8(v, 0xf0), i * 2 + 2, val_to_str(v2, lan24_priv_vals, "Reserved"), v2); + proto_tree_add_uint_format(s_tree, hf_ipmi_trn_lan24_priv, tvb, i + 1, 1, + v1, "%sMaximum Privilege Level for Cipher Suite #%d: %s (0x%02x)", + ipmi_dcd8(v, 0x0f), i * 2 + 1, val_to_str(v1, lan24_priv_vals, "Reserved"), v1); + } +} + +static void +lan_25(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_lan25_dst_selector, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_lan25_addr_format, NULL }; + static const int *byte34[] = { &hf_ipmi_trn_lan25_uprio, &hf_ipmi_trn_lan25_cfi, &hf_ipmi_trn_lan25_vlan_id, NULL }; + guint8 v; + + v = tvb_get_guint8(tvb, 1) >> 4; + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_lan25_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_trn_lan25_byte2, byte2, TRUE, 0); + switch (v) { + case 0: + break; + case 1: + proto_tree_add_bitmask_text(tree, tvb, 2, 2, NULL, NULL, ett_ipmi_trn_lan25_byte34, + byte34, TRUE, 0); + break; + default: + proto_tree_add_item(tree, hf_ipmi_trn_lan25_address, tvb, 2, tvb_length(tvb) - 2, TRUE); + break; + } +} + +static struct { + void (*intrp)(tvbuff_t *tvb, proto_tree *tree); + const char *name; +} lan_options[] = { + { lan_serial_00, "Set In Progress" }, + { lan_serial_01, "Authentication Type Support" }, + { lan_serial_02, "Authentication Type Enables" }, + { lan_03, "IP Address" }, + { lan_04, "IP Address Source" }, + { lan_05, "MAC Address" }, + { lan_06, "Subnet Mask" }, + { lan_07, "IPv4 Header Parameters" }, + { lan_08, "Primary RMCP Port Number" }, + { lan_09, "Secondary RMCP Port Number" }, + { lan_10, "BMC-generated ARP Control" }, + { lan_11, "Gratuitous ARP Interval" }, + { lan_12, "Default Gateway Address" }, + { lan_13, "Default Gateway MAC Address" }, + { lan_14, "Backup Gateway Address" }, + { lan_15, "Backup Gateway MAC Address" }, + { lan_16, "Community String" }, + { lan_17, "Number of Destinations" }, + { lan_18, "Destination Type" }, + { lan_19, "Destination Addresses" }, + { lan_20, "VLAN ID (802.1q)" }, + { lan_21, "VLAN Priority (802.1q)" }, + { lan_22, "Cipher Suite Entry Support (RMCP+)" }, + { lan_23, "Cipher Suite Entries (RMCP+)" }, + { lan_24, "Cipher Suite Privilege Levels (RMCP+)" }, + { lan_25, "Destination Address VLAN TAGs" }, +}; + +/* Set LAN Configuration Parameters + */ +static void +rq01(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_01_chan, NULL }; + tvbuff_t *next; + const char *desc; + guint8 pno; + + pno = tvb_get_guint8(tvb, 1); + if (pno < array_length(lan_options)) { + desc = lan_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_01_byte1, + byte1, TRUE, 0); + proto_tree_add_uint_format_value(tree, hf_ipmi_trn_01_param, tvb, 1, 1, + pno, "%s (0x%02x)", desc, pno); + if (pno < array_length(lan_options)) { + next = tvb_new_subset(tvb, 2, tvb_length(tvb) - 2, tvb_length(tvb) - 2); + lan_options[pno].intrp(next, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_trn_01_param_data, tvb, 2, + tvb_length(tvb) - 2, TRUE); + } +} + +static const value_string cc01[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0x83, "Attempt to read write-only parameter" }, + { 0, NULL } +}; + +/* Get LAN Configuration Parameters + */ +static void +rq02(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_02_getrev, &hf_ipmi_trn_02_chan, NULL }; + const char *desc; + guint8 pno; + + pno = tvb_get_guint8(tvb, 1); + + if (!tree) { + ipmi_setsaveddata(0, pno); + ipmi_setsaveddata(1, tvb_get_guint8(tvb, 0) & 0x80); + return; + } + + if (pno < array_length(lan_options)) { + desc = lan_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_02_byte1, byte1, TRUE, 0); + proto_tree_add_uint_format_value(tree, hf_ipmi_trn_02_param, tvb, 1, 1, + pno, "%s (0x%02x)", desc, pno); + proto_tree_add_item(tree, hf_ipmi_trn_02_set, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_02_block, tvb, 2, 1, TRUE); +} + +static void +rs02(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_02_rev_present, &hf_ipmi_trn_02_rev_compat, NULL }; + proto_item *ti; + tvbuff_t *next; + const char *desc; + guint32 pno, req; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_02_rev, byte1, TRUE, 0); + + if (!ipmi_getsaveddata(0, &pno) || !ipmi_getsaveddata(1, &req)) { + /* No request found - cannot parse further */ + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_trn_02_param_data, tvb, 1, tvb_length(tvb) - 1, TRUE); + }; + return; + } + + if ((req & 0x80) && tvb_length(tvb) > 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter revision; parameter data returned"); + PROTO_ITEM_SET_GENERATED(ti); + } else if (!(req & 0x80) && tvb_length(tvb) == 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned"); + PROTO_ITEM_SET_GENERATED(ti); + } + + if (pno < array_length(lan_options)) { + desc = lan_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc); + PROTO_ITEM_SET_GENERATED(ti); + + if (tvb_length(tvb) > 1) { + if (pno < array_length(lan_options)) { + next = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + lan_options[pno].intrp(next, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_trn_02_param_data, tvb, 1, + tvb_length(tvb) - 1, TRUE); + } + } +} + +static const value_string cc02[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +static void +rq03(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_03_chan, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_03_arp_resp, &hf_ipmi_trn_03_gratuitous_arp, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_03_rq_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_03_rq_byte2, byte2, TRUE, 0); +} + +static void +rs03(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_03_status_arp_resp, + &hf_ipmi_trn_03_status_gratuitous_arp, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_03_rs_byte1, byte1, TRUE, 0); +} + +static void +rq04(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_04_chan, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_04_clear, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_04_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_04_byte2, byte2, TRUE, 0); +} + +static void +rs04(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_ippkts, tvb, 0, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_iphdr_err, tvb, 2, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_ipaddr_err, tvb, 4, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_ippkts_frag, tvb, 6, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_tx_ippkts, tvb, 8, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_udppkts, tvb, 10, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_validrmcp, tvb, 12, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_rx_udpproxy, tvb, 14, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_04_dr_udpproxy, tvb, 16, 2, TRUE); +} + +static void +serial_03(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_serial03_connmode, &hf_ipmi_trn_serial03_terminal, + &hf_ipmi_trn_serial03_ppp, &hf_ipmi_trn_serial03_basic, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial03_byte1, byte1, TRUE, 0); +} + +static void +serial04_timeout_fmt(gchar *s, guint32 v) +{ + if (v) { + g_snprintf(s, ITEM_LABEL_LENGTH, "%d sec", 30 * v); + } + else { + g_snprintf(s, ITEM_LABEL_LENGTH, "Does not timeout"); + } +} + +static void +serial_04(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial04_timeout, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial04_byte1, byte1, TRUE, 0); +} + +static void +serial_05(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_serial05_cbcp_callback, + &hf_ipmi_trn_serial05_ipmi_callback, NULL }; + static const int *byte2[] = { &hf_ipmi_trn_serial05_cb_list, &hf_ipmi_trn_serial05_cb_user, + &hf_ipmi_trn_serial05_cb_prespec, &hf_ipmi_trn_serial05_no_cb, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Callback capabilities: ", "None", + ett_ipmi_trn_serial05_byte1, byte1, TRUE, BMT_NO_TFS); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "CBCP negotiation options: ", "None", + ett_ipmi_trn_serial05_byte2, byte2, TRUE, BMT_NO_TFS); + proto_tree_add_item(tree, hf_ipmi_trn_serial05_cb_dest1, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial05_cb_dest2, tvb, 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial05_cb_dest3, tvb, 4, 1, TRUE); +} + +static void +serial_06(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial06_inactivity, + &hf_ipmi_trn_serial06_dcd, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial06_byte1, byte1, TRUE, 0); +} + +static void +serial_07(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial07_flowctl, &hf_ipmi_trn_serial07_dtrhangup, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial07_bitrate, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial07_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial07_byte2, byte2, TRUE, 0); +} + +static void +serial_08(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial08_esc_powerup, + &hf_ipmi_trn_serial08_esc_reset, &hf_ipmi_trn_serial08_switch_authcap, + &hf_ipmi_trn_serial08_switch_rmcp, &hf_ipmi_trn_serial08_esc_switch1, + &hf_ipmi_trn_serial08_esc_switch2, &hf_ipmi_trn_serial08_switch_dcdloss, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial08_sharing, + &hf_ipmi_trn_serial08_ping_callback, &hf_ipmi_trn_serial08_ping_direct, + &hf_ipmi_trn_serial08_ping_retry, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Switch/escape settings", NULL, + ett_ipmi_trn_serial08_byte1, byte1, TRUE, BMT_NO_APPEND); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Sharing/ping settings", NULL, + ett_ipmi_trn_serial08_byte2, byte2, TRUE, BMT_NO_APPEND); +} + +static void +serial_09(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial09_ring_duration, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial09_ring_dead, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial09_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial09_byte2, byte2, TRUE, 0); +} + +static void +serial_10(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial10_set_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial10_init_str, tvb, 1, tvb_length(tvb) - 1, TRUE); +} + +static void +serial_11(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial11_esc_seq, tvb, 0, 5, TRUE); +} + +static void +serial_12(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial12_hangup_seq, tvb, 0, 8, TRUE); +} + +static void +serial_13(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial13_dial_cmd, tvb, 0, 8, TRUE); +} + +static void +serial_14(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial14_page_blackout, tvb, 0, 1, TRUE); +} + +static void +serial_15(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial15_comm_string, tvb, 0, 18, TRUE); +} + +static void +serial_16(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial16_ndest, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial16_byte1, byte1, TRUE, 0); +} + +static void +serial_17(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial17_dest_sel, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial17_ack, &hf_ipmi_trn_serial17_dest_type, NULL }; + static const gint *byte4[] = { &hf_ipmi_trn_serial17_alert_retries, &hf_ipmi_trn_serial17_call_retries, NULL }; + const gint *byte5[3] = { NULL, NULL, NULL }; + guint8 v; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial17_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial17_byte2, byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_serial17_alert_ack_timeout, tvb, 2, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 3, 1, NULL, NULL, + ett_ipmi_trn_serial17_byte4, byte4, TRUE, 0); + + v = tvb_get_guint8(tvb, 1) & 0x0f; + switch (v) { + case 0: /* Dial Page */ + case 3: /* Basic Mode Callback */ + byte5[0] = &hf_ipmi_trn_serial17_dialstr_sel; + break; + case 1: /* TAP Page */ + byte5[0] = &hf_ipmi_trn_serial17_tap_sel; + break; + case 2: /* PPP Alert */ + case 4: /* PPP Callback */ + byte5[0] = &hf_ipmi_trn_serial17_ipaddr_sel; + byte5[1] = &hf_ipmi_trn_serial17_ppp_sel; + break; + default: + proto_tree_add_item(tree, hf_ipmi_trn_serial17_unknown, tvb, 4, 1, TRUE); + return; + } + proto_tree_add_bitmask_text(tree, tvb, 4, 1, NULL, NULL, + ett_ipmi_trn_serial17_byte5, byte5, TRUE, 0); +} + +static void +serial_18(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial18_call_retry, tvb, 0, 1, TRUE); +} + +static void +serial_19(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial19_destsel, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial19_flowctl, &hf_ipmi_trn_serial19_dtrhangup, + &hf_ipmi_trn_serial19_stopbits, &hf_ipmi_trn_serial19_charsize, &hf_ipmi_trn_serial19_parity, NULL }; + static const gint *byte3[] = { &hf_ipmi_trn_serial19_bitrate, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial19_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial19_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, + ett_ipmi_trn_serial19_byte3, byte3, TRUE, 0); +} + +static void +serial_20(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial20_num_dial_strings, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial20_byte1, byte1, TRUE, 0); +} + +static void +serial_21(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial21_dialsel, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial21_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_serial21_blockno, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial21_dialstr, tvb, 2, 1, TRUE); +} + +static void +serial_22(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial22_num_ipaddrs, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial22_byte1, byte1, TRUE, 0); +} + +static void +serial_23(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial23_destsel, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial23_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_serial23_ipaddr, tvb, 1, 4, FALSE); +} + +static void +serial_24(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial24_num_tap_accounts, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial24_byte1, byte1, TRUE, 0); +} + +static void +serial_25(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_trn_serial25_dialstr_sel, &hf_ipmi_trn_serial25_tapsrv_sel, NULL }; + + proto_tree_add_item(tree, hf_ipmi_trn_serial25_tap_acct, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial25_byte2, byte2, TRUE, 0); +} + +static void +serial_26(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial26_tap_acct, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial26_tap_passwd, tvb, 1, 6, TRUE); +} + +static void +serial_27(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial27_tap_acct, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial27_tap_pager_id, tvb, 1, 16, TRUE); +} + +static void +serial_28(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial28_tapsrv_sel, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial28_confirm, NULL }; + static const gint *byte10[] = { &hf_ipmi_trn_serial28_t2, &hf_ipmi_trn_serial28_t1, NULL }; + static const gint *byte11[] = { &hf_ipmi_trn_serial28_t4, &hf_ipmi_trn_serial28_t3, NULL }; + static const gint *byte12[] = { &hf_ipmi_trn_serial28_t6, &hf_ipmi_trn_serial28_t5, NULL }; + static const gint *byte13[] = { &hf_ipmi_trn_serial28_n2, &hf_ipmi_trn_serial28_n1, NULL }; + static const gint *byte14[] = { &hf_ipmi_trn_serial28_n4, &hf_ipmi_trn_serial28_n3, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte2, byte2, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_serial28_srvtype, tvb, 2, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial28_ctrl_esc, tvb, 5, 4, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 9, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte10, byte10, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 10, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte11, byte11, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 11, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte12, byte12, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 12, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte13, byte13, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 13, 1, NULL, NULL, + ett_ipmi_trn_serial28_byte14, byte14, TRUE, 0); +} + +static void +serial_29(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial29_op, &hf_ipmi_trn_serial29_lineedit, + &hf_ipmi_trn_serial29_deletectl, &hf_ipmi_trn_serial29_echo, &hf_ipmi_trn_serial29_handshake, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial29_o_newline, &hf_ipmi_trn_serial29_i_newline, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial29_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial29_byte2, byte2, TRUE, 0); +} + +static void +serial_30(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial30_snooping, &hf_ipmi_trn_serial30_snoopctl, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_serial30_negot_ctl, &hf_ipmi_trn_serial30_use_xmit_accm, + &hf_ipmi_trn_serial30_xmit_addr_comp, &hf_ipmi_trn_serial30_xmit_proto_comp, NULL }; + static const gint *byte3[] = { &hf_ipmi_trn_serial30_ipaddr, &hf_ipmi_trn_serial30_accm, + &hf_ipmi_trn_serial30_addr_comp, &hf_ipmi_trn_serial30_proto_comp, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial30_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial30_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, + ett_ipmi_trn_serial30_byte3, byte3, TRUE, 0); +} + +static void +serial_31(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial31_port, tvb, 0, 2, TRUE); +} + +static void +serial_32(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial32_port, tvb, 0, 2, TRUE); +} + +static void +serial_33(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial33_auth_proto, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial33_byte1, byte1, TRUE, 0); +} + +static void +serial_34(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial34_chap_name, tvb, 0, 16, TRUE); +} + +static void +serial_35(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial35_recv_accm, tvb, 0, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_trn_serial35_xmit_accm, tvb, 4, 4, FALSE); +} + +static void +serial_36(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial36_snoop_accm, tvb, 0, 4, FALSE); +} + +static void +serial_37(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial37_num_ppp, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_serial37_byte1, byte1, TRUE, 0); +} + +static void +serial_38(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial38_acct_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial38_dialstr_sel, tvb, 1, 1, TRUE); +} + +static void +serial_39(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial39_acct_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial39_ipaddr, tvb, 1, 4, FALSE); +} + +static void +serial_40(tvbuff_t *tvb, proto_tree *tree) +{ + int slen; + + proto_tree_add_item(tree, hf_ipmi_trn_serial40_acct_sel, tvb, 0, 1, TRUE); + slen = tvb_length(tvb) - 1; + if (slen > 16) { + slen = 16; + } + proto_tree_add_item(tree, hf_ipmi_trn_serial40_username, tvb, 1, slen, TRUE); +} + +static void +serial_41(tvbuff_t *tvb, proto_tree *tree) +{ + int slen; + + proto_tree_add_item(tree, hf_ipmi_trn_serial41_acct_sel, tvb, 0, 1, TRUE); + slen = tvb_length(tvb) - 1; + if (slen > 16) { + slen = 16; + } + proto_tree_add_item(tree, hf_ipmi_trn_serial41_userdomain, tvb, 1, slen, TRUE); +} + +static void +serial_42(tvbuff_t *tvb, proto_tree *tree) +{ + int slen; + + proto_tree_add_item(tree, hf_ipmi_trn_serial42_acct_sel, tvb, 0, 1, TRUE); + slen = tvb_length(tvb) - 1; + if (slen > 16) { + slen = 16; + } + proto_tree_add_item(tree, hf_ipmi_trn_serial42_userpass, tvb, 1, slen, TRUE); +} + +static void +serial_43(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial43_auth_proto, NULL }; + + proto_tree_add_item(tree, hf_ipmi_trn_serial43_acct_sel, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial43_byte1, byte1, TRUE, 0); +} + +static void +serial_44(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial44_acct_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial44_hold_time, tvb, 1, 1, TRUE); +} + +static void +serial_45(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial45_src_ipaddr, tvb, 0, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_trn_serial45_dst_ipaddr, tvb, 4, 4, FALSE); +} + +static void +serial_46(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial46_tx_bufsize, tvb, 0, 2, TRUE); +} + +static void +serial_47(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial47_rx_bufsize, tvb, 0, 2, TRUE); +} + +static void +serial_48(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial48_ipaddr, tvb, 0, 4, FALSE); +} + +static void +serial_49(tvbuff_t *tvb, proto_tree *tree) +{ + int slen; + + proto_tree_add_item(tree, hf_ipmi_trn_serial49_blockno, tvb, 0, 1, TRUE); + slen = tvb_length(tvb) - 1; + if (slen > 16) { + slen = 16; + } + proto_tree_add_item(tree, hf_ipmi_trn_serial49_dialstr, tvb, 1, slen, TRUE); +} + +static void +serial_50(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_serial50_115200, &hf_ipmi_trn_serial50_57600, + &hf_ipmi_trn_serial50_38400, &hf_ipmi_trn_serial50_19200, &hf_ipmi_trn_serial50_9600, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Bit rate support: ", "None", + ett_ipmi_trn_serial50_byte1, byte1, TRUE, 0); +} + +static void +serial_51(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte2[] = { &hf_ipmi_trn_serial51_ipmi_channel, &hf_ipmi_trn_serial51_conn_num, NULL }; + static const gint *byte3[] = { &hf_ipmi_trn_serial51_ipmi_sharing, + &hf_ipmi_trn_serial51_ipmi_sol, &hf_ipmi_trn_serial51_chan_num, NULL }; + + proto_tree_add_item(tree, hf_ipmi_trn_serial51_port_assoc_sel, tvb, 0, 1, TRUE); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_serial51_byte2, byte2, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, + ett_ipmi_trn_serial51_byte3, byte3, TRUE, 0); +} + +static void +serial_52(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial52_port_assoc_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial52_conn_name, tvb, 1, 16, TRUE); +} + +static void +serial_53(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_serial53_port_assoc_sel, tvb, 0, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_serial53_chan_name, tvb, 1, 16, TRUE); +} + +static struct { + void (*intrp)(tvbuff_t *tvb, proto_tree *tree); + const char *name; +} serial_options[] = { + { lan_serial_00, "Set In Progress" }, + { lan_serial_01, "Authentication Type Support" }, + { lan_serial_02, "Authentication Type Enables" }, + { serial_03, "Connection Mode" }, + { serial_04, "Session Inactivity Timeout" }, + { serial_05, "Channel Callback Control" }, + { serial_06, "Session Termination" }, + { serial_07, "IPMI Messaging Comm Settings" }, + { serial_08, "Mux Switch Control" }, + { serial_09, "Modem Ring Time" }, + { serial_10, "Modem Init String" }, + { serial_11, "Modem Escape Sequence" }, + { serial_12, "Modem Hang-up Sequence" }, + { serial_13, "Modem Dial Command" }, + { serial_14, "Page Blackout Interval" }, + { serial_15, "Community String" }, + { serial_16, "Number of Alert Destinations" }, + { serial_17, "Destination Info" }, + { serial_18, "Call Retry Interval" }, + { serial_19, "Destination Comm Settings" }, + { serial_20, "Number of Dial Strings" }, + { serial_21, "Destination Dial Strings" }, + { serial_22, "Number of Alert Destination IP Addresses" }, + { serial_23, "Destination IP Addresses" }, + { serial_24, "Number of TAP Accounts" }, + { serial_25, "TAP Account" }, + { serial_26, "TAP Passwords" }, + { serial_27, "TAP Pager ID Strings" }, + { serial_28, "TAP Service Settings" }, + { serial_29, "Terminal Mode Configuration" }, + { serial_30, "PPP Protocol Options" }, + { serial_31, "PPP Primary RMCP Port" }, + { serial_32, "PPP Secondary RMCP Port" }, + { serial_33, "PPP Link Authentication" }, + { serial_34, "CHAP Name" }, + { serial_35, "PPP ACCM" }, + { serial_36, "PPP Snoop ACCM" }, + { serial_37, "Number of PPP Accounts" }, + { serial_38, "PPP Account Dial String Selector" }, + { serial_39, "PPP Account IP Addresses" }, + { serial_40, "PPP Account User Names" }, + { serial_41, "PPP Account User Domains" }, + { serial_42, "PPP Account User Passwords" }, + { serial_43, "PPP Account Authentication Settings" }, + { serial_44, "PPP Account Connection Hold Times" }, + { serial_45, "PPP UDP Proxy IP Header" }, + { serial_46, "PPP UDP Proxy Transmit Buffer Size" }, + { serial_47, "PPP UDP Proxy Receive Buffer Size" }, + { serial_48, "PPP Remote Console IP Address" }, + { serial_49, "System Phone Number" }, + { serial_50, "Bitrate Support" }, + { serial_51, "System Serial Port Association" }, + { serial_52, "System Connector Names" }, + { serial_53, "System Serial Channel Names" } +}; + +/* Set Serial/Modem Configuration Parameters + */ +static void +rq10(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_10_chan, NULL }; + tvbuff_t *next; + const char *desc; + guint8 pno; + + pno = tvb_get_guint8(tvb, 1); + if (pno < array_length(serial_options)) { + desc = serial_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_trn_10_byte1, + byte1, TRUE, 0); + proto_tree_add_uint_format_value(tree, hf_ipmi_trn_10_param, tvb, 1, 1, + pno, "%s (0x%02x)", desc, pno); + if (pno < array_length(serial_options)) { + next = tvb_new_subset(tvb, 2, tvb_length(tvb) - 2, tvb_length(tvb) - 2); + serial_options[pno].intrp(next, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_trn_10_param_data, tvb, 2, + tvb_length(tvb) - 2, TRUE); + } +} + +static const value_string cc10[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0x83, "Attempt to read write-only parameter" }, + { 0, NULL } +}; + +/* Get LAN Configuration Parameters + */ +static void +rq11(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_11_getrev, &hf_ipmi_trn_11_chan, NULL }; + const char *desc; + guint8 pno; + + pno = tvb_get_guint8(tvb, 1); + + if (!tree) { + ipmi_setsaveddata(0, pno); + ipmi_setsaveddata(1, tvb_get_guint8(tvb, 0)); + return; + } + + if (pno < array_length(serial_options)) { + desc = serial_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_11_byte1, byte1, TRUE, 0); + proto_tree_add_uint_format_value(tree, hf_ipmi_trn_11_param, tvb, 1, 1, + pno, "%s (0x%02x)", desc, pno); + proto_tree_add_item(tree, hf_ipmi_trn_11_set, tvb, 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_11_block, tvb, 2, 1, TRUE); +} + +static void +rs11(tvbuff_t *tvb, proto_tree *tree) +{ + static const int *byte1[] = { &hf_ipmi_trn_11_rev_present, &hf_ipmi_trn_11_rev_compat, NULL }; + proto_item *ti; + tvbuff_t *next; + const char *desc; + guint32 pno, req; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_11_rev, byte1, TRUE, 0); + + if (!ipmi_getsaveddata(0, &pno) && !ipmi_getsaveddata(1, &req)) { + /* No request found - cannot parse further */ + if (tvb_length(tvb) > 1) { + proto_tree_add_item(tree, hf_ipmi_trn_11_param_data, tvb, 1, tvb_length(tvb) - 1, TRUE); + }; + return; + } + + if (pno < array_length(serial_options)) { + desc = serial_options[pno].name; + } else if (pno >= 0xC0) { + desc = "OEM"; + } else { + desc = "Reserved"; + } + + if ((req & 0x80) && tvb_length(tvb) > 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter revision; parameter data returned"); + PROTO_ITEM_SET_GENERATED(ti); + } else if (!(req & 0x80) && tvb_length(tvb) == 1) { + ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned"); + PROTO_ITEM_SET_GENERATED(ti); + } + + ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc); + PROTO_ITEM_SET_GENERATED(ti); + + if (tvb_length(tvb) > 1) { + if (pno < array_length(serial_options)) { + next = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); + serial_options[pno].intrp(next, tree); + } else { + proto_tree_add_item(tree, hf_ipmi_trn_11_param_data, tvb, 1, + tvb_length(tvb) - 1, TRUE); + } + } +} + +static const value_string cc11[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +/* Set Serial/Modem Mux + */ +static void +rq12(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_12_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_12_mux_setting, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_12_rq_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_12_rq_byte2, byte2, TRUE, 0); +} + +static void +rs12(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_12_sw_to_sys, &hf_ipmi_trn_12_sw_to_bmc, + &hf_ipmi_trn_12_alert, &hf_ipmi_trn_12_msg, &hf_ipmi_trn_12_req, &hf_ipmi_trn_12_mux_state, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_12_rs_byte1, byte1, TRUE, 0); +} + +/* Get TAP Response Codes + */ +static void +rq13(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_13_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_13_byte1, byte1, TRUE, 0); +} + +static void +rs13(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_13_code1, tvb, 0, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_13_code2, tvb, 3, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_13_code3, tvb, 6, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_13_code4, tvb, 9, 3, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_13_code5, tvb, 12, 3, TRUE); +} + +/* Set PPP UDP Proxy Transmit Data + */ +static void +rq14(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_14_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_14_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_14_block, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_14_data, tvb, 2, 16, TRUE); +} + +/* Get PPP UDP Proxy Transmit Data + */ +static void +rq15(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_15_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_15_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_15_block, tvb, 1, 1, TRUE); +} + +static void +rs15(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_ipmi_trn_15_data, tvb, 0, 16, TRUE); +} + +/* Send PPP UDP Proxy Packet + */ +static void +rq16(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_16_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_16_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_16_src_port, tvb, 1, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_16_dst_port, tvb, 3, 2, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_16_src_addr, tvb, 5, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_trn_16_dst_addr, tvb, 9, 4, FALSE); + proto_tree_add_item(tree, hf_ipmi_trn_16_bytes, tvb, 13, 2, TRUE); +} + +static const value_string cc16[] = { + { 0x80, "PPP link is not up" }, + { 0x81, "IP protocol is not up" }, + { 0, NULL } +}; + +/* Get PPP UDP Proxy Receive Data + */ +static void +tr17_fmt_blockno(gchar *s, guint32 v) +{ + g_snprintf(s, ITEM_LABEL_LENGTH, "%d%s", + v, v ? "" : " (get received data length)"); +} + +static void +rq17(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_17_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_17_clear, &hf_ipmi_trn_17_block_num, NULL }; + + if (!tree) { + /* Save block number */ + ipmi_setsaveddata(0, tvb_get_guint8(tvb, 1) & 0x7f); + return; + } + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_17_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_17_byte2, byte2, TRUE, 0); +} + +static void +rs17(tvbuff_t *tvb, proto_tree *tree) +{ + guint32 bno; + + if (ipmi_getsaveddata(0, &bno) && bno == 0) { + /* Request for length */ + proto_tree_add_item(tree, hf_ipmi_trn_17_size, tvb, 0, 2, TRUE); + } else { + proto_tree_add_item(tree, hf_ipmi_trn_17_data, tvb, 0, + tvb_length(tvb) < 16 ? tvb_length(tvb) : 16, TRUE); + } +} + +static const value_string cc17[] = { + { 0x80, "No packet data available" }, + { 0, NULL } +}; + +/* Serial/Modem Connection Active + */ +static void +rq18(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_18_state, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_18_byte1, byte1, TRUE, 0); + proto_tree_add_item(tree, hf_ipmi_trn_18_ipmi_ver, tvb, 1, 1, TRUE); +} + +/* Callback + */ +static void +rq19(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_19_chan, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_19_dest_sel, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_19_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_19_byte2, byte2, TRUE, 0); +} + +static const value_string cc19[] = { + { 0x81, "Callback rejected, alert in progress on this channel" }, + { 0x82, "Callback rejected, IPMI messaging active on this channel" }, + { 0, NULL } +}; + +/* Common for Set/Get User Callback Options + */ +static void +parse_callback_options(tvbuff_t *tvb, guint offs, proto_tree *tree) +{ + static const gint *usercap[] = { &hf_ipmi_trn_XX_cap_cbcp, &hf_ipmi_trn_XX_cap_ipmi, NULL }; + static const gint *cbcp[] = { &hf_ipmi_trn_XX_cbcp_from_list, &hf_ipmi_trn_XX_cbcp_user, + &hf_ipmi_trn_XX_cbcp_prespec, &hf_ipmi_trn_XX_cbcp_nocb, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, offs, 1, + "User callback capabilities: ", "None", + ett_ipmi_trn_XX_usercap, usercap, TRUE, BMT_NO_TFS); + proto_tree_add_bitmask_text(tree, tvb, offs + 1, 1, + "CBCP negotiation options: ", "None", + ett_ipmi_trn_XX_cbcp, cbcp, TRUE, BMT_NO_TFS); + proto_tree_add_item(tree, hf_ipmi_trn_XX_dst1, tvb, offs + 2, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_XX_dst2, tvb, offs + 3, 1, TRUE); + proto_tree_add_item(tree, hf_ipmi_trn_XX_dst3, tvb, offs + 4, 1, TRUE); +} + +/* Set User Callback Options + */ +static void +rq1a(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_1a_user, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_1a_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_1a_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_1a_byte2, byte2, TRUE, 0); + parse_callback_options(tvb, 2, tree); +} + +/* Get User Callback Options + */ +static void +rq1b(tvbuff_t *tvb, proto_tree *tree) +{ + static const gint *byte1[] = { &hf_ipmi_trn_1b_user, NULL }; + static const gint *byte2[] = { &hf_ipmi_trn_1b_chan, NULL }; + + proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, + ett_ipmi_trn_1b_byte1, byte1, TRUE, 0); + proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, + ett_ipmi_trn_1b_byte2, byte2, TRUE, 0); +} + +static void +rs1b(tvbuff_t *tvb, proto_tree *tree) +{ + parse_callback_options(tvb, 0, tree); +} + +static const value_string cc21[] = { + { 0x80, "Parameter not supported" }, + { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" }, + { 0x82, "Attempt to write read-only parameter" }, + { 0x83, "Attempt to read write-only parameter" }, + { 0, NULL } +}; + +static const value_string cc22[] = { + { 0x80, "Parameter not supported" }, + { 0, NULL } +}; + +static const value_string cc33[] = { + { 0x80, "Target controller unavailable" }, + { 0, NULL } +}; + +static ipmi_cmd_t cmd_transport[] = { + /* LAN Device Commands */ + { 0x01, rq01, NULL, cc01, NULL, "Set LAN Configuration Parameters", 0 }, + { 0x02, rq02, rs02, cc02, NULL, "Get LAN Configuration Parameters", CMD_CALLRQ }, + { 0x03, rq03, rs03, NULL, NULL, "Suspend BMC ARPs", 0 }, + { 0x04, rq04, rs04, NULL, NULL, "Get IP/UDP/RMCP Statistics", 0 }, + + /* Serial/Modem Device Commands */ + { 0x10, rq10, NULL, cc10, NULL, "Set Serial/Modem Configuration", 0 }, + { 0x11, rq11, rs11, cc11, NULL, "Get Serial/Modem Configuration", CMD_CALLRQ }, + { 0x12, rq12, rs12, NULL, NULL, "Set Serial/Modem Mux", 0 }, + { 0x13, rq13, rs13, NULL, NULL, "Get TAP Response Codes", 0 }, + { 0x14, rq14, NULL, NULL, NULL, "Set PPP UDP Proxy Transmit Data", 0 }, + { 0x15, rq15, rs15, NULL, NULL, "Get PPP UDP Proxy Transmit Data", 0 }, + { 0x16, rq16, NULL, cc16, NULL, "Send PPP UDP Proxy Packet", 0 }, + { 0x17, rq17, rs17, cc17, NULL, "Get PPP UDP Proxy Receive Data", CMD_CALLRQ }, + { 0x18, rq18, NULL, NULL, NULL, "Serial/Modem Connection Active", 0 }, + { 0x19, rq19, NULL, cc19, NULL, "Callback", 0 }, + { 0x1a, rq1a, NULL, NULL, NULL, "Set User Callback Options", 0 }, + { 0x1b, rq1b, rs1b, NULL, NULL, "Get User Callback Options", 0 }, + { 0x1c, IPMI_TBD, NULL, NULL, "Set Serial Routing Mux", 0 }, + + /* Serial-Over-LAN Commands */ + { 0x20, IPMI_TBD, NULL, NULL, "SOL Activating", 0 }, + { 0x21, IPMI_TBD, cc21, NULL, "Set SOL Configuration Parameters", 0 }, + { 0x22, IPMI_TBD, cc22, NULL, "Get SOL Configuration Parameters", CMD_CALLRQ }, + + /* Command Forwarding Commands */ + { 0x30, IPMI_TBD, NULL, NULL, "Forwarded Command", 0 }, + { 0x31, IPMI_TBD, NULL, NULL, "Set Forwarded Commands", 0 }, + { 0x32, IPMI_TBD, NULL, NULL, "Get Forwarded Commands", 0 }, + { 0x33, IPMI_TBD, cc33, NULL, "Enable Forwarded Commands", 0 }, +}; + +void +ipmi_register_transport(gint proto_ipmi) +{ + static hf_register_info hf[] = { + { &hf_ipmi_trn_lan00_sip, + { "Set In Progress", + "ipmi.lan00.sip", FT_UINT8, BASE_HEX, lan00_sip_vals, 0x03, "", HFILL }}, + + { &hf_ipmi_trn_lanXX_oem, + { "OEM Proprietary", + "ipmi.lanXX.oem", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_ipmi_trn_lanXX_passwd, + { "Straight password/key", + "ipmi.lanXX.passwd", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_trn_lanXX_md5, + { "MD5", + "ipmi.lanXX.md5", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_trn_lanXX_md2, + { "MD2", + "ipmi.lanXX.md2", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_trn_lanXX_none, + { "None", + "ipmi.lanXX.none", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + + { &hf_ipmi_trn_lan03_ip, + { "IP Address", + "ipmi.lan03.ip", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan04_ipsrc, + { "IP Address Source", + "ipmi.lan04.ipsrc", FT_UINT8, BASE_HEX, lan04_ipsrc_vals, 0x0f, "", HFILL }}, + + { &hf_ipmi_trn_lan05_ether, + { "MAC Address", + "ipmi.lan05.mac", FT_ETHER, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan06_subnet, + { "Subnet Mask", + "ipmi.lan06.subnet", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan07_ttl, + { "Time-to-live", + "ipmi.lan07.ttl", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_lan07_flags, + { "Flags", + "ipmi.lan07.flags", FT_UINT8, BASE_HEX, NULL, 0xe0, "", HFILL }}, + { &hf_ipmi_trn_lan07_precedence, + { "Precedence", + "ipmi.lan07.precedence", FT_UINT8, BASE_DEC, NULL, 0xe0, "", HFILL }}, + { &hf_ipmi_trn_lan07_tos, + { "Type of service", + "ipmi.lan07.tos", FT_UINT8, BASE_HEX, NULL, 0x1e, "", HFILL }}, + + { &hf_ipmi_trn_lan08_rmcp_port, + { "Primary RMCP Port Number", + "ipmi.lan08.rmcp_port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan09_rmcp_port, + { "Secondary RMCP Port Number", + "ipmi.lan09.rmcp_port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan10_responses, + { "ARP responses", + "ipmi.lan10.responses", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_lan10_gratuitous, + { "Gratuitous ARPs", + "ipmi.lan10.gratuitous", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + + { &hf_ipmi_trn_lan11_arp_interval, + { "Gratuitous ARP interval", + "ipmi.lan10.arp_interval", FT_UINT8, BASE_CUSTOM, ipmi_fmt_500ms_0based, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan12_def_gw_ip, + { "Default Gateway Address", + "ipmi.lan12.def_gw_ip", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan13_def_gw_mac, + { "Default Gateway MAC Address", + "ipmi.lan13.def_gw_mac", FT_ETHER, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan14_bkp_gw_ip, + { "Backup Gateway Address", + "ipmi.lan14.bkp_gw_ip", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan15_bkp_gw_mac, + { "Backup Gateway MAC Address", + "ipmi.lan15.bkp_gw_mac", FT_ETHER, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan16_comm_string, + { "Community String", + "ipmi.lan16.comm_string", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan17_num_dst, + { "Number of Destinations", + "ipmi.lan17.num_dst", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + + { &hf_ipmi_trn_lan18_dst_selector, + { "Destination Selector", + "ipmi.lan18.dst_selector", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_lan18_ack, + { "Alert Acknowledged", + "ipmi.lan18.ack", FT_BOOLEAN, 8, TFS(&lan18_ack_tfs), 0x80, "", HFILL }}, + { &hf_ipmi_trn_lan18_dst_type, + { "Destination Type", + "ipmi.lan18.dst_type", FT_UINT8, BASE_HEX, lan18_dst_type_vals, 0x07, "", HFILL }}, + { &hf_ipmi_trn_lan18_tout, + { "Timeout/Retry Interval", + "ipmi.lan18.tout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_0based, 0, "", HFILL }}, + { &hf_ipmi_trn_lan18_retries, + { "Retries", + "ipmi.lan18.retries", FT_UINT8, BASE_DEC, NULL, 0x07, "", HFILL }}, + + { &hf_ipmi_trn_lan19_dst_selector, + { "Destination Selector", + "ipmi.lan19.dst_selector", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_lan19_addr_format, + { "Address Format", + "ipmi.lan19.addr_format", FT_UINT8, BASE_HEX, lan19_af_vals, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_lan19_address, + { "Address (format unknown)", + "ipmi.lan19.address", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_lan19_gw_sel, + { "Gateway selector", + "ipmi.lan19.gw_sel", FT_BOOLEAN, 8, TFS(&lan19_gw_sel_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_lan19_ip, + { "Alerting IP Address", + "ipmi.lan19.ip", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_lan19_mac, + { "Alerting MAC Address", + "ipmi.lan19.mac", FT_ETHER, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan20_vlan_id_enable, + { "VLAN ID Enable", + "ipmi.lan20.vlan_id_enable", FT_BOOLEAN, 16, TFS(&lan20_enable_tfs), 0x8000, "", HFILL }}, + { &hf_ipmi_trn_lan20_vlan_id, + { "VLAN ID", + "ipmi.lan20.vlan_id", FT_UINT16, BASE_HEX, NULL, 0x0fff, "", HFILL }}, + + { &hf_ipmi_trn_lan21_vlan_prio, + { "VLAN Priority", + "ipmi.lan21.vlan_prio", FT_UINT8, BASE_DEC, NULL, 0x07, "", HFILL }}, + + { &hf_ipmi_trn_lan22_num_cs_entries, + { "Number of Cipher Suite Entries", + "ipmi.lan22.num_cs_entries", FT_UINT8, BASE_DEC, NULL, 0x1f, "", HFILL }}, + + { &hf_ipmi_trn_lan23_cs_entry, + { "Cipher Suite ID", + "ipmi.lan23.cs_entry", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan24_priv, + { "Maximum Privilege Level", + "ipmi.lan24.priv", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_lan25_dst_selector, + { "Destination Selector", + "ipmi.lan25.dst_selector", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_lan25_addr_format, + { "Address Format", + "ipmi.lan25.addr_format", FT_UINT8, BASE_HEX, lan25_af_vals, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_lan25_address, + { "Address (format unknown)", + "ipmi.lan25.address", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_lan25_uprio, + { "User priority", + "ipmi.lan25.uprio", FT_UINT16, BASE_DEC, NULL, 0xe000, "", HFILL }}, + { &hf_ipmi_trn_lan25_cfi, + { "CFI", + "ipmi.lan25.cfi", FT_BOOLEAN, 16, NULL, 0x1000, "", HFILL }}, + { &hf_ipmi_trn_lan25_vlan_id, + { "VLAN ID", + "ipmi.lan25.vlan_id", FT_UINT16, BASE_HEX, NULL, 0x0fff, "", HFILL }}, + + { &hf_ipmi_trn_serial03_connmode, + { "Connection Mode", + "ipmi.serial03.connmode", FT_BOOLEAN, 8, TFS(&serial03_connmode_tfs), 0x80, "", HFILL }}, + { &hf_ipmi_trn_serial03_terminal, + { "Terminal Mode", + "ipmi.serial03.terminal", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial03_ppp, + { "PPP Mode", + "ipmi.serial03.ppp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial03_basic, + { "Basic Mode", + "ipmi.serial03.basic", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial04_timeout, + { "Session Inactivity Timeout", + "ipmi.serial04.timeout", FT_UINT8, BASE_CUSTOM, serial04_timeout_fmt, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial05_cbcp_callback, + { "CBCP Callback", + "ipmi.serial05.cbcp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial05_ipmi_callback, + { "IPMI Callback", + "ipmi.serial05.ipmi", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_list, + { "Callback to list of possible numbers", + "ipmi.serial05.cb_list", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_user, + { "Callback to user-specifiable number", + "ipmi.serial05.cb_user", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_prespec, + { "Callback to pre-specified number", + "ipmi.serial05.cb_prespec", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial05_no_cb, + { "No callback", + "ipmi.serial05.no_cb", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_dest1, + { "Callback destination 1", + "ipmi.serial05.cb_dest1", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_dest2, + { "Callback destination 2", + "ipmi.serial05.cb_dest2", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial05_cb_dest3, + { "Callback destination 3", + "ipmi.serial05.cb_dest3", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial06_inactivity, + { "Session Inactivity Timeout", + "ipmi.serial06.inactivity", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial06_dcd, + { "Close on DCD Loss", + "ipmi.serial06.dcd", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial07_flowctl, + { "Flow Control", + "ipmi.serial07.flowctl", FT_UINT8, BASE_HEX, serialXX_flowctl_vals, 0xc0, "", HFILL }}, + { &hf_ipmi_trn_serial07_dtrhangup, + { "DTR Hang-up", + "ipmi.serial07.dtrhangup", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_trn_serial07_bitrate, + { "Bit rate", + "ipmi.serial07.bitrate", FT_UINT8, BASE_HEX, serialXX_bitrate_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial08_esc_powerup, + { "Power-up/wakeup via ESC-^", + "ipmi.serial08.esc_powerup", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x40, "", HFILL }}, + { &hf_ipmi_trn_serial08_esc_reset, + { "Hard reset via ESC-R-ESC-r-ESC-R", + "ipmi.serial08.esc_reset", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_trn_serial08_switch_authcap, + { "Baseboard-to-BMC switch on Get Channel Auth Capabilities", + "ipmi.serial08.switch_authcap", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x10, "", HFILL }}, + { &hf_ipmi_trn_serial08_switch_rmcp, + { "Switch to BMC on IPMI-RMCP pattern", + "ipmi.serial08.switch_rmcp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_trn_serial08_esc_switch1, + { "BMC-to-Baseboard switch via ESC-Q", + "ipmi.serial08.esc_switch1", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial08_esc_switch2, + { "Baseboard-to-BMC switch via ESC-(", + "ipmi.serial08.esc_switch2", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial08_switch_dcdloss, + { "Switch to BMC on DCD loss", + "ipmi.serial08.switch_dcdloss", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial08_sharing, + { "Serial Port Sharing", + "ipmi.serial08.sharing", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_trn_serial08_ping_callback, + { "Serial/Modem Connection Active during callback", + "ipmi.serial08.ping_callback", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial08_ping_direct, + { "Serial/Modem Connection Active during direct call", + "ipmi.serial08.ping_direct", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial08_ping_retry, + { "Retry Serial/Modem Connection Active", + "ipmi.serial08.ping_retry", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial09_ring_duration, + { "Ring Duration", + "ipmi.serial09.ring_duration", FT_UINT8, BASE_CUSTOM, ipmi_fmt_500ms_1based, 0x3f, "", HFILL }}, + { &hf_ipmi_trn_serial09_ring_dead, + { "Ring Dead Time", + "ipmi.serial09.ring_dead", FT_UINT8, BASE_CUSTOM, ipmi_fmt_500ms_0based, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial10_set_sel, + { "Set selector (16-byte block #)", + "ipmi.serial10.set_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial10_init_str, + { "Modem Init String", + "ipmi.serial10.init_str", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial11_esc_seq, + { "Modem Escape Sequence", + "ipmi.serial11.esc_seq", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial12_hangup_seq, + { "Modem Hang-up Sequence", + "ipmi.serial12.hangup_seq", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial13_dial_cmd, + { "Modem Dial Command", + "ipmi.serial13.dial_cmd", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial14_page_blackout, + { "Page Blackout Interval (minutes)", + "ipmi.serial14.page_blackout", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial15_comm_string, + { "Community String", + "ipmi.serial15.comm_string", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial16_ndest, + { "Number of non-volatile Alert Destinations", + "ipmi.serial16.ndest", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial17_dest_sel, + { "Destination Selector", + "ipmi.serial17.dest_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial17_ack, + { "Alert Acknowledge", + "ipmi.serial17.ack", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_trn_serial17_dest_type, + { "Destination Type", + "ipmi.serial17.dest_type", FT_UINT8, BASE_HEX, serial17_dest_type_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial17_ack_timeout, + { "Alert Acknowledge Timeout", + "ipmi.serial17.ack_timeout", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial17_alert_retries, + { "Alert retries", + "ipmi.serial17.alert_retries", FT_UINT8, BASE_DEC, NULL, 0x70, "", HFILL }}, + { &hf_ipmi_trn_serial17_call_retries, + { "Call retries", + "ipmi.serial17.call_retries", FT_UINT8, BASE_DEC, NULL, 0x07, "", HFILL }}, + { &hf_ipmi_trn_serial17_alert_ack_timeout, + { "Alert Acknowledge Timeout", + "ipmi.serial17.alert_ack_timeout", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_0based, 0, "", HFILL }}, + { &hf_ipmi_trn_serial17_dialstr_sel, + { "Dial String Selector", + "ipmi.serial17.dialstr_sel", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial17_tap_sel, + { "TAP Account Selector", + "ipmi.serial17.tap_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial17_ipaddr_sel, + { "Destination IP Address Selector", + "ipmi.serial17.ipaddr_sel", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial17_ppp_sel, + { "PPP Account Set Selector", + "ipmi.serial17.ppp_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial17_unknown, + { "Destination-specific (format unknown)", + "ipmi.serial17.unknown", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial18_call_retry, + { "Call Retry Interval", + "ipmi.serial18.call_retry", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial19_destsel, + { "Destination selector", + "ipmi.serial19.destsel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial19_flowctl, + { "Flow Control", + "ipmi.serial19.flowctl", FT_UINT8, BASE_HEX, serialXX_flowctl_vals, 0xc0, "", HFILL }}, + { &hf_ipmi_trn_serial19_dtrhangup, + { "DTR Hang-up", + "ipmi.serial19.dtrhangup", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_trn_serial19_stopbits, + { "Stop bits", + "ipmi.serial19.stopbits", FT_BOOLEAN, 8, TFS(&serial19_stopbits_tfs), 0x10, "", HFILL }}, + { &hf_ipmi_trn_serial19_charsize, + { "Character size", + "ipmi.serial19.charsize", FT_BOOLEAN, 8, TFS(&serial19_charsize_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_trn_serial19_parity, + { "Parity", + "ipmi.serial19.parity", FT_UINT8, BASE_HEX, serial19_parity_vals, 0x07, "", HFILL }}, + { &hf_ipmi_trn_serial19_bitrate, + { "Bit rate", + "ipmi.serial19.bitrate", FT_UINT8, BASE_HEX, serialXX_bitrate_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial20_num_dial_strings, + { "Number of Dial Strings", + "ipmi.serial20.num_dial_strings", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial21_dialsel, + { "Dial String Selector", + "ipmi.serial21.dialsel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial21_blockno, + { "Block number", + "ipmi.serial21.blockno", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial21_dialstr, + { "Dial string", + "ipmi.serial21.dialstr", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial22_num_ipaddrs, + { "Number of Alert Destination IP Addresses", + "ipmi.serial22.num_ipaddrs", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial23_destsel, + { "Destination IP Address selector", + "ipmi.serial23.destsel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial23_ipaddr, + { "Destination IP Address", + "ipmi.serial23.ipaddr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial24_num_tap_accounts, + { "Number of TAP Accounts", + "ipmi.serial24.num_tap_accounts", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial25_tap_acct, + { "TAP Account Selector", + "ipmi.serial25.tap_acct", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial25_dialstr_sel, + { "Dial String Selector", + "ipmi.serial25.dialstr_sel", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial25_tapsrv_sel, + { "TAP Service Settings Selector", + "ipmi.serial25.tapsrv_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial26_tap_acct, + { "TAP Account Selector", + "ipmi.serial26.tap_acct", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial26_tap_passwd, + { "TAP Password", + "ipmi.serial26.tap_passwd", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial27_tap_acct, + { "TAP Account Selector", + "ipmi.serial27.tap_acct", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial27_tap_pager_id, + { "TAP Pager ID String", + "ipmi.serial27.tap_pager_id", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial28_tapsrv_sel, + { "TAP Service Settings Selector", + "ipmi.serial28.tapsrv_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial28_confirm, + { "TAP Confirmation", + "ipmi.serial28.confirm", FT_UINT8, BASE_HEX, serial28_confirm_vals, 0x03, "", HFILL }}, + { &hf_ipmi_trn_serial28_srvtype, + { "TAP 'SST' Service Type", + "ipmi.serial28.srvtype", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial28_ctrl_esc, + { "TAP Control-character escaping mask", + "ipmi.serial28.ctrl_esc", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial28_t2, + { "TAP T2", + "ipmi.serial28.tap_t2", FT_UINT8, BASE_CUSTOM, ipmi_fmt_500ms_0based, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial28_t1, + { "TAP T1", + "ipmi.serial28.tap_t1", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_0based, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial28_t4, + { "TAP T4", + "ipmi.serial28.tap_t4", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_0based, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial28_t3, + { "TAP T3", + "ipmi.serial28.tap_t3", FT_UINT8, BASE_CUSTOM, ipmi_fmt_2s_0based, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial28_t6, + { "IPMI T6", + "ipmi.serial28.ipmi_t6", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_0based, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial28_t5, + { "TAP T5", + "ipmi.serial28.tap_t5", FT_UINT8, BASE_CUSTOM, ipmi_fmt_2s_0based, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial28_n2, + { "TAP N2", + "ipmi.serial28.tap_n2", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial28_n1, + { "TAP N1", + "ipmi.serial28.tap_n1", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial28_n4, + { "IPMI N4", + "ipmi.serial28.ipmi_n4", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial28_n3, + { "TAP N3", + "ipmi.serial28.tap_n3", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial29_op, + { "Parameter Operation", + "ipmi.serial29.op", FT_UINT8, BASE_HEX, serial29_op_vals, 0xc0, "", HFILL }}, + { &hf_ipmi_trn_serial29_lineedit, + { "Line Editing", + "ipmi.serial29.lineedit", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x20, "", HFILL }}, + { &hf_ipmi_trn_serial29_deletectl, + { "Delete control", + "ipmi.serial29.deletectl", FT_UINT8, BASE_HEX, serial29_delete_vals, 0x0c, "", HFILL }}, + { &hf_ipmi_trn_serial29_echo, + { "Echo", + "ipmi.serial29.echo", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial29_handshake, + { "Handshake", + "ipmi.serial29.handshake", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial29_o_newline, + { "Output newline sequence", + "ipmi.serial29.o_newline", FT_UINT8, BASE_HEX, serial29_o_nl_vals, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial29_i_newline, + { "Input newline sequence", + "ipmi.serial29.i_newline", FT_UINT8, BASE_HEX, serial29_i_nl_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial30_snooping, + { "System Negotiation Snooping", + "ipmi.serial30.snooping", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial30_snoopctl, + { "Snoop ACCM Control", + "ipmi.serial30.snoopctl", FT_UINT8, BASE_HEX, serial30_snoopctl_vals, 0x03, "", HFILL }}, + { &hf_ipmi_trn_serial30_negot_ctl, + { "BMC negotiates link parameters", + "ipmi.serial30.negot_ctl", FT_UINT8, BASE_HEX, serial30_negoctl_vals, 0x30, "", HFILL }}, + { &hf_ipmi_trn_serial30_use_xmit_accm, + { "Filtering incoming chars", + "ipmi.serial30.filter", FT_BOOLEAN, 8, TFS(&serial30_filter_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial30_xmit_addr_comp, + { "Transmit with Address and Ctl Field Compression", + "ipmi.serial30.xmit_addr_comp", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial30_xmit_proto_comp, + { "Transmit with Protocol Field Compression", + "ipmi.serial30.xmit_proto_comp", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial30_ipaddr, + { "IP Address negotiation", + "ipmi.serial30.ipaddr", FT_UINT8, BASE_HEX, serial30_ipaddr_val, 0x18, "", HFILL }}, + { &hf_ipmi_trn_serial30_accm, + { "ACCM Negotiation", + "ipmi.serial30.accm", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial30_addr_comp, + { "Address and Ctl Field Compression", + "ipmi.serial30.addr_comp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial30_proto_comp, + { "Protocol Field Compression", + "ipmi.serial30.proto_comp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial31_port, + { "Primary RMCP Port Number", + "ipmi.serial31.port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + { &hf_ipmi_trn_serial32_port, + { "Secondary RMCP Port Number", + "ipmi.serial32.port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + { &hf_ipmi_trn_serial33_auth_proto, + { "PPP Link Authentication Protocol", + "ipmi.serial33.auth_proto", FT_UINT8, BASE_HEX, serialXX_proto_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial34_chap_name, + { "CHAP Name", + "ipmi.serial34.chap_name", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial35_recv_accm, + { "Receive ACCM", + "ipmi.serial35.recv_accm", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial35_xmit_accm, + { "Transmit ACCM", + "ipmi.serial35.xmit_accm", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial36_snoop_accm, + { "Snoop Receive ACCM", + "ipmi.serial36.snoop_accm", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial37_num_ppp, + { "Number of PPP Accounts", + "ipmi.serial37.num_ppp", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial38_acct_sel, + { "PPP Account Selector", + "ipmi.serial38.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial38_dialstr_sel, + { "Dial String Selector", + "ipmi.serial38.dialstr_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial39_acct_sel, + { "PPP Account Selector", + "ipmi.serial39.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial39_ipaddr, + { "IP Address", + "ipmi.serial39.ipaddr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial40_acct_sel, + { "PPP Account Selector", + "ipmi.serial40.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial40_username, + { "User Name", + "ipmi.serial40.username", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial41_acct_sel, + { "PPP Account Selector", + "ipmi.serial41.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial41_userdomain, + { "User Domain", + "ipmi.serial41.userdomain", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial42_acct_sel, + { "PPP Account Selector", + "ipmi.serial42.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial42_userpass, + { "User Password", + "ipmi.serial42.userpass", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial43_acct_sel, + { "PPP Account Selector", + "ipmi.serial43.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial43_auth_proto, + { "Link Auth Type", + "ipmi.serial43.auth_proto", FT_UINT8, BASE_HEX, serialXX_proto_vals, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial44_acct_sel, + { "PPP Account Selector", + "ipmi.serial44.acct_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial44_hold_time, + { "Connection Hold Time", + "ipmi.serial44.hold_time", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }}, + { &hf_ipmi_trn_serial45_src_ipaddr, + { "Source IP Address", + "ipmi.serial45.src_ipaddr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial45_dst_ipaddr, + { "Destination IP Address", + "ipmi.serial45.dst_ipaddr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial46_tx_bufsize, + { "Transmit Buffer Size", + "ipmi.serial46.tx_size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial47_rx_bufsize, + { "Receive Buffer Size", + "ipmi.serial47.rx_size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial48_ipaddr, + { "Remote Console IP Address", + "ipmi.serial48.ipaddr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial49_blockno, + { "Block number", + "ipmi.serial49.blockno", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial49_dialstr, + { "Dial string", + "ipmi.serial49.dialstr", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial50_115200, + { "115200", + "ipmi.serial50.115200", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_ipmi_trn_serial50_57600, + { "57600", + "ipmi.serial50.57600", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_trn_serial50_38400, + { "38400", + "ipmi.serial50.38400", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_trn_serial50_19200, + { "19200", + "ipmi.serial50.19200", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_ipmi_trn_serial50_9600, + { "9600", + "ipmi.serial50.9600", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_ipmi_trn_serial51_port_assoc_sel, + { "Serial Port Association Entry", + "ipmi.serial51.port_assoc_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial51_ipmi_channel, + { "IPMI Channel", + "ipmi.serial51.ipmi_channel", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_serial51_conn_num, + { "Connector number", + "ipmi.serial51.conn_num", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial51_ipmi_sharing, + { "Used with IPMI Serial Port Sharing", + "ipmi.serial51.ipmi_sharing", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_trn_serial51_ipmi_sol, + { "Used with IPMI Serial-over-LAN", + "ipmi.serial51.ipmi_sol", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_ipmi_trn_serial51_chan_num, + { "Serial controller channel number", + "ipmi.serial51.chan_num", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_serial52_port_assoc_sel, + { "Serial Port Association Entry", + "ipmi.serial52.port_assoc_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial52_conn_name, + { "Connector Name", + "ipmi.serial52_conn_name", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial53_port_assoc_sel, + { "Serial Port Association Entry", + "ipmi.serial53.port_assoc_sel", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_serial53_chan_name, + { "Channel Name", + "ipmi.serial52_chan_name", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_01_chan, + { "Channel", + "ipmi.tr01.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_01_param, + { "Parameter Selector", + "ipmi.tr01.param", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_01_param_data, + { "Parameter data", + "ipmi.tr01.param_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_02_getrev, + { "Get parameter revision only", + "ipmi.tr02.getrev", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_trn_02_chan, + { "Channel", + "ipmi.tr02.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_02_param, + { "Parameter selector", + "ipmi.tr02.param", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_02_set, + { "Set selector", + "ipmi.tr02.set", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_02_block, + { "Block selector", + "ipmi.tr02.block", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_02_rev_present, + { "Present parameter revision", + "ipmi.tr02.rev.present", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_02_rev_compat, + { "Oldest forward-compatible", + "ipmi.tr02.rev.compat", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_02_param_data, + { "Parameter data", + "ipmi.tr02.param_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_03_chan, + { "Channel", + "ipmi.tr03.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_03_arp_resp, + { "BMC-generated ARP responses", + "ipmi.tr03.arp_resp", FT_BOOLEAN, 8, TFS(&tfs_03_suspend), 0x02, "", HFILL }}, + { &hf_ipmi_trn_03_gratuitous_arp, + { "Gratuitous ARPs", + "ipmi.tr03.gratuitous_arp", FT_BOOLEAN, 8, TFS(&tfs_03_suspend), 0x01, "", HFILL }}, + { &hf_ipmi_trn_03_status_arp_resp, + { "ARP Response status", + "ipmi.tr03.status_arp_resp", FT_BOOLEAN, 8, TFS(&tfs_03_arp_status), 0x02, "", HFILL }}, + { &hf_ipmi_trn_03_status_gratuitous_arp, + { "Gratuitous ARP status", + "ipmi.tr03.status_gratuitous_arp", FT_BOOLEAN, 8, TFS(&tfs_03_arp_status), 0x01, "", HFILL }}, + + { &hf_ipmi_trn_04_chan, + { "Channel", + "ipmi.tr04.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_04_clear, + { "Statistics", + "ipmi.tr04.clear", FT_BOOLEAN, 8, TFS(&tfs_04_clear), 0x01, "", HFILL }}, + { &hf_ipmi_trn_04_rx_ippkts, + { "Received IP Packets", + "ipmi.tr04.rx_ippkts", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_iphdr_err, + { "Received IP Header Errors", + "ipmi.tr04.rx_iphdr_err", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_ipaddr_err, + { "Received IP Address Errors", + "ipmi.tr04.rx_ipaddr_err", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_ippkts_frag, + { "Received Fragmented IP Packets", + "ipmi.tr04.rx_ippkts_frag", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_tx_ippkts, + { "Transmitted IP Packets", + "ipmi.tr04.tx_ippkts", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_udppkts, + { "Received UDP Packets", + "ipmi.tr04.rx_udppkts", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_validrmcp, + { "Received Valid RMCP Packets", + "ipmi.tr04.rx_validrmcp", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_rx_udpproxy, + { "Received UDP Proxy Packets", + "ipmi.tr04.rx_udpproxy", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_04_dr_udpproxy, + { "Dropped UDP Proxy Packets", + "ipmi.tr04.dr_udpproxy", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_10_chan, + { "Channel", + "ipmi.tr10.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_10_param, + { "Parameter Selector", + "ipmi.tr10.param", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_10_param_data, + { "Parameter data", + "ipmi.tr10.param_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_11_getrev, + { "Get parameter revision only", + "ipmi.tr11.getrev", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_trn_11_chan, + { "Channel", + "ipmi.tr11.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_11_param, + { "Parameter selector", + "ipmi.tr11.param", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_11_set, + { "Set selector", + "ipmi.tr11.set", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_11_block, + { "Block selector", + "ipmi.tr11.block", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_11_rev_present, + { "Present parameter revision", + "ipmi.tr11.rev.present", FT_UINT8, BASE_DEC, NULL, 0xf0, "", HFILL }}, + { &hf_ipmi_trn_11_rev_compat, + { "Oldest forward-compatible", + "ipmi.tr11.rev.compat", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_11_param_data, + { "Parameter data", + "ipmi.tr11.param_data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_12_chan, + { "Channel", + "ipmi.tr12.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_12_mux_setting, + { "Mux Setting", + "ipmi.tr12.mux_setting", FT_UINT8, BASE_HEX, vals_12_mux, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_12_sw_to_sys, + { "Requests to switch to system", + "ipmi.tr12.sw_to_sys", FT_BOOLEAN, 8, TFS(&tfs_12_blocked), 0x80, "", HFILL }}, + { &hf_ipmi_trn_12_sw_to_bmc, + { "Requests to switch to BMC", + "ipmi.tr12.sw_to_bmc", FT_BOOLEAN, 8, TFS(&tfs_12_blocked), 0x40, "", HFILL }}, + { &hf_ipmi_trn_12_alert, + { "Alert in progress", + "ipmi.tr12.alert", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_ipmi_trn_12_msg, + { "IPMI/OEM messaging active", + "ipmi.tr12.msg", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_ipmi_trn_12_req, + { "Request", + "ipmi.tr12.req", FT_BOOLEAN, 8, TFS(&tfs_12_req), 0x02, "", HFILL }}, + { &hf_ipmi_trn_12_mux_state, + { "Mux set to", + "ipmi.tr12.mux_state", FT_BOOLEAN, 8, TFS(&tfs_12_mux_state), 0x01, "", HFILL }}, + + { &hf_ipmi_trn_13_chan, + { "Channel", + "ipmi.tr13.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_13_code1, + { "Last code", + "ipmi.tr13.code1", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_13_code2, + { "2nd code", + "ipmi.tr13.code2", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_13_code3, + { "3rd code", + "ipmi.tr13.code3", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_13_code4, + { "4th code", + "ipmi.tr13.code4", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_13_code5, + { "5th code", + "ipmi.tr13.code5", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_14_chan, + { "Channel", + "ipmi.tr14.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_14_block, + { "Block number", + "ipmi.tr14.block", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_14_data, + { "Block data", + "ipmi.tr14.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_15_chan, + { "Channel", + "ipmi.tr15.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_15_block, + { "Block number", + "ipmi.tr15.block", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_15_data, + { "Block data", + "ipmi.tr15.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_16_chan, + { "Channel", + "ipmi.tr16.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_16_src_port, + { "Source Port", + "ipmi.tr16.src_port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + { &hf_ipmi_trn_16_dst_port, + { "Destination Port", + "ipmi.tr16.dst_port", FT_UINT16, BASE_CUSTOM, ipmi_fmt_udpport, 0, "", HFILL }}, + { &hf_ipmi_trn_16_src_addr, + { "Source IP Address", + "ipmi.tr16.src_addr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_16_dst_addr, + { "Destination IP Address", + "ipmi.tr16.dst_addr", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_16_bytes, + { "Bytes to send", + "ipmi.tr16.bytes", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_17_chan, + { "Channel", + "ipmi.tr17.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_17_clear, + { "Clear buffer", + "ipmi.tr17.clear", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_ipmi_trn_17_block_num, + { "Block number", + "ipmi.tr17.block_num", FT_UINT8, BASE_CUSTOM, tr17_fmt_blockno, 0x7f, "", HFILL }}, + { &hf_ipmi_trn_17_size, + { "Number of received bytes", + "ipmi.tr17.size", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_17_data, + { "Block Data", + "ipmi.tr17.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_18_state, + { "Session state", + "ipmi.tr18.state", FT_UINT8, BASE_HEX, vals_18_state, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_18_ipmi_ver, + { "IPMI Version", + "ipmi.tr18.ipmi_ver", FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, "", HFILL }}, + + { &hf_ipmi_trn_19_chan, + { "Channel", + "ipmi.tr19.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + { &hf_ipmi_trn_19_dest_sel, + { "Destination selector", + "ipmi.tr19.dest_sel", FT_UINT8, BASE_DEC, NULL, 0x0f, "", HFILL }}, + + { &hf_ipmi_trn_XX_cap_cbcp, + { "CBCP callback", + "ipmi.trXX.cap_cbcp", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_XX_cap_ipmi, + { "IPMI callback", + "ipmi.trXX.cap_ipmi", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_XX_cbcp_from_list, + { "Callback to one from list of numbers", + "ipmi.trXX.cbcp_from_list", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x08, "", HFILL }}, + { &hf_ipmi_trn_XX_cbcp_user, + { "Callback to user-specified number", + "ipmi.trXX.cbcp_user", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x04, "", HFILL }}, + { &hf_ipmi_trn_XX_cbcp_prespec, + { "Callback to pre-specified number", + "ipmi.trXX.cbcp_prespec", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x02, "", HFILL }}, + { &hf_ipmi_trn_XX_cbcp_nocb, + { "No callback", + "ipmi.trXX.cbcp_nocb", FT_BOOLEAN, 8, TFS(&enabled_tfs), 0x01, "", HFILL }}, + { &hf_ipmi_trn_XX_dst1, + { "Callback destination 1", + "ipmi.trXX.dst1", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_XX_dst2, + { "Callback destination 2", + "ipmi.trXX.dst2", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + { &hf_ipmi_trn_XX_dst3, + { "Callback destination 3", + "ipmi.trXX.dst3", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }}, + + { &hf_ipmi_trn_1a_user, + { "User ID", + "ipmi.tr1a.user", FT_UINT8, BASE_DEC, NULL, 0x3f, "", HFILL }}, + { &hf_ipmi_trn_1a_chan, + { "Channel", + "ipmi.tr1a.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + + { &hf_ipmi_trn_1b_user, + { "User ID", + "ipmi.tr1b.user", FT_UINT8, BASE_DEC, NULL, 0x3f, "", HFILL }}, + { &hf_ipmi_trn_1b_chan, + { "Channel", + "ipmi.tr1b.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, "", HFILL }}, + + }; + static gint *ett[] = { + &ett_ipmi_trn_lan00_byte1, + &ett_ipmi_trn_lan01_byte1, + &ett_ipmi_trn_lan02_byte1, + &ett_ipmi_trn_lan02_byte2, + &ett_ipmi_trn_lan02_byte3, + &ett_ipmi_trn_lan02_byte4, + &ett_ipmi_trn_lan02_byte5, + &ett_ipmi_trn_lan04_byte1, + &ett_ipmi_trn_lan07_byte2, + &ett_ipmi_trn_lan07_byte3, + &ett_ipmi_trn_lan10_byte1, + &ett_ipmi_trn_lan17_byte1, + &ett_ipmi_trn_lan18_byte1, + &ett_ipmi_trn_lan18_byte2, + &ett_ipmi_trn_lan18_byte4, + &ett_ipmi_trn_lan19_byte1, + &ett_ipmi_trn_lan19_byte2, + &ett_ipmi_trn_lan19_byte3, + &ett_ipmi_trn_lan20_byte12, + &ett_ipmi_trn_lan21_byte1, + &ett_ipmi_trn_lan22_byte1, + &ett_ipmi_trn_lan24_byte1, + &ett_ipmi_trn_lan24_byte2, + &ett_ipmi_trn_lan24_byte3, + &ett_ipmi_trn_lan24_byte4, + &ett_ipmi_trn_lan24_byte5, + &ett_ipmi_trn_lan24_byte6, + &ett_ipmi_trn_lan24_byte7, + &ett_ipmi_trn_lan24_byte8, + &ett_ipmi_trn_lan25_byte1, + &ett_ipmi_trn_lan25_byte2, + &ett_ipmi_trn_lan25_byte34, + &ett_ipmi_trn_serial03_byte1, + &ett_ipmi_trn_serial04_byte1, + &ett_ipmi_trn_serial05_byte1, + &ett_ipmi_trn_serial05_byte2, + &ett_ipmi_trn_serial06_byte1, + &ett_ipmi_trn_serial07_byte1, + &ett_ipmi_trn_serial07_byte2, + &ett_ipmi_trn_serial08_byte1, + &ett_ipmi_trn_serial08_byte2, + &ett_ipmi_trn_serial09_byte1, + &ett_ipmi_trn_serial09_byte2, + &ett_ipmi_trn_serial16_byte1, + &ett_ipmi_trn_serial17_byte1, + &ett_ipmi_trn_serial17_byte2, + &ett_ipmi_trn_serial17_byte4, + &ett_ipmi_trn_serial17_byte5, + &ett_ipmi_trn_serial19_byte1, + &ett_ipmi_trn_serial19_byte2, + &ett_ipmi_trn_serial19_byte3, + &ett_ipmi_trn_serial20_byte1, + &ett_ipmi_trn_serial21_byte1, + &ett_ipmi_trn_serial22_byte1, + &ett_ipmi_trn_serial23_byte1, + &ett_ipmi_trn_serial24_byte1, + &ett_ipmi_trn_serial25_byte2, + &ett_ipmi_trn_serial28_byte1, + &ett_ipmi_trn_serial28_byte2, + &ett_ipmi_trn_serial28_byte10, + &ett_ipmi_trn_serial28_byte11, + &ett_ipmi_trn_serial28_byte12, + &ett_ipmi_trn_serial28_byte13, + &ett_ipmi_trn_serial28_byte14, + &ett_ipmi_trn_serial29_byte1, + &ett_ipmi_trn_serial29_byte2, + &ett_ipmi_trn_serial30_byte1, + &ett_ipmi_trn_serial30_byte2, + &ett_ipmi_trn_serial30_byte3, + &ett_ipmi_trn_serial33_byte1, + &ett_ipmi_trn_serial37_byte1, + &ett_ipmi_trn_serial43_byte1, + &ett_ipmi_trn_serial50_byte1, + &ett_ipmi_trn_serial51_byte2, + &ett_ipmi_trn_serial51_byte3, + &ett_ipmi_trn_01_byte1, + &ett_ipmi_trn_02_byte1, + &ett_ipmi_trn_02_rev, + &ett_ipmi_trn_03_rq_byte1, + &ett_ipmi_trn_03_rq_byte2, + &ett_ipmi_trn_03_rs_byte1, + &ett_ipmi_trn_04_byte1, + &ett_ipmi_trn_04_byte2, + &ett_ipmi_trn_10_byte1, + &ett_ipmi_trn_11_byte1, + &ett_ipmi_trn_11_rev, + &ett_ipmi_trn_12_rq_byte1, + &ett_ipmi_trn_12_rq_byte2, + &ett_ipmi_trn_12_rs_byte1, + &ett_ipmi_trn_13_byte1, + &ett_ipmi_trn_14_byte1, + &ett_ipmi_trn_15_byte1, + &ett_ipmi_trn_16_byte1, + &ett_ipmi_trn_17_byte1, + &ett_ipmi_trn_17_byte2, + &ett_ipmi_trn_18_byte1, + &ett_ipmi_trn_19_byte1, + &ett_ipmi_trn_19_byte2, + &ett_ipmi_trn_XX_usercap, + &ett_ipmi_trn_XX_cbcp, + &ett_ipmi_trn_1a_byte1, + &ett_ipmi_trn_1a_byte2, + &ett_ipmi_trn_1b_byte1, + &ett_ipmi_trn_1b_byte2, + }; + + proto_register_field_array(proto_ipmi, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ipmi_register_netfn_cmdtab(IPMI_TRANSPORT_REQ, IPMI_OEM_NONE, NULL, 0, NULL, + cmd_transport, array_length(cmd_transport)); +} diff --git a/epan/dissectors/packet-ipmi-update.c b/epan/dissectors/packet-ipmi-update.c new file mode 100644 index 0000000000..d3d35760bb --- /dev/null +++ b/epan/dissectors/packet-ipmi-update.c @@ -0,0 +1,53 @@ +/* packet-ipmi-update.c + * Sub-dissectors for IPMI messages (netFn=Firmware Update, PPS-specific) + * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <epan/packet.h> + +#include "packet-ipmi.h" + +static ipmi_cmd_t cmd_update[] = { + { 0x00, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Status", 0 }, + { 0x01, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Start", 0 }, + { 0x02, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Prepare", 0 }, + { 0x03, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Write", 0 }, + { 0x04, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Complete", 0 }, + { 0x05, IPMI_TBD, NULL, NULL, "[PPS OEM] Restore Backup", 0 }, + { 0x06, IPMI_TBD, NULL, NULL, "[PPS OEM] Query Backup Version", 0 } +}; + +void +ipmi_register_update(gint proto_ipmi _U_) +{ + ipmi_register_netfn_cmdtab(IPMI_UPDATE_REQ, IPMI_OEM_PPS, NULL, 0, NULL, + cmd_update, array_length(cmd_update)); +} diff --git a/epan/dissectors/packet-ipmi.h b/epan/dissectors/packet-ipmi.h new file mode 100644 index 0000000000..88d84c4bb4 --- /dev/null +++ b/epan/dissectors/packet-ipmi.h @@ -0,0 +1,186 @@ +/* packet-ipmi.h + * Definitions for IPMI dissection + * Copyright 2002-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __PACKET_IPMI_H__ +#define __PACKET_IPMI_H__ + +/* IPMI definitions */ + +/* Max 32 netfn codes: 6 bits, of which 1 designates request/response */ +#define IPMI_NETFN_MAX 32 + +/* IPMI Network Function supported values. + */ +#define IPMI_CHASSIS_REQ 0x00 /* Chassis */ +#define IPMI_BRIDGE_REQ 0x02 /* Bridge */ +#define IPMI_SE_REQ 0x04 /* Sensor/Event */ +#define IPMI_APP_REQ 0x06 /* Application */ +#define IPMI_UPDATE_REQ 0x08 /* Firmware update */ +#define IPMI_STORAGE_REQ 0x0a /* Storage */ +#define IPMI_TRANSPORT_REQ 0x0c /* Transport */ +#define IPMI_GROUP_REQ 0x2c /* Group */ +#define IPMI_OEM_REQ 0x2e /* OEM */ + +/* Selector for dissecting OEM commands which do not carry OEM signatures. + * IPMI spec says these commands are to be specified by OEM and depend on + * the IANA number reported via Get Device ID. However, Wireshark has no + * means to guess that. Therefore, allow the user to select which OEM commands + * should be used. This applies to the following netFns: 0x08/0x09 (Update), + * 0x30..0x3f. Note that the commands which bear defining body signature + * (netFns 0x2c..0x2f) are registered with IPMI_OEM_NONE, as they can be + * recognized. */ +enum ipmi_oem_selector { + IPMI_OEM_NONE = 0, + IPMI_OEM_PPS /* Pigeon Point Systems extensions */ +}; + +/* IPMI header fields */ +struct ipmi_header { + guint8 trg_sa; + guint8 trg_lun; + guint8 src_sa; + guint8 src_lun; + guint8 netfn; + guint8 cmd; + guint8 seq; + guint8 ccode; + guint8 data_len; +}; + +extern struct ipmi_header *ipmi_current_hdr; + +/* Sub-parser */ +typedef void (*ipmi_cmd_handler_t)(tvbuff_t *, proto_tree *); + +/* IPMI command structure. */ +typedef struct { + guint32 cmd; /* Command number */ + ipmi_cmd_handler_t parse_req; /* Request parser */ + ipmi_cmd_handler_t parse_resp; /* Response parser */ + const value_string *cs_cc; /* Command-specific completion codes */ + const value_string *subfn; /* Subfunction codes */ + const char *desc; /* Command description */ + int flags; /* Command flags */ +} ipmi_cmd_t; + +/* Command flags */ +#define CMD_MAYBROADCAST 0x01 /* Command can be broadcast over IPMB */ +#define CMD_CALLRQ 0x02 /* Call request handler early to cache data */ +#define CMD_NEWCONV 0x04 /* This command starts new conversation */ + +void ipmi_setsaveddata(guint idx, guint32 val); +gboolean ipmi_getsaveddata(guint idx, guint32 *val); + +/* Top-level search structure: signatures (if any) + command table */ +typedef struct ipmi_netfn_handler { + struct ipmi_netfn_handler *next; + const char *desc; + enum ipmi_oem_selector oem_selector; + const guint8 *sig; + ipmi_cmd_t *cmdtab; + guint32 cmdtablen; +} ipmi_netfn_t; + +/* Handy wrapper around decode_bitfield_value() */ +char *ipmi_dcd8(guint32 val, guint32 mask); + +/* Stub parser. Use this to substitute for not-yet-written subparsers; + NULL in command table means 'no custom data in this request/response' */ +void ipmi_notimpl(tvbuff_t *tvb, proto_tree *tree); +#define IPMI_TBD ipmi_notimpl, ipmi_notimpl + +/* Add a Type/Length field to tree */ +void ipmi_add_typelen(proto_tree *tree, const char *desc, tvbuff_t *tvb, + guint offs, gboolean is_fru); + +/* Add Timestamp in IPMI format */ +void ipmi_add_timestamp(proto_tree *tree, gint hf, tvbuff_t *tvb, guint offset); + +/* GUID, IPMI style (fields reversed, little-endian) */ +void ipmi_add_guid(proto_tree *tree, gint hf, tvbuff_t *tvb, guint offset); + +/* Common format routines */ +void ipmi_fmt_10ms_1based(gchar *, guint32); +void ipmi_fmt_500ms_0based(gchar *, guint32); +void ipmi_fmt_500ms_1based(gchar *, guint32); +void ipmi_fmt_1s_0based(gchar *, guint32); +void ipmi_fmt_1s_1based(gchar *, guint32); +void ipmi_fmt_2s_0based(gchar *, guint32); +void ipmi_fmt_5s_1based(gchar *, guint32); +void ipmi_fmt_version(gchar *, guint32); +void ipmi_fmt_channel(gchar *, guint32); +void ipmi_fmt_udpport(gchar *, guint32); +void ipmi_fmt_percent(gchar *, guint32); + +/* Registrar for subparsers */ +void ipmi_register_netfn_cmdtab(guint32 netfn, enum ipmi_oem_selector oem_selector, + const guint8 *sig, guint32 siglen, const char *desc, + ipmi_cmd_t *cmdtab, guint32 cmdtablen); + +/* Lookup routines */ +guint32 ipmi_getsiglen(guint32 netfn); +const char *ipmi_getnetfnname(guint32 netfn, ipmi_netfn_t *nf); +ipmi_netfn_t *ipmi_getnetfn(guint32 netfn, const guint8 *sig); +ipmi_cmd_t *ipmi_getcmd(ipmi_netfn_t *nf, guint32 cmd); +const char *ipmi_get_completion_code(guint8 completion, ipmi_cmd_t *cmd); + +/* Sub-registrars (ipmi_*.c) */ +void ipmi_register_app(int proto); +void ipmi_register_bridge(int proto); +void ipmi_register_chassis(int proto); +void ipmi_register_picmg(int proto); +void ipmi_register_pps(int proto); +void ipmi_register_se(int proto); +void ipmi_register_storage(int proto); +void ipmi_register_transport(int proto); +void ipmi_register_update(int proto); + +/* Main dissection routine */ +#define IPMI_D_NONE 0x0001 /* Do not parse at all */ +#define IPMI_D_SESSION_HANDLE 0x0002 /* Session handle */ +#define IPMI_D_BROADCAST 0x0004 /* Check for broadcast message */ +#define IPMI_D_TRG_SA 0x0008 /* Target slave addr is present */ + +struct ipmi_reqresp; + +typedef struct { + guint32 flags; + gchar info[ITEM_LABEL_LENGTH]; + void *arg; /* Argument passed to callbacks */ + + /* Extra methods for requests that contain embedded commands */ + struct ipmi_header *(*getmoreheaders)(struct ipmi_header *base, void *arg, guint i); + int (*whichresponse)(struct ipmi_header *hdr, struct ipmi_reqresp *rr); + int (*otheridx)(struct ipmi_header *hdr); +} ipmi_dissect_format_t; + +int ipmi_guess_dissect_flags(tvbuff_t *tvb); +void ipmi_do_dissect(tvbuff_t *tvb, proto_tree *tree, ipmi_dissect_format_t *dfmt); + +struct ipmi_header *ipmi_sendmsg_getheaders(struct ipmi_header *base, void *arg, guint i); +int ipmi_sendmsg_whichresponse(struct ipmi_header *hdr, struct ipmi_reqresp *rr); +int ipmi_sendmsg_otheridx(struct ipmi_header *hdr); + +#endif |