aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/CMakeLists.txt2
-rw-r--r--epan/dissectors/Makefile.common4
-rw-r--r--epan/dissectors/packet-ipmi-app.c100
-rw-r--r--epan/dissectors/packet-ipmi-chassis.c25
-rw-r--r--epan/dissectors/packet-ipmi-picmg.c1602
-rw-r--r--epan/dissectors/packet-ipmi-pps.c119
-rw-r--r--epan/dissectors/packet-ipmi-se.c55
-rw-r--r--epan/dissectors/packet-ipmi-session.c8
-rw-r--r--epan/dissectors/packet-ipmi-storage.c24
-rwxr-xr-xepan/dissectors/packet-ipmi-trace.c479
-rw-r--r--epan/dissectors/packet-ipmi-transport.c74
-rwxr-xr-xepan/dissectors/packet-ipmi-vita.c1325
-rw-r--r--epan/dissectors/packet-ipmi.c1592
-rw-r--r--epan/dissectors/packet-ipmi.h97
14 files changed, 4583 insertions, 923 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index f6d69f5aed..7461dc1cbc 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -809,6 +809,7 @@ set(DISSECTOR_SRC
dissectors/packet-ipfc.c
dissectors/packet-ipmi-session.c
dissectors/packet-ipmi.c
+ dissectors/packet-ipmi-trace.c
dissectors/packet-ipnet.c
dissectors/packet-ipoib.c
dissectors/packet-ipp.c
@@ -1409,6 +1410,7 @@ set(IPMI_SUBPARSERS
dissectors/packet-ipmi-transport.c
dissectors/packet-ipmi-pps.c
dissectors/packet-ipmi-update.c
+ dissectors/packet-ipmi-vita.c
)
set(DISSECTOR_SUPPORT_SRC
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index 94ce213316..6d24559e13 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -729,6 +729,7 @@ DISSECTOR_SRC = \
packet-ipfc.c \
packet-ipmi-session.c \
packet-ipmi.c \
+ packet-ipmi-trace.c \
packet-ipnet.c \
packet-ipoib.c \
packet-ipp.c \
@@ -1713,7 +1714,8 @@ IPMI_SUBPARSERS = \
packet-ipmi-storage.c \
packet-ipmi-transport.c \
packet-ipmi-pps.c \
- packet-ipmi-update.c
+ packet-ipmi-update.c \
+ packet-ipmi-vita.c
# Dissector helpers. They're included in the source files in this
# directory, but they're not dissectors themselves, i.e. they're not
diff --git a/epan/dissectors/packet-ipmi-app.c b/epan/dissectors/packet-ipmi-app.c
index fffb526827..97b71bc93f 100644
--- a/epan/dissectors/packet-ipmi-app.c
+++ b/epan/dissectors/packet-ipmi-app.c
@@ -57,6 +57,8 @@ 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_33_rs_byte1 = -1;
+static gint ett_ipmi_app_33_msg = -1;
static gint ett_ipmi_app_34_byte1 = -1;
static gint ett_ipmi_app_34_msg = -1;
@@ -181,10 +183,15 @@ 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_33_rs_chan = -1;
+static gint hf_ipmi_app_33_rs_priv = -1;
+static gint hf_ipmi_app_33_msg = -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_34_msg = -1;
static gint hf_ipmi_app_38_rq_ipmi20 = -1;
static gint hf_ipmi_app_38_rq_chan = -1;
@@ -422,7 +429,7 @@ rs01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
&hf_ipmi_app_01_ipmi_ads_sensor, NULL };
size_t len;
- len = tvb_length(tvb);
+ len = tvb_captured_length(tvb);
proto_tree_add_item(tree, hf_ipmi_app_01_dev_id, tvb, 0, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_app_01_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
@@ -481,7 +488,7 @@ rs04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static void
rq05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- proto_tree_add_item(tree, hf_ipmi_app_05_devspec, tvb, 0, tvb_length(tvb), ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_app_05_devspec, tvb, 0, -1, ENC_NA);
}
/* Set ACPI Power State.
@@ -659,6 +666,29 @@ static const value_string cc33[] = {
{ 0, NULL }
};
+static void
+rs33(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint *byte1[] = { &hf_ipmi_app_33_rs_chan,
+ &hf_ipmi_app_33_rs_priv, NULL };
+ tvbuff_t *next;
+ ipmi_dissect_arg_t arg;
+
+ proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_app_33_rs_byte1,
+ byte1, ENC_LITTLE_ENDIAN, 0);
+
+ next = tvb_new_subset_remaining(tvb, 1);
+
+ arg.context = IPMI_E_GETMSG;
+ arg.channel = tvb_get_guint8(tvb, 0) & 0xF;
+ arg.flags = 0;
+
+ do_dissect_ipmb(next, pinfo, tree,
+ hf_ipmi_app_33_msg, ett_ipmi_app_33_msg, &arg);
+
+}
+
+
/* Send Message
*/
static void
@@ -666,43 +696,34 @@ rq34(tvbuff_t *tvb, packet_info *pinfo, 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;
+ ipmi_dissect_arg_t arg;
proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
ett_ipmi_app_34_byte1, byte1, ENC_LITTLE_ENDIAN, 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, pinfo, s_tree, &dfmt);
- proto_item_set_text(ti, "%s", dfmt.info);
+ next = tvb_new_subset_remaining(tvb, 1);
+
+ arg.context = IPMI_E_SENDMSG_RQ;
+ arg.channel = tvb_get_guint8(tvb, 0) & 0xF;
+ arg.flags = 0;
+
+ do_dissect_ipmb(next, pinfo, tree,
+ hf_ipmi_app_34_msg, ett_ipmi_app_34_msg, &arg);
}
static void
rs34(tvbuff_t *tvb, packet_info *pinfo, 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, pinfo, s_tree, &dfmt);
- proto_item_set_text(ti, "%s", dfmt.info);
+ if (tvb_captured_length(tvb)) {
+ ipmi_dissect_arg_t arg;
+
+ arg.context = IPMI_E_SENDMSG_RS;
+ arg.channel = 0;
+ arg.flags = 0;
+
+ do_dissect_ipmb(tvb, pinfo, tree,
+ hf_ipmi_app_34_msg, ett_ipmi_app_34_msg, &arg);
}
}
@@ -851,7 +872,7 @@ static void
rq3c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_app_3c_session_id, tvb, 0, 4, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 4) {
+ if (tvb_captured_length(tvb) > 4) {
proto_tree_add_item(tree, hf_ipmi_app_3c_session_handle, tvb, 4, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -953,7 +974,7 @@ static const value_string cc62[] = {
static ipmi_cmd_t cmd_app[] = {
/* IPM Device Global Commands */
- { 0x01, NULL, rs01, NULL, NULL, "Get Device ID", CMD_MAYBROADCAST },
+ { 0x01, NULL, rs01, NULL, NULL, "Get Device ID", 0 },
{ 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 },
@@ -978,7 +999,7 @@ static ipmi_cmd_t cmd_app[] = {
{ 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 },
+ { 0x33, NULL, rs33, cc33, NULL, "Get Message", CMD_CALLRQ },
{ 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 },
@@ -1313,6 +1334,16 @@ ipmi_register_app(gint proto_ipmi)
{ "Channel State",
"ipmi.app32.rs_state", FT_BOOLEAN, 8, TFS(&tfs_32_state), 0x01, NULL, HFILL }},
+ { &hf_ipmi_app_33_rs_chan,
+ { "Channel",
+ "ipmi.app33.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, NULL, HFILL }},
+ { &hf_ipmi_app_33_rs_priv,
+ { "Inferred privilege level",
+ "ipmi.app33.priv", FT_UINT8, BASE_HEX, VALS(vals_XX_priv), 0xf0, NULL, HFILL }},
+ { &hf_ipmi_app_33_msg,
+ { "Message data",
+ "ipmi.app33.msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
+
{ &hf_ipmi_app_34_track,
{ "Tracking",
"ipmi.app34.track", FT_UINT8, BASE_HEX, VALS(vals_34_track), 0xc0, NULL, HFILL }},
@@ -1325,6 +1356,9 @@ ipmi_register_app(gint proto_ipmi)
{ &hf_ipmi_app_34_chan,
{ "Channel",
"ipmi.app34.chan", FT_UINT8, BASE_CUSTOM, ipmi_fmt_channel, 0x0f, NULL, HFILL }},
+ { &hf_ipmi_app_34_msg,
+ { "Embedded message",
+ "ipmi.app34.msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_app_38_rq_ipmi20,
{ "Version compatibility",
@@ -1462,6 +1496,8 @@ ipmi_register_app(gint proto_ipmi)
&ett_ipmi_app_32_rq_byte2,
&ett_ipmi_app_32_rs_byte1,
&ett_ipmi_app_32_rs_byte2,
+ &ett_ipmi_app_33_rs_byte1,
+ &ett_ipmi_app_33_msg,
&ett_ipmi_app_34_byte1,
&ett_ipmi_app_34_msg,
&ett_ipmi_app_38_rq_byte1,
diff --git a/epan/dissectors/packet-ipmi-chassis.c b/epan/dissectors/packet-ipmi-chassis.c
index 2d8d85c5a6..98e9ed68b3 100644
--- a/epan/dissectors/packet-ipmi-chassis.c
+++ b/epan/dissectors/packet-ipmi-chassis.c
@@ -404,7 +404,7 @@ static void
bootopt_07(tvbuff_t *tvb, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_selector, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_data, tvb, 1, tvb_length(tvb) - 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_data, tvb, 1, -1, ENC_NA);
}
@@ -438,7 +438,7 @@ rs00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_chs_00_sel_dev_addr, tvb, 3, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_chs_00_sm_dev_addr, tvb, 4, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) >= 5) {
+ if (tvb_captured_length(tvb) >= 5) {
proto_tree_add_item(tree, hf_ipmi_chs_00_bridge_dev_addr, tvb, 5, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -470,7 +470,7 @@ rs01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ett_ipmi_chs_01_last_event, byte2, ENC_LITTLE_ENDIAN, 0);
proto_tree_add_bitmask_text(tree, tvb, 2, 1, "Misc. State: ", NULL,
ett_ipmi_chs_01_misc, byte3, ENC_LITTLE_ENDIAN, 0);
- if (tvb_length(tvb) > 3) {
+ if (tvb_captured_length(tvb) > 3) {
proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Front panel buttons capabilities: ",
NULL, ett_ipmi_chs_01_fpb, byte4, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
};
@@ -494,11 +494,11 @@ rq04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
static const int *byte2[] = { &hf_ipmi_chs_04_perm_on, NULL };
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
proto_tree_add_item(tree, hf_ipmi_chs_04_ival, tvb, 0, 1, ENC_LITTLE_ENDIAN);
}
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Flags: ", "None",
ett_ipmi_chs_04_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
}
@@ -517,7 +517,7 @@ rq05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_chs_05_sdr_dev_addr, tvb, 2, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_chs_05_sel_dev_addr, tvb, 3, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_chs_05_sm_dev_addr, tvb, 4, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 5) {
+ if (tvb_captured_length(tvb) > 5) {
/* Bridge device address is optional */
proto_tree_add_item(tree, hf_ipmi_chs_05_bridge_dev_addr, tvb, 5, 1, ENC_LITTLE_ENDIAN);
}
@@ -588,13 +588,13 @@ rq08(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ipmi_dcd8(pno, 0x7f), desc, pno);
/* Data is optional; no data means 'just set validity' */
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
if (pno < array_length(boot_options)) {
- sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
+ sub = tvb_new_subset_remaining(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);
+ -1, "Parameter data: %s", desc);
}
}
}
@@ -670,11 +670,10 @@ rs09(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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);
+ sub = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_chs_09_rs_param_data, tvb, 2, -1, ENC_NA);
}
}
@@ -715,7 +714,7 @@ 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, VALS(bo00_sip_vals), 0x03, NULL, HFILL }},
+ "ipmi.bootopt00.sip", FT_UINT8, BASE_HEX, VALS(bo00_sip_vals), 0x03, NULL, HFILL }},
{ &hf_ipmi_chs_bo01_spsel,
{ "Service Partition Selector",
"ipmi.bootopt01.spsel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
diff --git a/epan/dissectors/packet-ipmi-picmg.c b/epan/dissectors/packet-ipmi-picmg.c
index a957ff26ae..04f2423747 100644
--- a/epan/dissectors/packet-ipmi-picmg.c
+++ b/epan/dissectors/packet-ipmi-picmg.c
@@ -28,11 +28,11 @@
#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_link_info = -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;
@@ -51,6 +51,23 @@ 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 ett_ipmi_picmg_link_state = -1;
+static gint ett_ipmi_picmg_link_dev = -1;
+
+static gint ett_ipmi_picmg_clock_setting = -1;
+static gint ett_ipmi_picmg_clock_res = -1;
+
+static gint ett_ipmi_picmg_hpm_caps = -1;
+
+static gint ett_ipmi_picmg_47_byte1 = -1;
+
+static gint ett_ipmi_picmg_23_rq_byte2 = -1;
+static gint ett_ipmi_picmg_23_rs_byte5 = -1;
+static gint ett_ipmi_picmg_25_rs_byte4 = -1;
+static gint ett_ipmi_picmg_25_rs_byte5 = -1;
+static gint ett_ipmi_picmg_27_rs_byte3 = -1;
+static gint ett_ipmi_picmg_28_rq_byte3 = -1;
+static gint ett_ipmi_picmg_29_rs_byte3 = -1;
static gint hf_ipmi_picmg_led_function = -1;
static gint hf_ipmi_picmg_led_on_duration = -1;
@@ -63,6 +80,30 @@ 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_linkinfo = -1;
+static gint hf_ipmi_picmg_linkinfo_amc_chan = -1;
+static gint hf_ipmi_picmg_linkinfo_amc_ports = -1;
+static gint hf_ipmi_picmg_linkinfo_amc_type = -1;
+static gint hf_ipmi_picmg_linkinfo_amc_type_ext = -1;
+static gint hf_ipmi_picmg_linkinfo_amc_grpid = -1;
+static gint hf_ipmi_picmg_linkinfo_state_0 = -1;
+static gint hf_ipmi_picmg_linkinfo_state_1 = -1;
+static gint hf_ipmi_picmg_linkinfo_dev = -1;
+static gint hf_ipmi_picmg_linkinfo_dev_type = -1;
+static gint hf_ipmi_picmg_linkinfo_dev_id = -1;
+
+static gint hf_ipmi_picmg_clock_id = -1;
+static gint hf_ipmi_picmg_clock_cfg = -1;
+static gint hf_ipmi_picmg_clock_setting = -1;
+static gint hf_ipmi_picmg_clock_state = -1;
+static gint hf_ipmi_picmg_clock_dir = -1;
+static gint hf_ipmi_picmg_clock_pll = -1;
+static gint hf_ipmi_picmg_clock_family = -1;
+static gint hf_ipmi_picmg_clock_accuracy = -1;
+static gint hf_ipmi_picmg_clock_frequency = -1;
+static gint hf_ipmi_picmg_clock_resource = -1;
+static gint hf_ipmi_picmg_clock_resource_type = -1;
+static gint hf_ipmi_picmg_clock_resource_dev = -1;
static gint hf_ipmi_picmg_00_version = -1;
static gint hf_ipmi_picmg_00_max_fruid = -1;
@@ -175,6 +216,8 @@ 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_1a_flags = -1;
+
static gint hf_ipmi_picmg_1b_addr_active = -1;
static gint hf_ipmi_picmg_1b_addr_backup = -1;
@@ -288,6 +331,114 @@ static gint hf_ipmi_picmg_36_fail_oper_fw = -1;
static gint hf_ipmi_picmg_37_percent = -1;
+static gint hf_ipmi_picmg_hpm_id = -1;
+static gint hf_ipmi_picmg_hpm_rev = -1;
+static gint hf_ipmi_picmg_hpm2_mask = -1;
+static gint hf_ipmi_picmg_hpm2_caps = -1;
+static gint hf_ipmi_picmg_hpm2_dyn_ssn = -1;
+static gint hf_ipmi_picmg_hpm2_ver_chg = -1;
+static gint hf_ipmi_picmg_hpm2_ext_mgt = -1;
+static gint hf_ipmi_picmg_hpm2_pkt_trc = -1;
+static gint hf_ipmi_picmg_hpm2_sol_ext = -1;
+static gint hf_ipmi_picmg_hpm_oem_start = -1;
+static gint hf_ipmi_picmg_hpm_oem_rev = -1;
+static gint hf_ipmi_picmg_hpm2_sol_oem_start = -1;
+static gint hf_ipmi_picmg_hpm2_sol_oem_rev = -1;
+static gint hf_ipmi_picmg_hpm_cred_hnd = -1;
+static gint hf_ipmi_picmg_hpm_func_sel = -1;
+static gint hf_ipmi_picmg_hpm_ipmi_rev = -1;
+static gint hf_ipmi_picmg_hpm_cipher_id = -1;
+static gint hf_ipmi_picmg_hpm_auth_type = -1;
+static gint hf_ipmi_picmg_hpm_priv_level = -1;
+static gint hf_ipmi_picmg_hpm_chn_num = -1;
+static gint hf_ipmi_picmg_hpm_avail_time = -1;
+static gint hf_ipmi_picmg_hpm_user_name = -1;
+static gint hf_ipmi_picmg_hpm_user_pwd = -1;
+static gint hf_ipmi_picmg_hpm_bmc_key = -1;
+static gint hf_ipmi_picmg_hpm_operation = -1;
+static gint hf_ipmi_picmg_hpm_ssn_hnd = -1;
+
+static gint hf_ipmi_picmg_hpm_power_draw = -1;
+static gint hf_ipmi_picmg_hpm_base_channels = -1;
+static gint hf_ipmi_picmg_hpm_fabric_channels = -1;
+static gint hf_ipmi_picmg_hpm_update_channels = -1;
+static gint hf_ipmi_picmg_hpm_cross_channels = -1;
+static gint hf_ipmi_picmg_hpm_num_chn_desc = -1;
+static gint hf_ipmi_picmg_hpm_chn_mask = -1;
+
+static gint hf_ipmi_picmg_hpm_ext_mgmt_state = -1;
+static gint hf_ipmi_picmg_hpm_polling_period = -1;
+static gint hf_ipmi_picmg_hpm_auth_pwr_state = -1;
+static gint hf_ipmi_picmg_hpm_amc_pwr_state = -1;
+
+static gint hf_ipmi_picmg47_port = -1;
+static gint hf_ipmi_picmg47_flags = -1;
+static gint hf_ipmi_picmg47_assignment = -1;
+static gint hf_ipmi_picmg47_state = -1;
+static gint hf_ipmi_picmg47_instance = -1;
+
+static gint hf_ipmi_picmg48_sub_fru_type = -1;
+static gint hf_ipmi_picmg48_sub_fru_id = -1;
+static gint hf_ipmi_picmg48_ip_source = -1;
+
+static gint hf_ipmi_picmg_23_rq_byte2 = -1;
+static gint hf_ipmi_picmg_23_slot_sel = -1;
+static gint hf_ipmi_picmg_23_carrier_num = -1;
+static gint hf_ipmi_picmg_23_slot_num = -1;
+static gint hf_ipmi_picmg_23_tier_num = -1;
+static gint hf_ipmi_picmg_23_rs_byte5 = -1;
+static gint hf_ipmi_picmg_23_slot_base = -1;
+static gint hf_ipmi_picmg_23_tier_base = -1;
+static gint hf_ipmi_picmg_23_orientation = -1;
+static gint hf_ipmi_picmg_23_origin_x = -1;
+static gint hf_ipmi_picmg_23_origin_y = -1;
+
+static gint hf_ipmi_picmg_24_channel = -1;
+static gint hf_ipmi_picmg_24_control = -1;
+static gint hf_ipmi_picmg_24_current = -1;
+static gint hf_ipmi_picmg_24_primary_pm = -1;
+static gint hf_ipmi_picmg_24_backup_pm = -1;
+
+static gint hf_ipmi_picmg_25_start = -1;
+static gint hf_ipmi_picmg_25_count = -1;
+static gint hf_ipmi_picmg_25_max = -1;
+static gint hf_ipmi_picmg_25_gstatus = -1;
+static gint hf_ipmi_picmg_25_fault = -1;
+static gint hf_ipmi_picmg_25_pwr_good = -1;
+static gint hf_ipmi_picmg_25_mp_good = -1;
+static gint hf_ipmi_picmg_25_role = -1;
+static gint hf_ipmi_picmg_25_cstatus = -1;
+static gint hf_ipmi_picmg_25_pwr_on = -1;
+static gint hf_ipmi_picmg_25_pwr_ovr = -1;
+static gint hf_ipmi_picmg_25_pwr = -1;
+static gint hf_ipmi_picmg_25_enable = -1;
+static gint hf_ipmi_picmg_25_mp_ovr = -1;
+static gint hf_ipmi_picmg_25_mp = -1;
+static gint hf_ipmi_picmg_25_ps1 = -1;
+
+static gint hf_ipmi_picmg_26_pm_site = -1;
+static gint hf_ipmi_picmg_27_rs_byte3 = -1;
+static gint hf_ipmi_picmg_27_pm_healthy = -1;
+static gint hf_ipmi_picmg_28_timeout = -1;
+static gint hf_ipmi_picmg_28_rq_byte3 = -1;
+static gint hf_ipmi_picmg_28_mch2 = -1;
+static gint hf_ipmi_picmg_28_mch1 = -1;
+
+static gint hf_ipmi_picmg_29_rs_byte3 = -1;
+static gint hf_ipmi_picmg_29_maj_rst = -1;
+static gint hf_ipmi_picmg_29_min_rst = -1;
+static gint hf_ipmi_picmg_29_alarm_cut = -1;
+static gint hf_ipmi_picmg_29_test_mode = -1;
+static gint hf_ipmi_picmg_29_pwr_alarm = -1;
+static gint hf_ipmi_picmg_29_minor_alarm = -1;
+static gint hf_ipmi_picmg_29_major_alarm = -1;
+static gint hf_ipmi_picmg_29_crit_alarm = -1;
+
+static gint hf_ipmi_picmg_2a_alarm_id = -1;
+static gint hf_ipmi_picmg_2a_alarm_ctrl = -1;
+
+static gint hf_ipmi_picmg_2b_alarm_state = -1;
+
static const value_string site_type_vals[] = {
{ 0x00, "PICMG board" },
{ 0x01, "Power Entry" },
@@ -358,6 +509,21 @@ static const value_string linkinfo_type_vals[] = {
{ 0, NULL }
};
+static const value_string linkinfo_amc_type_vals[] = {
+ { 0x02, "AMC.1 PCI Express" },
+ { 0x03, "AMC.1 PCI Express Advanced Switching" },
+ { 0x04, "AMC.1 PCI Express Advanced Switching" },
+ { 0x05, "AMC.2 Ethernet" },
+ { 0x06, "AMC.3 Serial RapidIO" },
+ { 0x07, "AMC.3 Storage" },
+ { 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" },
@@ -536,16 +702,16 @@ rs00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static void
rq01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
}
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_addr_key_type, tvb, 1, 1, ENC_LITTLE_ENDIAN);
}
- if (tvb_length(tvb) > 2) {
+ if (tvb_captured_length(tvb) > 2) {
proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_addr_key, tvb, 2, 1, ENC_LITTLE_ENDIAN);
}
- if (tvb_length(tvb) > 3) {
+ if (tvb_captured_length(tvb) > 3) {
proto_tree_add_item(tree, hf_ipmi_picmg_01_rq_site_type, tvb, 3, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -690,10 +856,10 @@ rs08(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_bitmask_text(tree, tvb, 0, 1, "LED States: ", "None",
ett_ipmi_picmg_08_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
parse_led_state(tree, tvb, 1, "Local Control ");
- if (tvb_length(tvb) > 4) {
+ if (tvb_captured_length(tvb) > 4) {
parse_led_state(tree, tvb, 4, "Override ");
}
- if (tvb_length(tvb) > 7) {
+ if (tvb_captured_length(tvb) > 7) {
proto_tree_add_item(tree, hf_ipmi_picmg_08_lamptest_duration, tvb, 7, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -788,7 +954,7 @@ static void
rq0d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_picmg_0d_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_item(tree, hf_ipmi_picmg_0d_start, tvb, 1, 2, ENC_LITTLE_ENDIAN);
}
}
@@ -837,6 +1003,9 @@ rq0f(tvbuff_t *tvb, packet_info *pinfo _U_, 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, ENC_LITTLE_ENDIAN, 0);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_1a_flags, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ }
}
static void
@@ -845,19 +1014,21 @@ rs0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static const value_string state_vals[] = {
{ 0x00, "Disabled" },
{ 0x01, "Enabled" },
+ { 0x02, "Disabled, Extended Inactive State Link" },
+ { 0x03, "Enabled, Extended Inactive State Link" },
{ 0, NULL }
};
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
parse_link_info_state(tree, tvb, 0, " 1", state_vals);
}
- if (tvb_length(tvb) > 5) {
+ if (tvb_captured_length(tvb) > 5) {
parse_link_info_state(tree, tvb, 5, " 2", state_vals);
}
- if (tvb_length(tvb) > 10) {
+ if (tvb_captured_length(tvb) > 10) {
parse_link_info_state(tree, tvb, 10, " 3", state_vals);
}
- if (tvb_length(tvb) > 15) {
+ if (tvb_captured_length(tvb) > 15) {
parse_link_info_state(tree, tvb, 15, " 4", state_vals);
}
}
@@ -916,7 +1087,7 @@ rs12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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;
+ max = tvb_captured_length(tvb) - 3;
if (max == 0) {
max = 1; /* One byte is mandatory */
} else if (max > 20) {
@@ -937,7 +1108,7 @@ rs12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static void
rq13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
proto_tree_add_item(tree, hf_ipmi_picmg_13_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -972,7 +1143,7 @@ rq15(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_picmg_15_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
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) {
+ if (tvb_captured_length(tvb) > 2) {
proto_tree_add_item(tree, hf_ipmi_picmg_15_local_enable, tvb, 2, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -993,10 +1164,10 @@ rs16(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_item(tree, hf_ipmi_picmg_16_local_level, tvb, 1, 1, ENC_LITTLE_ENDIAN);
}
- if (tvb_length(tvb) > 2) {
+ if (tvb_captured_length(tvb) > 2) {
proto_tree_add_item(tree, hf_ipmi_picmg_16_local_enable, tvb, 2, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -1019,11 +1190,12 @@ rq17(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{ 0x02, "Notify" },
{ 0, NULL }
};
- guint to_shmm = ipmi_current_hdr->trg_sa == 0x20;
+ guint to_shmm = ipmi_get_hdr(pinfo)->rs_sa == 0x20;
guint cmd = tvb_get_guint8(tvb, 0);
+ ipmi_set_data(pinfo, 0, (to_shmm << 8) | cmd);
+
if (!tree) {
- ipmi_setsaveddata(0, (to_shmm << 8) | cmd);
return;
}
@@ -1064,7 +1236,7 @@ rs17(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
guint32 val;
guint8 status;
- if (!ipmi_getsaveddata(0, &val)) {
+ if (!ipmi_get_data(pinfo, 0, &val)) {
/* Without knowing the command, we cannot decipher the response */
proto_tree_add_item(tree, hf_ipmi_picmg_17_status, tvb, 0, 1, ENC_LITTLE_ENDIAN);
return;
@@ -1092,6 +1264,78 @@ rs18(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_picmg_18_sensor_num, tvb, 1, 1, ENC_LITTLE_ENDIAN);
}
+static void
+parse_amc_link_info_state(proto_tree *tree, tvbuff_t *tvb, guint offs)
+{
+ static const int *amc_link_info[] = {
+ &hf_ipmi_picmg_linkinfo_amc_ports,
+ &hf_ipmi_picmg_linkinfo_amc_type,
+ &hf_ipmi_picmg_linkinfo_amc_type_ext,
+ &hf_ipmi_picmg_linkinfo_amc_grpid,
+ NULL };
+ static const int *amc_link_state[] = {
+ &hf_ipmi_picmg_linkinfo_state_0,
+ &hf_ipmi_picmg_linkinfo_state_1,
+ NULL };
+
+ proto_tree_add_bitmask(tree, tvb, offs, hf_ipmi_picmg_linkinfo,
+ ett_ipmi_picmg_link_info, amc_link_info, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, offs + 3, hf_ipmi_picmg_linkinfo_state,
+ ett_ipmi_picmg_link_state, amc_link_state, ENC_LITTLE_ENDIAN);
+}
+
+static const int *amc_link_dev[] = {
+ &hf_ipmi_picmg_linkinfo_dev_id,
+ NULL };
+
+/* Set AMC Port State
+ */
+static void
+rq19(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_linkinfo_amc_chan, tvb, 0, 1,
+ ENC_LITTLE_ENDIAN);
+ parse_amc_link_info_state(tree, tvb, 1);
+ if (tvb_captured_length(tvb) > 5) {
+ proto_tree_add_bitmask(tree, tvb, 5, hf_ipmi_picmg_linkinfo_dev,
+ ett_ipmi_picmg_link_dev, amc_link_dev, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get AMC Port State
+ */
+static void
+rq1a(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_linkinfo_amc_chan, tvb, 0, 1,
+ ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_picmg_linkinfo_dev,
+ ett_ipmi_picmg_link_state, amc_link_dev, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_1a_flags, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+static void
+rs1a(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint len = tvb_captured_length(tvb);
+ if (len > 0) {
+ parse_amc_link_info_state(tree, tvb, 0);
+ }
+ if (len > 4) {
+ parse_amc_link_info_state(tree, tvb, 4);
+ }
+ if (len > 8) {
+ parse_amc_link_info_state(tree, tvb, 8);
+ }
+ if (len > 12) {
+ parse_amc_link_info_state(tree, tvb, 12);
+ }
+}
+
/* Get Shelf Manager IPMB Address
*/
static void
@@ -1109,7 +1353,7 @@ rq1c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_site_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_enable_state, tvb, 1, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_1c_fan_policy_timeout, tvb, 2, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 3) {
+ if (tvb_captured_length(tvb) > 3) {
proto_tree_add_item(tree, hf_ipmi_picmg_1c_site_number, tvb, 3, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_1c_site_type, tvb, 4, 1, ENC_LITTLE_ENDIAN);
}
@@ -1121,7 +1365,7 @@ static void
rq1d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_picmg_1d_fan_site_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_item(tree, hf_ipmi_picmg_1d_site_number, tvb, 1, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_1d_site_type, tvb, 2, 1, ENC_LITTLE_ENDIAN);
}
@@ -1131,7 +1375,7 @@ static void
rs1d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_picmg_1d_policy, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_item(tree, hf_ipmi_picmg_1d_coverage, tvb, 1, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -1185,7 +1429,7 @@ rq20(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_picmg_20_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_20_lockid, tvb, 1, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_20_offset, tvb, 3, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_picmg_20_data, tvb, 5, tvb_length(tvb) - 5, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_picmg_20_data, tvb, 5, -1, ENC_NA);
}
static void
@@ -1233,8 +1477,8 @@ rs21(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static void
rq22(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
+ ipmi_set_data(pinfo, 0, tvb_get_guint8(tvb, 0));
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, ENC_LITTLE_ENDIAN);
@@ -1249,12 +1493,12 @@ rs22(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_picmg_22_update_cnt, tvb, 0, 2, ENC_LITTLE_ENDIAN);
- max = tvb_length(tvb) / 2 - 1;
+ max = tvb_captured_length(tvb) / 2 - 1;
if (!max) {
/* At least one shall be present */
max = 1;
}
- ipmi_getsaveddata(0, &offs);
+ ipmi_get_data(pinfo, 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,
@@ -1262,6 +1506,392 @@ rs22(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
}
}
+static const value_string picmg_23_slot_selectors[] = {
+ { 0, "MicroTCA Shelf within a Frame" },
+ { 1, "MicroTCA Carrier within a Shelf" },
+ { 2, "Slot within a MicroTCA Carrier" },
+ { 0, NULL }
+};
+
+static const value_string picmg_23_num_bases[] = {
+ { 0, "Zero-based" },
+ { 1, "One-based" },
+ { 0, NULL }
+};
+
+static const value_string picmg_23_orientations[] = {
+ { 0, "Vertical" },
+ { 1, "Horizontal" },
+ { 0, NULL }
+};
+
+/* Get Location Info
+ */
+static void
+rq23(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * picmg_23_rq_byte2[] = {
+ &hf_ipmi_picmg_23_slot_sel,
+ &hf_ipmi_picmg_23_carrier_num,
+ NULL
+ };
+
+ proto_tree_add_bitmask(tree, tvb, 0, hf_ipmi_picmg_23_rq_byte2,
+ ett_ipmi_picmg_23_rq_byte2, picmg_23_rq_byte2,
+ ENC_LITTLE_ENDIAN);
+ if ((tvb_get_guint8(tvb, 0) & 0xC0) == 0x80) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_site_num,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_site_type,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+static void
+rs23(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * picmg_23_rs_byte5[] = {
+ &hf_ipmi_picmg_23_slot_base,
+ &hf_ipmi_picmg_23_tier_base,
+ &hf_ipmi_picmg_23_orientation,
+ NULL
+ };
+
+ proto_tree_add_item(tree, hf_ipmi_picmg_23_slot_num,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_23_tier_num,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_ipmi_picmg_23_rs_byte5,
+ ett_ipmi_picmg_23_rs_byte5, picmg_23_rs_byte5,
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_23_origin_x,
+ tvb, 3, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_23_origin_y,
+ tvb, 5, 2, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string picmg_24_controls[] = {
+ { 0, "Disable MP" },
+ { 1, "Enable MP" },
+ { 2, "De-assert ENABLE#" },
+ { 3, "Assert ENABLE#" },
+ { 4, "Disable PWR" },
+ { 5, "Enable PWR" },
+ { 0, NULL }
+};
+
+void
+fmt_power_amps(gchar *s, guint32 v)
+{
+ g_snprintf(s, ITEM_LABEL_LENGTH, "%d.%dA", v / 10, v % 10);
+}
+
+/* Power Channel Control
+ */
+static void
+rq24(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_24_channel,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_24_control,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_24_current,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_24_primary_pm,
+ tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_24_backup_pm,
+ tvb, 4, 1, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string picmg_25_fault_vals[] = {
+ { 0, "Redundant PM is not providing Payload Power current" },
+ { 1, "Redundant PM is providing Payload Power current" },
+ { 0, NULL }
+};
+
+static const true_false_string picmg_25_roles = {
+ "Primary", "Redundant"
+};
+
+/* Get Power Channel Status
+ */
+static void
+rq25(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_25_start,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_25_count,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+static void
+rs25(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * picmg_25_gstatus[] = {
+ &hf_ipmi_picmg_25_fault,
+ &hf_ipmi_picmg_25_pwr_good,
+ &hf_ipmi_picmg_25_mp_good,
+ &hf_ipmi_picmg_25_role,
+ NULL
+ };
+ static const gint * picmg_25_cstatus[] = {
+ &hf_ipmi_picmg_25_pwr_on,
+ &hf_ipmi_picmg_25_pwr_ovr,
+ &hf_ipmi_picmg_25_pwr,
+ &hf_ipmi_picmg_25_enable,
+ &hf_ipmi_picmg_25_mp_ovr,
+ &hf_ipmi_picmg_25_mp,
+ &hf_ipmi_picmg_25_ps1,
+ NULL
+ };
+
+ guint i, len = tvb_captured_length(tvb);
+
+ proto_tree_add_item(tree, hf_ipmi_picmg_25_max,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_picmg_25_gstatus,
+ ett_ipmi_picmg_25_rs_byte4, picmg_25_gstatus,
+ ENC_LITTLE_ENDIAN);
+
+ for (i = 2; i < len; i++) {
+ proto_tree_add_bitmask(tree, tvb, i, hf_ipmi_picmg_25_cstatus,
+ ett_ipmi_picmg_25_rs_byte5, picmg_25_cstatus,
+ ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* PM Reset
+ */
+static void
+rq26(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_26_pm_site,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get PM Status
+ */
+static void
+rs27(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * picmg_27_status[] = {
+ &hf_ipmi_picmg_27_pm_healthy,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_ipmi_picmg_27_rs_byte3,
+ ett_ipmi_picmg_27_rs_byte3, picmg_27_status,
+ ENC_LITTLE_ENDIAN);
+}
+
+static const value_string cc28[] = {
+ { 0x80, "Returned from autonomous mode" },
+ { 0, NULL }
+};
+
+void
+fmt_100ms(gchar *s, guint32 v)
+{
+ g_snprintf(s, ITEM_LABEL_LENGTH, "%d.%dS", v / 10, v % 10);
+}
+
+/* PM Heart-Beat
+ */
+static void
+rq28(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * picmg_28_flags[] = {
+ &hf_ipmi_picmg_28_mch2,
+ &hf_ipmi_picmg_28_mch1,
+ NULL
+ };
+ proto_tree_add_item(tree, hf_ipmi_picmg_28_timeout,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_picmg_28_rq_byte3,
+ ett_ipmi_picmg_28_rq_byte3, picmg_28_flags,
+ ENC_LITTLE_ENDIAN);
+}
+
+static const true_false_string picmg_29_alarm_actions = {
+ "Produces(results in) an implementation-defined action",
+ "Not implemented"
+};
+
+static const true_false_string picmg_29_alarm_modes = {
+ "Can be controlled/enabled by the Set Telco Alarm State command",
+ "Can not be controlled/enabled"
+};
+
+/* Get Telco Alarm Capabilities
+ */
+static void
+rs29(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * picmg_29_caps[] = {
+ &hf_ipmi_picmg_29_maj_rst,
+ &hf_ipmi_picmg_29_min_rst,
+ &hf_ipmi_picmg_29_alarm_cut,
+ &hf_ipmi_picmg_29_test_mode,
+ &hf_ipmi_picmg_29_pwr_alarm,
+ &hf_ipmi_picmg_29_minor_alarm,
+ &hf_ipmi_picmg_29_major_alarm,
+ &hf_ipmi_picmg_29_crit_alarm,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_ipmi_picmg_29_rs_byte3,
+ ett_ipmi_picmg_29_rs_byte3, picmg_29_caps,
+ ENC_LITTLE_ENDIAN);
+}
+
+static const value_string picmg_2a_alarm_ids[] = {
+ { 0, "Critical Alarm" },
+ { 1, "Major Alarm" },
+ { 2, "Minor Alarm" },
+ { 3, "Power Alarm" },
+ { 4, "Alarm Cutoff" },
+ { 0, NULL }
+};
+
+static const value_string picmg_2a_alarm_ctrls[] = {
+ { 0, "off / cutoff disabled" },
+ { 1, "on / cutoff enabled" },
+ { 0xFF, "test mode" },
+ { 0, NULL }
+};
+
+/* Set Telco Alarm State
+ */
+static void
+rq2a(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_05_fruid,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_2a_alarm_id,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_2a_alarm_ctrl,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get Telco Alarm State
+ */
+static void
+rq2b(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_05_fruid,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_2a_alarm_id,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+static void
+rs2b(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_2b_alarm_state,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string amc_clock_ids[] = {
+ { 1, "TCLKA(CLK1A)" },
+ { 2, "TCLKB(CLK1B)" },
+ { 3, "TCLKC(CLK1)" },
+ { 4, "TCLKD(CLK2A)" },
+ { 5, "FCLKA(CLK2B)" },
+ { 6, "CLK2" },
+ { 7, "CLK3A" },
+ { 8, "CLK3B" },
+ { 9, "CLK3" },
+ { 0, NULL }
+};
+
+static const value_string amc_clock_dirs[] = {
+ { 0, "Clock receiver" },
+ { 1, "Clock source" },
+ { 0, NULL }
+};
+
+static const value_string amc_clock_plls[] = {
+ { 0, "Default state" },
+ { 1, "Connect through PLL" },
+ { 2, "Bypass PLL" },
+ { 0, NULL }
+};
+
+static const range_string amc_clock_families[] = {
+ { 0, 0, "Unspecified" },
+ { 1, 1, "SONET/SDH/PDH" },
+ { 2, 2, "Reserved for PCI Express" },
+ { 3, 0xC8, "Reserved" },
+ { 0xC9, 0xFF, "Vendor defined" },
+ { 0, 0, NULL }
+};
+
+static const value_string amc_clock_resource_types[] = {
+ { 0, "On-Carrier device" },
+ { 1, "AMC module" },
+ { 2, "Backplane" },
+ { 3, "Reserved" },
+ { 0, NULL }
+};
+
+static const int * amc_clock_setting[] = {
+ &hf_ipmi_picmg_clock_pll,
+ &hf_ipmi_picmg_clock_dir,
+ &hf_ipmi_picmg_clock_state,
+ NULL
+};
+
+static const int * amc_clock_resource[] = {
+ &hf_ipmi_picmg_clock_resource_type,
+ &hf_ipmi_picmg_clock_resource_dev,
+ NULL
+};
+
+/* Set Clock State
+ */
+static void
+rq2c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_id, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_cfg, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_ipmi_picmg_clock_setting,
+ ett_ipmi_picmg_clock_setting, amc_clock_setting, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 3) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_family, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_accuracy, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_frequency, tvb, 5, 4, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 9) {
+ proto_tree_add_bitmask(tree, tvb, 9, hf_ipmi_picmg_clock_resource,
+ ett_ipmi_picmg_clock_res, amc_clock_resource, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get Clock State (request)
+ */
+static void
+rq2d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_id, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_bitmask(tree, tvb, 1, hf_ipmi_picmg_clock_resource,
+ ett_ipmi_picmg_clock_res, amc_clock_resource, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get Clock State (response)
+ */
+static void
+rs2d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_bitmask(tree, tvb, 0, hf_ipmi_picmg_clock_setting,
+ ett_ipmi_picmg_clock_setting, amc_clock_setting, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_cfg, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_family, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_accuracy, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_clock_frequency, tvb, 4, 4, ENC_LITTLE_ENDIAN);
+ }
+}
+
static void
add_component_bits(proto_tree *tree, tvbuff_t *tvb, guint offs, const char *desc)
{
@@ -1322,7 +1952,7 @@ parse_version(tvbuff_t *tvb, proto_tree *tree)
static void
prop_02(tvbuff_t *tvb, proto_tree *tree)
{
- guint len = tvb_length(tvb);
+ guint len = tvb_captured_length(tvb);
if (len > 12) {
len = 12;
@@ -1347,8 +1977,8 @@ rq2f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
guint8 pno = tvb_get_guint8(tvb, 1);
const char *desc;
+ ipmi_set_data(pinfo, 0, pno);
if (!tree) {
- ipmi_setsaveddata(0, pno);
return;
}
@@ -1372,9 +2002,9 @@ rs2f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
const char *desc;
proto_item *ti;
- if (!ipmi_getsaveddata(0, &pno)) {
+ if (!ipmi_get_data(pinfo, 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), ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_picmg_2f_prop_data, tvb, 0, -1, ENC_NA);
return;
}
@@ -1391,7 +2021,7 @@ rs2f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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), ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_picmg_2f_prop_data, tvb, 0, -1, ENC_NA);
}
}
@@ -1431,13 +2061,13 @@ static void
rq32(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_picmg_32_block, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_picmg_32_data, tvb, 1, tvb_length(tvb) - 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_picmg_32_data, tvb, 1, -1, ENC_NA);
}
static void
rs32(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
proto_tree_add_item(tree, hf_ipmi_picmg_32_sec_offs, tvb, 0, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_picmg_32_sec_len, tvb, 4, 4, ENC_LITTLE_ENDIAN);
}
@@ -1484,7 +2114,7 @@ rs34(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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) {
+ if (tvb_captured_length(tvb) > 2) {
proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL,
ett_ipmi_picmg_34_byte3, byte3, ENC_LITTLE_ENDIAN, 0);
}
@@ -1500,7 +2130,7 @@ static const value_string cc34[] = {
static void
rq35(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- if (tvb_length(tvb) > 0) {
+ if (tvb_captured_length(tvb) > 0) {
proto_tree_add_item(tree, hf_ipmi_picmg_35_rollback_override, tvb, 0, 1, ENC_LITTLE_ENDIAN);
}
}
@@ -1556,7 +2186,7 @@ rs37(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static const gint *byte2[] = { &hf_ipmi_picmg_37_percent, NULL };
const char *desc;
- switch (ipmi_current_hdr->ccode) {
+ switch (ipmi_get_ccode(pinfo)) {
case 0x00: desc = "Components completed rollback: "; break;
case 0x80: desc = "Components (should be None): "; break;
case 0x81: desc = "Components failed to rollback: "; break;
@@ -1564,12 +2194,198 @@ rs37(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
}
add_component_bits(tree, tvb, 0, desc);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL,
ett_ipmi_picmg_37_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
}
}
+/* Get HPM.x Capabilities
+ */
+static void
+rq3e(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_id, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+static void
+rs3e(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint *hpm2_caps[] = {
+ &hf_ipmi_picmg_hpm2_dyn_ssn,
+ &hf_ipmi_picmg_hpm2_ver_chg,
+ &hf_ipmi_picmg_hpm2_ext_mgt,
+ &hf_ipmi_picmg_hpm2_pkt_trc,
+ &hf_ipmi_picmg_hpm2_sol_ext,
+ NULL };
+ guint8 hpm_x;
+
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_id, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_rev, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+
+ hpm_x = tvb_get_guint8(tvb, 0);
+
+ if (hpm_x == 2) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm2_mask, tvb, 2, 2, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 4) {
+ proto_tree_add_bitmask(tree, tvb, 4, hf_ipmi_picmg_hpm2_caps,
+ ett_ipmi_picmg_hpm_caps, hpm2_caps, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 5) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_oem_start,
+ tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_oem_rev,
+ tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 7) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm2_sol_oem_start,
+ tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm2_sol_oem_rev,
+ tvb, 8, 1, ENC_LITTLE_ENDIAN);
+ }
+ } else if (hpm_x == 3) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_oem_start,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_oem_rev,
+ tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+static const value_string hpm2_func_selectors[] = {
+ { 0x0, "Create Credentials" },
+ { 0x1, "Get Session Info" },
+ { 0x2, "Get User Name, least significant bytes" },
+ { 0x3, "Get User Name, most significant bytes" },
+ { 0x4, "Get Password, least significant bytes" },
+ { 0x5, "Get Password, most significant bytes" },
+ { 0x6, "Get BMC Key, least significant bytes" },
+ { 0x7, "Get BMC Key, most significant bytes" },
+ { 0, NULL }
+};
+
+static const value_string hpm2_ipmi_revs[] = {
+ { 0x0, "IPMI 1.5 session" },
+ { 0x1, "IPMI 2.0 session" },
+ { 0, NULL }
+};
+
+static const value_string hpm2_auth_types[] = {
+ { 0x0, "None" },
+ { 0x1, "MD2" },
+ { 0x2, "MD5" },
+ { 0x4, "Straight password" },
+ { 0x5, "OEM" },
+ { 0, NULL }
+};
+
+/* Get Dynamic Credentials
+ */
+static void
+rq3f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_cred_hnd,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_func_sel,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ if (!tvb_get_guint8(tvb, 1)) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ipmi_rev,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_get_guint8(tvb, 2)) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_cipher_id,
+ tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ } else {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_auth_type,
+ tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ }
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_priv_level,
+ tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_chn_num,
+ tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_avail_time,
+ tvb, 6, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_21_ipaddr,
+ tvb, 10, 4, ENC_BIG_ENDIAN);
+ }
+}
+
+static void
+rs3f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint8 func;
+
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_cred_hnd,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_func_sel,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+
+ func = tvb_get_guint8(tvb, 1);
+
+ switch (func) {
+ case 0:
+ case 1:
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_avail_time,
+ tvb, 2, 4, ENC_LITTLE_ENDIAN);
+ break;
+ case 2:
+ case 3:
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_user_name,
+ tvb, 2, 8, ENC_NA);
+ break;
+ case 4:
+ case 5:
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_user_pwd,
+ tvb, 2, 10, ENC_NA);
+ break;
+ case 6:
+ case 7:
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_bmc_key,
+ tvb, 2, 10, ENC_NA);
+ break;
+ }
+}
+
+static const value_string picmg40_operations[] = {
+ { 0x0, "Initiate new operation" },
+ { 0x1, "Poll for completion status" },
+ { 0, NULL }
+};
+
+static const value_string cc40[] = {
+ { 0x80, "In progress" },
+ { 0x81, "No previous establishment request" },
+ { 0x82, "LAN sessions are not supported" },
+ { 0x83, "Error trying to establish a session" },
+ { 0, NULL }
+};
+
+/* Get Session Handle for Explicit LAN Bridging
+ */
+static void
+rq40(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_ipmbaddr,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_fruid,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_operation,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+static void
+rs40(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_chn_num,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ssn_hnd,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ssn_hnd,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ssn_hnd,
+ tvb, 3, 1, ENC_LITTLE_ENDIAN);
+}
+
static const value_string cc37[] = {
{ 0x80, "Rollback in progress" },
{ 0x81, "Rollback failure" },
@@ -1585,65 +2401,270 @@ static const value_string cc38[] = {
{ 0, NULL }
};
+static const value_string hpm_x_ids[] = {
+ { 0x02, "HPM.2" },
+ { 0x03, "HPM.3" },
+ { 0, NULL }
+};
+
+/* Get ATCA Extended Management Resources
+ */
+static void
+rs41(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_power_draw,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_base_channels,
+ tvb, 1, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_fabric_channels,
+ tvb, 3, 2, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 5) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_update_channels,
+ tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 6) {
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_cross_channels,
+ tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+
+static const value_string amc_resource_types[] = {
+ { 0, "On-Carrier device (IRTM, MCH)" },
+ { 1, "AMC module" },
+ { 0, NULL }
+};
+
+/* Get AMC Extended Management Resources
+ */
+static void
+rs42(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint *amc_resource_type[] = {
+ &hf_ipmi_picmg_linkinfo_dev_type,
+ &hf_ipmi_picmg_linkinfo_dev_id,
+ NULL };
+ guint8 num, i;
+
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_power_draw,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_num_chn_desc,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+
+ num = tvb_get_guint8(tvb, 1);
+
+ for (i = 0; i < num; i++) {
+ proto_tree_add_bitmask(tree, tvb, 2 + i * 5,
+ hf_ipmi_picmg_linkinfo_dev, ett_ipmi_picmg_link_dev,
+ amc_resource_type, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_chn_mask,
+ tvb, 3 + i * 5, 4, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Set ATCA Extended Management State
+ */
+static void
+rq43(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ext_mgmt_state,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_polling_period,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get ATCA Extended Management State
+ */
+static void
+rs44(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_ext_mgmt_state,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string auth_pwr_states[] = {
+ { 0, "Normal. Full Payload Power." },
+ { 1, "Extended Management Power" },
+ { 0, NULL }
+};
+
+static const value_string amc_pwr_states[] = {
+ { 0, "Standard Management Power" },
+ { 1, "Extended Management Power" },
+ { 2, "Full Payload Power." },
+ { 0, NULL }
+};
+
+/* Set AMC Power State
+ */
+static void
+rq45(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_auth_pwr_state,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get AMC Power State
+ */
+static void
+rs46(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_auth_pwr_state,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg_hpm_amc_pwr_state,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string picmg47_flags[] = {
+ { 0, "Assign Payload Instance." },
+ { 1, "Return Assigned Instance" },
+ { 0, NULL }
+};
+
+static const value_string picmg47_states[] = {
+ { 0, "No session currently opened on this System Serial Port." },
+ { 1, "A session already opened on this System Serial Port." },
+ { 0, NULL }
+};
+
+static const value_string cc47[] = {
+ { 0x80, "Payload Instance can not be assigned at this time." },
+ { 0, NULL }
+};
+
+/* Assign SOL Payload Instance
+ */
+static void
+rq47(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg47_port,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_picmg47_flags,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+
+}
+
+static void
+rs47(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint *byte1[] = {
+ &hf_ipmi_picmg47_state,
+ &hf_ipmi_picmg47_instance,
+ NULL };
+
+ proto_tree_add_bitmask(tree, tvb, 0, hf_ipmi_picmg47_assignment,
+ ett_ipmi_picmg_47_byte1, byte1, ENC_LITTLE_ENDIAN);
+}
+
+static const value_string picmg48_fru_types[] = {
+ { 0, "None" },
+ { 1, "IPMB-L address of subsidiary MMC" },
+ { 2, "IPMB-0 address of subsidiary EMMC" },
+ { 3, "FRU Device ID of subsidiary FRU" },
+ { 0, NULL }
+};
+
+static const value_string picmg48_ip_sources[] = {
+ { 0, "Not configured for HPM.3" },
+ { 2, "DHCP assigned" },
+ { 4, "DHCP Proxy assigned" },
+ { 0, NULL }
+};
+
+/* Get IP Address Source
+ */
+static void
+rq48(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg_01_rs_ipmbaddr,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_picmg48_sub_fru_type,
+ tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_ipmi_picmg48_sub_fru_id,
+ tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+static void
+rs48(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ipmi_picmg48_ip_source,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
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 },
+ /* 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, rq19, NULL, NULL, NULL, "[AMC.0] Set AMC Port State", 0 },
+ { 0x1a, rq1a, rs1a, 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, rq23, rs23, NULL, NULL, "[uTCA] Get Location Information", 0 },
+ { 0x24, rq24, NULL, NULL, NULL, "[uTCA] Power Channel Control", 0 },
+ { 0x25, rq25, rs25, NULL, NULL, "[uTCA] Get Power Channel Status", 0 },
+ { 0x26, rq26, NULL, NULL, NULL, "[uTCA] PM Reset", 0 },
+ { 0x27, rq26, rs27, NULL, NULL, "[uTCA] Get PM Status", 0 },
+ { 0x28, rq28, NULL, cc28, NULL, "[uTCA] PM Heartbeat", 0 },
+ { 0x29, rq05, rs29, NULL, NULL, "[uTCA] Get Telco Alarm Capability", 0 },
+ { 0x2a, rq2a, NULL, NULL, NULL, "[uTCA] Set Telco Alarm State", 0 },
+ { 0x2b, rq2b, rs2b, NULL, NULL, "[uTCA] Get Telco Alarm State", 0 },
+ { 0x2c, rq2c, NULL, NULL, NULL, "[AMC.0] Set Clock State", 0 },
+ { 0x2d, rq2d, rs2d, 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 },
+ { 0x3e, rq3e, rs3e, NULL, NULL, "[HPM.2] Get HPM.x Capabilities", 0 },
+ { 0x3f, rq3f, rs3f, NULL, NULL, "[HPM.2] Get Dynamic Credentials", 0 },
+ { 0x40, rq40, rs40, cc40, NULL, "[HPM.2] Get Session Handle for Explicit LAN Bridging", 0 },
+ { 0x41, NULL, rs41, NULL, NULL, "[HPM.2] Get ATCA Extended Management Resources", 0 },
+ { 0x42, NULL, rs42, NULL, NULL, "[HPM.2] Get AMC Extended Management Resources", 0 },
+ { 0x43, rq43, NULL, NULL, NULL, "[HPM.2] Set ATCA Extended Management State", 0 },
+ { 0x44, NULL, rs44, NULL, NULL, "[HPM.2] Get ATCA Extended Management State", 0 },
+ { 0x45, rq45, NULL, NULL, NULL, "[HPM.2] Set AMC Power State", 0 },
+ { 0x46, NULL, rs46, NULL, NULL, "[HPM.2] Get AMC Power State", 0 },
+ { 0x47, rq47, rs47, cc47, NULL, "[HPM.2] Assign SOL Payload Instance", 0 },
+ { 0x48, rq48, rs48, NULL, NULL, "[HPM.3] Get IP Address Source", 0 }
};
void
@@ -1680,7 +2701,77 @@ ipmi_register_picmg(gint proto_ipmi)
"ipmi.linkinfo.chan", FT_UINT32, BASE_DEC, NULL, 0x0000003f, NULL, HFILL }},
{ &hf_ipmi_picmg_linkinfo_state,
{ "State",
- "ipmi.picmg0e.state", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ "ipmi.linkinfo.state", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo,
+ { "Link Info",
+ "ipmi.linkinfo", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_amc_chan,
+ { "Channel",
+ "ipmi.linkinfo.chan", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_amc_ports,
+ { "Ports",
+ "ipmi.linkinfo.ports", FT_UINT24, BASE_HEX, VALS(linkinfo_ports_vals), 0x00000f, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_amc_type,
+ { "Type",
+ "ipmi.linkinfo.type", FT_UINT24, BASE_HEX, VALS(linkinfo_amc_type_vals), 0x000ff0, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_amc_type_ext,
+ { "Type extension",
+ "ipmi.linkinfo.type_ext", FT_UINT24, BASE_HEX, NULL, 0x00f000, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_amc_grpid,
+ { "Grouping ID",
+ "ipmi.linkinfo.grpid", FT_UINT24, BASE_DEC, NULL, 0xff0000, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_state_0,
+ { "Enabled",
+ "ipmi.linkinfo.state0", FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_state_1,
+ { "Extended Management Link",
+ "ipmi.linkinfo.state1", FT_BOOLEAN, 8, NULL, 0x2, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_dev,
+ { "On-Carrier Device",
+ "ipmi.linkinfo.dev", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_dev_type,
+ { "Device Type",
+ "ipmi.linkinfo.dev.type", FT_UINT8, BASE_DEC, VALS(amc_resource_types), 0x80, NULL, HFILL }},
+ { &hf_ipmi_picmg_linkinfo_dev_id,
+ { "Device ID",
+ "ipmi.linkinfo.dev.id", FT_UINT8, BASE_DEC_HEX, NULL, 0xF, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_clock_id,
+ { "Clock ID",
+ "ipmi.clock.id", FT_UINT8, BASE_HEX, VALS(amc_clock_ids), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_cfg,
+ { "Clock Configuration Descriptor Index",
+ "ipmi.clock.cfg", FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_setting,
+ { "Clock Setting",
+ "ipmi.clock.setting", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_state,
+ { "Clock State",
+ "ipmi.clock.state", FT_UINT8, BASE_DEC, VALS(enable_vals), 0x8, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_dir,
+ { "Clock Direction",
+ "ipmi.clock.dir", FT_UINT8, BASE_DEC, VALS(amc_clock_dirs), 0x4, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_pll,
+ { "PLL Control",
+ "ipmi.clock.pll", FT_UINT8, BASE_DEC, VALS(amc_clock_plls), 0x3, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_family,
+ { "Clock Family",
+ "ipmi.clock.family", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(amc_clock_families), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_accuracy,
+ { "Clock Accuracy",
+ "ipmi.clock.accu", FT_UINT8, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_frequency,
+ { "Clock Frequency",
+ "ipmi.clock.freq", FT_UINT32, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_resource,
+ { "Clock Resource ID",
+ "ipmi.clock.res", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_resource_type,
+ { "Resource Type",
+ "ipmi.clock.res.type", FT_UINT8, BASE_HEX, VALS(amc_clock_resource_types), 0xC0, NULL, HFILL }},
+ { &hf_ipmi_picmg_clock_resource_dev,
+ { "Device ID",
+ "ipmi.clock.res.id", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
{ &hf_ipmi_picmg_00_version,
{ "PICMG Extension Version",
@@ -1708,7 +2799,7 @@ ipmi_register_picmg(gint proto_ipmi)
{ "Hardware Address",
"ipmi.picmg01.rs_hwaddr", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_picmg_01_rs_ipmbaddr,
- { "IPMB-0 Address",
+ { "IPMB Address",
"ipmi.picmg01.rs_ipmbaddr", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_picmg_01_rs_rsrv,
{ "Reserved (shall be 0xFF)",
@@ -1971,6 +3062,10 @@ ipmi_register_picmg(gint proto_ipmi)
{ "Sensor Number",
"ipmi.picmg18.sensor_num", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_1a_flags,
+ { "Extended Request Flags",
+ "ipmi.picmg1a.flags", FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+
{ &hf_ipmi_picmg_1b_addr_active,
{ "Active Shelf Manager IPMB Address",
"ipmi.picmg1b.addr_active", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
@@ -2272,10 +3367,312 @@ ipmi_register_picmg(gint proto_ipmi)
{ "Estimated percentage complete",
"ipmi.picmg37.percent", FT_UINT8, BASE_CUSTOM, ipmi_fmt_percent, 0x7f, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_id,
+ { "HPM.x Identifier",
+ "ipmi.picmg.hpm.id", FT_UINT8, BASE_HEX, VALS(hpm_x_ids), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_rev,
+ { "HPM.x Revision Identifier",
+ "ipmi.picmg.hpm.rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_mask,
+ { "IPMI LAN Channel Mask",
+ "ipmi.picmg.hpm2.mask", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_caps,
+ { "HPM.2 Capabilities",
+ "ipmi.picmg.hpm2.caps", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_dyn_ssn,
+ { "Dynamic Sessions",
+ "ipmi.picmg.hpm2.dynssn", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_ver_chg,
+ { "Version Change Sensor for LAN Configuration",
+ "ipmi.picmg.hpm2.verchg", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_ext_mgt,
+ { "Extended Inactive State Management",
+ "ipmi.picmg.hpm2.extmgt", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_pkt_trc,
+ { "IPMI Channel Packet Trace",
+ "ipmi.picmg.hpm2.pkttrc", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_sol_ext,
+ { "SOL Extensions",
+ "ipmi.picmg.hpm2.solext", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_oem_start,
+ { "OEM LAN Parameters Start Location",
+ "ipmi.picmg.hpm.oem.start", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_oem_rev,
+ { "OEM LAN Parameters Blocks Revision Number",
+ "ipmi.picmg.hpm.oem.rev", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_sol_oem_start,
+ { "OEM SOL Parameters Start Location",
+ "ipmi.picmg.hpm2.sol.oem.start", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm2_sol_oem_rev,
+ { "OEM SOL Parameters Blocks Revision Number",
+ "ipmi.picmg.hpm2.sol.oem.rev", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_cred_hnd,
+ { "Credentials Handle",
+ "ipmi.picmg.hpm.cred.hnd", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_func_sel,
+ { "Function Selector",
+ "ipmi.picmg.hpm.func.sel", FT_UINT8, BASE_DEC, VALS(hpm2_func_selectors), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_ipmi_rev,
+ { "IPMI Revision",
+ "ipmi.picmg.hpm.ipmi.rev", FT_UINT8, BASE_HEX, VALS(hpm2_ipmi_revs), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_auth_type,
+ { "Authentication Type",
+ "ipmi.picmg.hpm.auth.type", FT_UINT8, BASE_HEX, VALS(hpm2_auth_types), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_cipher_id,
+ { "Cipher Suite ID",
+ "ipmi.picmg.hpm.cipher", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_priv_level,
+ { "Maximum Privilege Level",
+ "ipmi.picmg.hpm.priv", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_chn_num,
+ { "IPMI Lan Channel Number",
+ "ipmi.picmg.hpm.chn.num", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_avail_time,
+ { "Availability Time",
+ "ipmi.picmg.hpm.avail", FT_UINT32, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_user_name,
+ { "User Name",
+ "ipmi.picmg.hpm.user.name", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_user_pwd,
+ { "User Password",
+ "ipmi.picmg.hpm.user.pwd", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_bmc_key,
+ { "BMC Key",
+ "ipmi.picmg.hpm.bmc.key", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_operation,
+ { "Command Operation Mode",
+ "ipmi.picmg.hpm.operation", FT_UINT8, BASE_DEC, VALS(picmg40_operations), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_ssn_hnd,
+ { "Session Handle",
+ "ipmi.picmg.hpm.ssn.hnd", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_power_draw,
+ { "Extended Management Power Draw",
+ "ipmi.picmg.hpm.pwr.draw", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_base_channels,
+ { "Base Interface Channels",
+ "ipmi.picmg.hpm.base.chn", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_fabric_channels,
+ { "Fabric Interface Channels",
+ "ipmi.picmg.hpm.base.chn", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_update_channels,
+ { "Update Channels",
+ "ipmi.picmg.hpm.upd.chn", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_cross_channels,
+ { "ShMC Cross-Connect Channels",
+ "ipmi.picmg.hpm.cross.chn", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_num_chn_desc,
+ { "Number of Channel Descriptors",
+ "ipmi.picmg.hpm.num.chn.desc", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_chn_mask,
+ { "Channel Bitmask",
+ "ipmi.picmg.hpm.chn.mask", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_ext_mgmt_state,
+ { "Extended Management State",
+ "ipmi.picmg.hpm.ext.mgmt.state", FT_UINT8, BASE_DEC, VALS(enable_vals), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_polling_period,
+ { "Polling Period",
+ "ipmi.picmg.hpm.poll.period", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_auth_pwr_state,
+ { "Authorized Power State",
+ "ipmi.picmg.hpm.auth.pwr", FT_UINT8, BASE_DEC, VALS(auth_pwr_states), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_hpm_amc_pwr_state,
+ { "Actual Power State",
+ "ipmi.picmg.hpm.amc.pwr", FT_UINT8, BASE_DEC, VALS(amc_pwr_states), 0, NULL, HFILL }},
+
+ { &hf_ipmi_picmg47_port,
+ { "System Serial Port Number",
+ "ipmi.picmg47.port", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg47_flags,
+ { "Flags",
+ "ipmi.picmg47.flags", FT_UINT8, BASE_DEC, VALS(picmg47_flags), 0x01, NULL, HFILL }},
+ { &hf_ipmi_picmg47_assignment,
+ { "Assigned Instance",
+ "ipmi.picmg47.assign", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg47_state,
+ { "Serial port assigned to instance state",
+ "ipmi.picmg47.state", FT_UINT8, BASE_DEC, VALS(picmg47_states), 0x80, NULL, HFILL }},
+ { &hf_ipmi_picmg47_instance,
+ { "Payload instance number",
+ "ipmi.picmg47.instance", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
+
+ { &hf_ipmi_picmg48_sub_fru_type,
+ { "Subsidiary FRU Identifier Type",
+ "ipmi.picmg48.fru.type", FT_UINT8, BASE_DEC, VALS(picmg48_fru_types), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg48_sub_fru_id,
+ { "Subsidiary FRU Identifier",
+ "ipmi.picmg48.fru.id", FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg48_ip_source,
+ { "IP Address Source",
+ "ipmi.picmg48.ip.source", FT_UINT8, BASE_DEC, VALS(picmg48_ip_sources), 0, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_23_rq_byte2,
+ { "Request Flags",
+ "ipmi.picmg23.rq.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_slot_sel,
+ { "MCS",
+ "ipmi.picmg23.rq.mcs", FT_UINT8, BASE_HEX, VALS(picmg_23_slot_selectors), 0xC0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_carrier_num,
+ { "Carrier Number",
+ "ipmi.picmg23.carrier.num", FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_slot_num,
+ { "Slot Number",
+ "ipmi.picmg23.slot.num", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_tier_num,
+ { "Tier Number",
+ "ipmi.picmg23.tier.num", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_rs_byte5,
+ { "Orientation Flags",
+ "ipmi.picmg23.rs.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_slot_base,
+ { "Slot Numbers",
+ "ipmi.picmg23.slot.base", FT_UINT8, BASE_DEC, VALS(picmg_23_num_bases), 0x80, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_tier_base,
+ { "Tier Numbers",
+ "ipmi.picmg23.tier.base", FT_UINT8, BASE_DEC, VALS(picmg_23_num_bases), 0x40, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_orientation,
+ { "Carrier Orientation",
+ "ipmi.picmg23.orient", FT_UINT8, BASE_DEC, VALS(picmg_23_orientations), 0x20, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_origin_x,
+ { "Origin X",
+ "ipmi.picmg23.origin.x", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_23_origin_y,
+ { "Origin Y",
+ "ipmi.picmg23.origin.y", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_24_channel,
+ { "Power Channel Number",
+ "ipmi.picmg.pwr.channel", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_24_control,
+ { "Power Channel Control",
+ "ipmi.picmg.pwr.control", FT_UINT8, BASE_DEC, VALS(picmg_24_controls), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_24_current,
+ { "Power Channel Current Limit",
+ "ipmi.picmg.pwr.limit", FT_UINT8, BASE_CUSTOM, fmt_power_amps, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_24_primary_pm,
+ { "Primary PM",
+ "ipmi.picmg.primary.pm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_24_backup_pm,
+ { "Redundant PM",
+ "ipmi.picmg.backup.pm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_25_start,
+ { "Starting Power Channel Number",
+ "ipmi.picmg25.start", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_count,
+ { "Power Channel Count",
+ "ipmi.picmg25.count", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_max,
+ { "Max Power Channel Number",
+ "ipmi.picmg25.max", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_gstatus,
+ { "Global Status",
+ "ipmi.picmg25.gstatus", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_fault,
+ { "Unidentified Fault",
+ "ipmi.picmg25.fault", FT_UINT8, BASE_DEC, VALS(picmg_25_fault_vals), 0x08, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_pwr_good,
+ { "Payload Power is Good",
+ "ipmi.picmg25.pwr.good", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_mp_good,
+ { "Management Power is Good",
+ "ipmi.picmg25.mp.good", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_role,
+ { "Role",
+ "ipmi.picmg25.fault", FT_BOOLEAN, 8, TFS(&picmg_25_roles), 0x01, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_cstatus,
+ { "Power Channel Status",
+ "ipmi.picmg25.cstatus", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_pwr_on,
+ { "PWR_ON is asserted",
+ "ipmi.picmg25.pwr.on", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_pwr_ovr,
+ { "Payload Power Overcurrent is detected",
+ "ipmi.picmg25.pwr.ovr", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_pwr,
+ { "Payload Power is enabled",
+ "ipmi.picmg25.pwr", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_enable,
+ { "ENABLE# is asserted",
+ "ipmi.picmg25.enable", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_mp_ovr,
+ { "Management Power Overcurrent is detected",
+ "ipmi.picmg25.mp.ovr", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_mp,
+ { "Management Power is enabled",
+ "ipmi.picmg25.mp", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_ipmi_picmg_25_ps1,
+ { "PS1# is asserted",
+ "ipmi.picmg25.ps1", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_26_pm_site,
+ { "PM Site Number",
+ "ipmi.picmg26.pm.site", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_27_rs_byte3,
+ { "PM Status",
+ "ipmi.picmg26.pm.status", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_27_pm_healthy,
+ { "PM is present and healthy",
+ "ipmi.picmg26.pm.hly", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_ipmi_picmg_28_timeout,
+ { "Time-out",
+ "ipmi.picmg28.timeout", FT_UINT8, BASE_CUSTOM, fmt_100ms, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_28_rq_byte3,
+ { "Flags",
+ "ipmi.picmg28.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_28_mch2,
+ { "Use MCH2 PS1# de-assertion to indicate Carrier Manager is extracted",
+ "ipmi.picmg28.mch2", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_ipmi_picmg_28_mch1,
+ { "Use MCH1 PS1# de-assertion to indicate Carrier Manager is extracted",
+ "ipmi.picmg28.mch1", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_29_rs_byte3,
+ { "Alarm Capabilities",
+ "ipmi.picmg29.caps", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_maj_rst,
+ { "Autonomous Major Reset",
+ "ipmi.picmg29.maj.rst", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_actions), 0x80, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_min_rst,
+ { "Autonomous Minor Reset",
+ "ipmi.picmg29.min.rst", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_actions), 0x40, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_alarm_cut,
+ { "Autonomous alarm cutoff",
+ "ipmi.picmg29.alrm.cut", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_actions), 0x20, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_test_mode,
+ { "Test Mode",
+ "ipmi.picmg29.test.mode", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_modes), 0x10, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_pwr_alarm,
+ { "Power Alarm",
+ "ipmi.picmg29.pwr.alrm", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_modes), 0x08, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_minor_alarm,
+ { "Minor Alarm",
+ "ipmi.picmg29.min.alrm", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_modes), 0x04, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_major_alarm,
+ { "Minor Alarm",
+ "ipmi.picmg29.maj.alrm", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_modes), 0x02, NULL, HFILL }},
+ { &hf_ipmi_picmg_29_crit_alarm,
+ { "Critical Alarm",
+ "ipmi.picmg29.crit.alrm", FT_BOOLEAN, 8, TFS(&picmg_29_alarm_modes), 0x01, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_2a_alarm_id,
+ { "Alarm ID",
+ "ipmi.picmg29.alrm.id", FT_UINT8, BASE_HEX, VALS(picmg_2a_alarm_ids), 0, NULL, HFILL }},
+ { &hf_ipmi_picmg_2a_alarm_ctrl,
+ { "Alarm Control",
+ "ipmi.picmg29.alrm.ctrl", FT_UINT8, BASE_HEX, VALS(picmg_2a_alarm_ctrls), 0, NULL, HFILL }},
+
+ { &hf_ipmi_picmg_2b_alarm_state,
+ { "Alarm State",
+ "ipmi.picmg29.alrm.ctrl", FT_UINT8, BASE_HEX, VALS(picmg_2a_alarm_ctrls), 0, NULL, HFILL }},
+
};
static gint *ett[] = {
&ett_ipmi_picmg_led_color,
&ett_ipmi_picmg_link_info,
+ &ett_ipmi_picmg_link_state,
+ &ett_ipmi_picmg_link_dev,
+ &ett_ipmi_picmg_clock_setting,
+ &ett_ipmi_picmg_clock_res,
&ett_ipmi_picmg_05_byte1,
&ett_ipmi_picmg_06_byte1,
&ett_ipmi_picmg_06_byte2,
@@ -2298,6 +3695,15 @@ ipmi_register_picmg(gint proto_ipmi)
&ett_ipmi_picmg_34_byte3,
&ett_ipmi_picmg_36_byte2,
&ett_ipmi_picmg_37_byte2,
+ &ett_ipmi_picmg_hpm_caps,
+ &ett_ipmi_picmg_47_byte1,
+ &ett_ipmi_picmg_23_rq_byte2,
+ &ett_ipmi_picmg_23_rs_byte5,
+ &ett_ipmi_picmg_25_rs_byte4,
+ &ett_ipmi_picmg_25_rs_byte5,
+ &ett_ipmi_picmg_27_rs_byte3,
+ &ett_ipmi_picmg_28_rq_byte3,
+ &ett_ipmi_picmg_29_rs_byte3
};
static guint8 sig_picmg[1] = { 0 };
diff --git a/epan/dissectors/packet-ipmi-pps.c b/epan/dissectors/packet-ipmi-pps.c
index 5d4a3c77c3..f3d089018f 100644
--- a/epan/dissectors/packet-ipmi-pps.c
+++ b/epan/dissectors/packet-ipmi-pps.c
@@ -28,59 +28,72 @@
#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 }
+ { 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 },
+ { 0x37, IPMI_TBD, NULL, NULL, "[PPS OEM] Calibrate A2F Temperature Sensor", 0 },
+ { 0x38, IPMI_TBD, NULL, NULL, "[PPS OEM] Get GPIO Signal State", 0 },
+ { 0x39, IPMI_TBD, NULL, NULL, "[PPS OEM] Set GPIO Signal State", 0 },
+ { 0x40, IPMI_TBD, NULL, NULL, "[PPS OEM] Sensor AFS Dump MBX Page", 0 },
+ { 0x41, IPMI_TBD, NULL, NULL, "[PPS OEM] Reset Non-Volatile Parameters and Reboot", 0 },
+ { 0x42, IPMI_TBD, NULL, NULL, "[PPS OEM] Dump Profiling Data", 0 },
+ { 0x43, IPMI_TBD, NULL, NULL, "[PPS OEM] Get FPGA Design Version", 0 },
+ { 0x44, IPMI_TBD, NULL, NULL, "[PPS OEM] Get IPMB Trace Mask", 0 },
+ { 0x45, IPMI_TBD, NULL, NULL, "[PPS OEM] Set IPMB Trace Mask", 0 },
+ { 0x46, IPMI_TBD, NULL, NULL, "[PPS OEM] Get PWM DAC Level", 0 },
+ { 0x47, IPMI_TBD, NULL, NULL, "[PPS OEM] Set PWM DAC Level", 0 },
+ { 0x48, IPMI_TBD, NULL, NULL, "[PPS OEM] Get FRU Info Write-Protect State", 0 },
+ { 0x49, IPMI_TBD, NULL, NULL, "[PPS OEM] Set FRU Info Write-Protect State", 0 }
};
void
diff --git a/epan/dissectors/packet-ipmi-se.c b/epan/dissectors/packet-ipmi-se.c
index def7398c46..b464a00316 100644
--- a/epan/dissectors/packet-ipmi-se.c
+++ b/epan/dissectors/packet-ipmi-se.c
@@ -1837,7 +1837,7 @@ parse_platform_event(tvbuff_t *tvb, proto_tree *tree)
fall back to "default" display in such weird cases.
*/
reinit_statics();
- if (tvb_length(tvb) <= 5) {
+ if (tvb_captured_length(tvb) <= 5) {
return;
}
@@ -1854,7 +1854,7 @@ parse_platform_event(tvbuff_t *tvb, proto_tree *tree)
}
/* Now the same for byte 3 */
- if (tvb_length(tvb) <= 6) {
+ if (tvb_captured_length(tvb) <= 6) {
return;
}
@@ -2028,7 +2028,7 @@ cfgparam_13(tvbuff_t *tvb, proto_tree *tree)
proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp13_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
proto_tree_add_item(tree, hf_ipmi_se_cp13_blocksel, tvb, 1, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_se_cp13_string, tvb, 2, tvb_length(tvb) - 2, ENC_ASCII|ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_se_cp13_string, tvb, 2, -1, ENC_ASCII|ENC_NA);
}
static void
@@ -2267,10 +2267,10 @@ rq12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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);
+ sub = tvb_new_subset_remaining(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,
+ proto_tree_add_none_format(tree, hf_ipmi_se_12_data, tvb, 1, -1,
"Configuration parameter data: %s", desc);
}
}
@@ -2295,9 +2295,9 @@ rq13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
pno = tvb_get_guint8(tvb, 0);
+ ipmi_set_data(pinfo, 0, pno);
if (!tree) {
/* Just cache parameter selector */
- ipmi_setsaveddata(0, pno);
return;
}
@@ -2334,18 +2334,18 @@ rs13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Parameter revision", NULL,
ett_ipmi_se_13_rev, byte1, ENC_LITTLE_ENDIAN, 0);
- if (!ipmi_getsaveddata(0, &pno)) {
+ if (!ipmi_get_data(pinfo, 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, ENC_NA);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, -1, ENC_NA);
}
return;
}
- if ((pno & 0x80) && tvb_length(tvb) > 1) {
+ if ((pno & 0x80) && tvb_captured_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) {
+ } else if (!(pno & 0x80) && tvb_captured_length(tvb) == 1) {
ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned");
PROTO_ITEM_SET_GENERATED(ti);
}
@@ -2362,12 +2362,12 @@ rs13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc);
PROTO_ITEM_SET_GENERATED(ti);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
if (pno < array_length(conf_params)) {
- sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
+ sub = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, -1, ENC_NA);
}
}
}
@@ -2433,18 +2433,18 @@ rq16(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static const gint *byte3[] = { &hf_ipmi_se_16_send_string, &hf_ipmi_se_16_string_sel, NULL };
tvbuff_t *sub;
+ ipmi_set_data(pinfo, 0, (tvb_get_guint8(tvb, 1) & 0xc0) >> 6);
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, ENC_LITTLE_ENDIAN, 0);
proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_16_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_se_16_byte3, byte3, ENC_LITTLE_ENDIAN, 0);
- if (tvb_length(tvb) > 3) {
+ if (tvb_captured_length(tvb) > 3) {
proto_tree_add_item(tree, hf_ipmi_se_16_gen, tvb, 3, 1, ENC_LITTLE_ENDIAN);
- sub = tvb_new_subset(tvb, 4, tvb_length(tvb) - 4, tvb_length(tvb) - 4);
+ sub = tvb_new_subset_remaining(tvb, 4);
parse_platform_event(sub, tree);
}
}
@@ -2454,7 +2454,7 @@ rs16(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
guint32 val;
- if (ipmi_getsaveddata(0, &val) && val == 0x01) {
+ if (ipmi_get_data(pinfo, 0, &val) && val == 0x01) {
/* Operation == Get Alert Immediate Status */
proto_tree_add_item(tree, hf_ipmi_se_16_status, tvb, 0, 1, ENC_LITTLE_ENDIAN);
}
@@ -2489,10 +2489,13 @@ rq20(tvbuff_t *tvb, packet_info *pinfo _U_, 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, ENC_LITTLE_ENDIAN, 0);
- ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0) & 0x01);
+ if (tvb_captured_length(tvb) > 0) {
+ ipmi_set_data(pinfo, 0, tvb_get_guint8(tvb, 0) & 0x01);
+
+ if (tree) {
+ proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
+ ett_ipmi_se_20_rq_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
+ }
}
}
@@ -2503,7 +2506,7 @@ rs20(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
&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) {
+ if (ipmi_get_data(pinfo, 0, &val) && val) {
proto_tree_add_item(tree, hf_ipmi_se_20_rs_sdr, tvb, 0, 1, ENC_LITTLE_ENDIAN);
} else {
proto_tree_add_item(tree, hf_ipmi_se_20_rs_num, tvb, 0, 1, ENC_LITTLE_ENDIAN);
@@ -2537,7 +2540,7 @@ static void
rs21(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_se_21_next, tvb, 0, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_se_21_recdata, tvb, 2, tvb_length(tvb) - 2, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_se_21_recdata, tvb, 2, -1, ENC_NA);
}
static const value_string cc21[] = {
@@ -2727,7 +2730,7 @@ add_events(tvbuff_t *tvb, int offs, proto_tree *tree, const struct true_false_st
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 len = tvb_captured_length(tvb);
int i, j, val, msk;
for (i = 0; (offs < len) && (i < 4); i++, offs++) {
@@ -2833,7 +2836,7 @@ rs2d(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_se_2d_reading, tvb, 0, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_2d_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
- len = tvb_length(tvb);
+ len = tvb_captured_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]);
diff --git a/epan/dissectors/packet-ipmi-session.c b/epan/dissectors/packet-ipmi-session.c
index b3f6e403ad..c04db04a9f 100644
--- a/epan/dissectors/packet-ipmi-session.c
+++ b/epan/dissectors/packet-ipmi-session.c
@@ -173,7 +173,7 @@ dissect_ipmi_session(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
if (tree) {
offset = 0;
ti = proto_tree_add_protocol_format(tree, proto_ipmi_session,
- tvb, 0, tvb_length(tvb),
+ tvb, 0, -1,
"IPMI v%s Session Wrapper, session ID 0x%x",
authtype == IPMI_AUTH_RMCPP ? "2.0+" : "1.5",
session_id);
@@ -251,12 +251,12 @@ dissect_ipmi_session(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
offset += msg_len;
/* Show the rest of the session wrapper as binary data */
- if (offset < tvb_length(tvb)) {
+ if (offset < tvb_captured_length(tvb)) {
proto_tree_add_item(sess_tree, hf_ipmi_session_trailer,
- tvb, offset, tvb_length(tvb) - offset, ENC_NA);
+ tvb, offset, -1, ENC_NA);
}
}
- return tvb_length(tvb);
+ return tvb_captured_length(tvb);
}
void
diff --git a/epan/dissectors/packet-ipmi-storage.c b/epan/dissectors/packet-ipmi-storage.c
index 29f260235d..5f9d0ab6f9 100644
--- a/epan/dissectors/packet-ipmi-storage.c
+++ b/epan/dissectors/packet-ipmi-storage.c
@@ -268,7 +268,7 @@ static void
rs11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_stor_11_ret_count, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_stor_11_data, tvb, 1, tvb_length(tvb) - 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_11_data, tvb, 1, -1, ENC_NA);
}
static const value_string cc11[] = {
@@ -283,7 +283,7 @@ rq12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_stor_12_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ipmi_stor_12_offset, tvb, 1, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_stor_12_data, tvb, 1, tvb_length(tvb) - 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_12_data, tvb, 3, -1, ENC_NA);
}
static void
@@ -354,7 +354,7 @@ static void
rs23(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_stor_23_next, tvb, 0, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_stor_23_data, tvb, 2, tvb_length(tvb) - 2, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_23_data, tvb, 2, -1, ENC_NA);
}
/* Add SDR
@@ -362,7 +362,7 @@ rs23(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
static void
rq24(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- proto_tree_add_item(tree, hf_ipmi_stor_24_data, tvb, 0, tvb_length(tvb), ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_24_data, tvb, 0, -1, ENC_NA);
}
static void
@@ -383,7 +383,7 @@ rq25(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_stor_25_offset, tvb, 4, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_bitmask_text(tree, tvb, 5, 1, NULL, NULL,
ett_ipmi_stor_25_byte6, byte6, ENC_LITTLE_ENDIAN, 0);
- proto_tree_add_item(tree, hf_ipmi_stor_25_data, tvb, 6, tvb_length(tvb) - 6, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_25_data, tvb, 6, -1, ENC_NA);
}
static void
@@ -532,7 +532,7 @@ static void
rs43(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_stor_43_next, tvb, 0, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_stor_43_data, tvb, 2, tvb_length(tvb) - 2, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_43_data, tvb, 2, -1, ENC_NA);
}
static const value_string cc43[] = {
@@ -546,7 +546,7 @@ static const value_string cc43[] = {
static void
rq44(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- proto_tree_add_item(tree, hf_ipmi_stor_44_data, tvb, 0, tvb_length(tvb), ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_44_data, tvb, 0, -1, ENC_NA);
}
static void
@@ -573,7 +573,7 @@ rq45(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(tree, hf_ipmi_stor_45_offset, tvb, 4, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_bitmask_text(tree, tvb, 5, 1, NULL, NULL,
ett_ipmi_stor_45_byte6, byte6, ENC_LITTLE_ENDIAN, 0);
- proto_tree_add_item(tree, hf_ipmi_stor_45_data, tvb, 6, tvb_length(tvb) - 6, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_45_data, tvb, 6, -1, ENC_NA);
}
static void
@@ -651,8 +651,8 @@ rq5a(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
static const int *byte1[] = { &hf_ipmi_stor_5a_log_type, NULL };
+ ipmi_set_data(pinfo, 0, tvb_get_guint8(tvb, 0) & 0x0f);
if (!tree) {
- ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0) & 0x0f);
return;
}
@@ -665,8 +665,8 @@ rs5a(tvbuff_t *tvb, packet_info *pinfo _U_, 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), ENC_NA);
+ if (!ipmi_get_data(pinfo, 0, &v) || v > 2) {
+ proto_tree_add_item(tree, hf_ipmi_stor_5a_unknown, tvb, 0, -1, ENC_NA);
return;
}
@@ -691,7 +691,7 @@ rq5b(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ett_ipmi_stor_5b_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
if (v > 2) {
- proto_tree_add_item(tree, hf_ipmi_stor_5b_unknown, tvb, 1, tvb_length(tvb) - 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_stor_5b_unknown, tvb, 1, -1, ENC_NA);
return;
}
diff --git a/epan/dissectors/packet-ipmi-trace.c b/epan/dissectors/packet-ipmi-trace.c
new file mode 100755
index 0000000000..fa5dc03980
--- /dev/null
+++ b/epan/dissectors/packet-ipmi-trace.c
@@ -0,0 +1,479 @@
+/* packet-hpm2-trace.c
+ * Routines for HPM.2 Trace Data Block disassembly
+ * By Dmitry Bazhenov <dima_b@pigeonpoint.com>
+ * Copyright 2014 Pigeon Point Systems
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/dissectors/packet-ipmi.h>
+#include <wiretap/wtap.h>
+
+/*
+ * See
+ *
+ * http://www.picmg.org/v2internal/resourcepage2.cfm?id=12
+ */
+
+/* Trace data block types. */
+enum {
+ HPM2_TRACE_PACKET_DATA = 0,
+ HPM2_CHN_STATE_NOTIFY = 1,
+ HPM2_EMBED_ASCII_MSG = 2
+};
+
+/* Data directions. */
+enum {
+ HPM2_TRACE_DATA_OUT = 0, /* From IPM controller */
+ HPM2_TRACE_DATA_IN = 1 /* To IPM controller */
+};
+
+/* Redundant channel indicators. */
+enum {
+ HPM2_TRACE_1ST_CHN = 0,
+ HPM2_TRACE_2ND_CHN = 1
+};
+
+/* IPMB local status values. */
+enum {
+ HPM2_IPMB_S_OK = 0,
+ HPM2_IPMB_S_ERR_SCL_HI = 1,
+ HPM2_IPMB_S_ERR_SDA_HI = 2,
+ HPM2_IPMB_S_ERR_SCL_LO = 3,
+ HPM2_IPMB_S_ERR_SDA_LO = 4,
+ HPM2_IPMB_S_SCL_TIMEOUT = 5,
+ HPM2_IPMB_S_UNDER_TEST = 6,
+ HPM2_IPMB_S_UNKNOWN_ERR = 7
+};
+
+/* IPMI channel protocol types. */
+enum {
+ IPMI_PROTO_IPMB_1_0 = 0x01,
+ IPMI_PROTO_ICMB_1_0 = 0x02,
+ IPMI_PROTO_IPMI_SMBUS = 0x04,
+ IPMI_PROTO_KCS = 0x05,
+ IPMI_PROTO_SMIC = 0x06,
+ IPMI_PROTO_BT_10 = 0x07,
+ IPMI_PROTO_BT_15 = 0x08,
+ IPMI_PROTO_TMODE = 0x09,
+ IPMI_PROTO_OEM_1 = 0x1C,
+ IPMI_PROTO_OEM_2 = 0x1D,
+ IPMI_PROTO_OEM_3 = 0x1E,
+ IPMI_PROTO_OEM_4 = 0x1F
+};
+
+/* IPMB override status values. */
+enum {
+ HPM2_IPMB_S_ISOLATED = 0,
+ HPM2_IPMB_S_LOCAL_CTRL = 1
+};
+
+void proto_register_ipmi_trace(void);
+void proto_reg_handoff_ipmi_trace(void);
+
+static int proto_ipmi_trace = -1;
+
+static dissector_handle_t data_dissector_handle;
+static dissector_table_t proto_dissector_table;
+
+static gint ett_ipmi_trace = -1;
+static gint ett_trace_block_type = -1;
+static gint ett_trace_timestamp = -1;
+static gint ett_trace_protocol_data = -1;
+static gint ett_trace_ipmb_state = -1;
+
+static gint hf_trace_block_type = -1;
+static gint hf_trace_channel_num = -1;
+static gint hf_trace_packet_type = -1;
+static gint hf_trace_timestamp = -1;
+static gint hf_trace_timestamp_sec = -1;
+static gint hf_trace_timestamp_msec = -1;
+static gint hf_trace_data_type = -1;
+static gint hf_trace_protocol_data = -1;
+static gint hf_trace_dir = -1;
+static gint hf_trace_ipmb_red_chn = -1;
+static gint hf_trace_ipmb_link_num = -1;
+static gint hf_trace_data_len = -1;
+static gint hf_trace_notify_format = -1;
+static gint hf_trace_ipmb_state = -1;
+static gint hf_trace_ipmb_ovr_state = -1;
+static gint hf_trace_ipmb_loc_state = -1;
+
+static const value_string str_packet_types[] = {
+ { 0, "IPMI Trace Packet Data" },
+ { 1, "Channel State Change Notification" },
+ { 2, "Embedded ASCII message" },
+ { 0, NULL }
+};
+
+static const value_string str_protocol_types[] = {
+ { 0, "n/a" },
+ { 1, "IPMB-1.0" },
+ { 2, "ICMB-1.0" },
+ { 4, "IPMI-SMBus" },
+ { 5, "KCS" },
+ { 6, "SMIC" },
+ { 7, "BT-10" },
+ { 8, "BT-15" },
+ { 9, "TMode" },
+ { 0x1C, "OEM Protocol 1" },
+ { 0x1D, "OEM Protocol 2" },
+ { 0x1E, "OEM Protocol 3" },
+ { 0x1F, "OEM Protocol 4" },
+ { 0, NULL }
+};
+
+static const value_string str_redund_chns[] = {
+ { 0, "First channel" },
+ { 1, "Second channel" },
+ { 0, NULL }
+};
+
+static const value_string str_trace_dirs[] = {
+ { 0, "From IPM Controller" },
+ { 1, "To IPM Controller" },
+ { 0, NULL }
+};
+
+static const value_string str_ipmb_notify_formats[] = {
+ { 0, "Derived from PICMG 3.0" },
+ { 0, NULL }
+};
+
+static const value_string str_ipmb_ovr_statuses[] = {
+ { 0, "Override status, bus isolated" },
+ { 1, "Local Control State" },
+ { 0, NULL }
+};
+
+static const value_string str_ipmb_loc_statuses[] = {
+ { 0, "No Failure" },
+ { 1, "Unable to drive clock HI" },
+ { 2, "Unable to drive data HI" },
+ { 3, "Unable to drive clock LO" },
+ { 4, "Unable to drive data LO" },
+ { 5, "Clock low timeout" },
+ { 6, "Under test" },
+ { 7, "Undiagnosed Communications Failure" },
+ { 0, NULL }
+};
+
+static const gint * bits_trace_block_type[] = {
+ &hf_trace_channel_num,
+ &hf_trace_packet_type,
+ NULL
+};
+
+static const gint * bits_ipmb_protocol_data[] = {
+ &hf_trace_ipmb_link_num,
+ &hf_trace_ipmb_red_chn,
+ &hf_trace_dir,
+ NULL
+};
+
+static const gint * bits_host_protocol_data[] = {
+ &hf_trace_dir,
+ NULL
+};
+
+static const gint * bits_chn_state_info[] = {
+ &hf_trace_ipmb_ovr_state,
+ &hf_trace_ipmb_loc_state,
+ NULL
+};
+
+/* HPM.2 Trace Collection tree indices. */
+static gint * const ipmi_trace_ett[] = {
+ &ett_ipmi_trace,
+ &ett_trace_block_type,
+ &ett_trace_timestamp,
+ &ett_trace_protocol_data,
+ &ett_trace_ipmb_state
+};
+
+/* HPM.2 Trace Collection header fields. */
+static hf_register_info ipmi_trace_hf[] = {
+ { &hf_trace_block_type, {
+ "Trace Data Block Type", "hpm2.trace.block.type",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_trace_channel_num, {
+ "IPMI Channel Number being traced", "hpm2.trace.chn.num",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0F, NULL, HFILL } },
+ { &hf_trace_packet_type, {
+ "Packet Type", "hpm2.trace.packet.type",
+ FT_UINT8, BASE_DEC, VALS(str_packet_types), 0x30, NULL, HFILL } },
+ { &hf_trace_timestamp, {
+ "Timestamp", "hpm2.trace.stamp",
+ FT_RELATIVE_TIME, BASE_NONE, NULL, 0, NULL, HFILL } },
+ { &hf_trace_timestamp_sec, {
+ "Seconds part", "hpm2.trace.stamp.sec",
+ FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_trace_timestamp_msec, {
+ "Milliseconds part", "hpm2.trace.stamp.msec",
+ FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_trace_data_type, {
+ "Trace Data Type", "hpm2.trace.data.type",
+ FT_UINT8, BASE_HEX, VALS(str_protocol_types), 0, NULL, HFILL } },
+ { &hf_trace_protocol_data, {
+ "Additional protocol specific data", "hpm2.trace.proto.data",
+ FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_trace_ipmb_link_num, {
+ "Radial IPMB Link Number", "hpm2.trace.ipmb.link.num",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x003F, NULL, HFILL } },
+ { &hf_trace_ipmb_red_chn, {
+ "Redundant Channel Indicator", "hpm2.trace.ipmb.red.chn",
+ FT_UINT16, BASE_DEC, VALS(str_redund_chns), 0x0040, NULL, HFILL } },
+ { &hf_trace_dir, {
+ "Direction", "hpm2.trace.dir",
+ FT_UINT16, BASE_DEC, VALS(str_trace_dirs), 0x0080, NULL, HFILL } },
+ { &hf_trace_data_len, {
+ "Data length", "hpm2.trace.data.len",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_trace_notify_format, {
+ "Data format", "hpm2.trace.data.format",
+ FT_UINT8, BASE_HEX, VALS(str_ipmb_notify_formats), 0, NULL, HFILL } },
+ { &hf_trace_ipmb_state, {
+ "State Change Information", "hpm2.trace.ipmb.state",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_trace_ipmb_ovr_state, {
+ "IPMB Override status", "hpm2.trace.ipmb.state.ovr",
+ FT_UINT8, BASE_DEC, VALS(str_ipmb_ovr_statuses), 0x8, NULL, HFILL } },
+ { &hf_trace_ipmb_loc_state, {
+ "IPMB Local status", "hpm2.trace.ipmb.state.loc",
+ FT_UINT8, BASE_DEC, VALS(str_ipmb_loc_statuses), 0x7, NULL, HFILL } },
+};
+
+static void
+dissect_ipmb_state_notify(tvbuff_t * tvb, proto_tree * tree)
+{
+ /* add data format */
+ proto_tree_add_item(tree, hf_trace_notify_format,
+ tvb, 0, 1, ENC_LITTLE_ENDIAN);
+
+ /* add host-specific data */
+ proto_tree_add_bitmask(tree, tvb, 1,
+ hf_trace_ipmb_state, ett_trace_ipmb_state,
+ bits_chn_state_info, ENC_LITTLE_ENDIAN);
+}
+
+static void
+dissect_ipmi_trace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint block_type, chn_num, data_type, tmp;
+ tvbuff_t * next_tvb;
+
+ if (tvb_captured_length(tvb) < 11) {
+ /* TODO: add expert info */
+ call_dissector(data_dissector_handle, tvb, pinfo, tree);
+ return;
+ }
+
+ /* get first byte */
+ tmp = tvb_get_guint8(tvb, 0);
+
+ /* get block type */
+ block_type = (tmp >> 4) & 3;
+
+ /* get channel number */
+ chn_num = tmp & 0xF;
+
+ /* get trace data type */
+ data_type = tvb_get_guint8(tvb, 7);
+
+
+ col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "Channel %d", chn_num);
+ col_set_str(pinfo->cinfo, COL_PROTOCOL,
+ val_to_str(data_type, str_protocol_types,
+ "Reserved (0x%02x)"));
+
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (block_type == HPM2_TRACE_PACKET_DATA) {
+ col_set_str(pinfo->cinfo, COL_INFO, "Trace Packet Data");
+ } else if (block_type == HPM2_CHN_STATE_NOTIFY) {
+ col_set_str(pinfo->cinfo, COL_INFO,
+ "Channel State Change Notification");
+ } else if (block_type == HPM2_EMBED_ASCII_MSG) {
+ char str[257];
+
+ /* get data length */
+ guint str_len = tvb_get_guint8(tvb, 10);
+
+ if (str_len) {
+ /* copy string */
+ tvb_memcpy(tvb, str, 11, str_len);
+
+ /* pad with nul */
+ str[str_len] = 0;
+
+ /* print the string right inside the column */
+ col_add_str(pinfo->cinfo, COL_INFO, str);
+ }
+ } else {
+ col_set_str(pinfo->cinfo, COL_INFO, "Reserved");
+ }
+
+
+ if ( tree ) {
+ proto_item * ti;
+ proto_tree * trace_tree;
+ proto_tree * stamp_tree;
+ nstime_t timestamp;
+
+ /* add protocol label */
+ ti = proto_tree_add_item(tree, proto_ipmi_trace, tvb, 0, -1, ENC_NA);
+
+ /* create protocol sub-tree */
+ trace_tree = proto_item_add_subtree(ti, ett_ipmi_trace);
+
+ /* add block type/channel bitmask */
+ proto_tree_add_bitmask(trace_tree, tvb, 0, hf_trace_block_type,
+ ett_trace_block_type, bits_trace_block_type,
+ ENC_LITTLE_ENDIAN);
+
+ /* get seconds part */
+ timestamp.secs = tvb_get_letohl(tvb, 1);
+
+ /* get milliseconds part */
+ timestamp.nsecs = (int) tvb_get_letohs(tvb, 5) * 1000000;
+
+ /* add timestamp */
+ ti = proto_tree_add_time(trace_tree, hf_trace_timestamp, tvb, 1,
+ 6, &timestamp);
+
+ /* create timestamp sub-tree */
+ stamp_tree = proto_item_add_subtree(ti, ett_trace_timestamp);
+
+ /* add seconds part */
+ proto_tree_add_item(stamp_tree, hf_trace_timestamp_sec,
+ tvb, 1, 4, ENC_LITTLE_ENDIAN);
+
+ /* add milliseconds part */
+ proto_tree_add_item(stamp_tree, hf_trace_timestamp_msec,
+ tvb, 5, 2, ENC_LITTLE_ENDIAN);
+
+ /* add trace data type */
+ proto_tree_add_item(trace_tree, hf_trace_data_type,
+ tvb, 7, 1, ENC_LITTLE_ENDIAN);
+
+ if (data_type == IPMI_PROTO_IPMB_1_0) {
+ /* add ipmb-specific data */
+ proto_tree_add_bitmask(trace_tree, tvb, 8,
+ hf_trace_protocol_data, ett_trace_protocol_data,
+ bits_ipmb_protocol_data, ENC_LITTLE_ENDIAN);
+ } else if (data_type == IPMI_PROTO_KCS
+ || data_type == IPMI_PROTO_SMIC
+ || data_type == IPMI_PROTO_BT_10
+ || data_type == IPMI_PROTO_BT_15) {
+ /* add host-specific data */
+ proto_tree_add_bitmask(trace_tree, tvb, 8,
+ hf_trace_protocol_data, ett_trace_protocol_data,
+ bits_host_protocol_data, ENC_LITTLE_ENDIAN);
+ } else {
+ /* add protocol specific data */
+ proto_tree_add_item(trace_tree, hf_trace_protocol_data, tvb,
+ 8, 2, ENC_LITTLE_ENDIAN);
+ }
+
+ /* add data length*/
+ proto_tree_add_item(trace_tree, hf_trace_data_len, tvb,
+ 10, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ /* get pointer to remaining data buffer */
+ next_tvb = tvb_new_subset_remaining(tvb, 11);
+
+ if (block_type == HPM2_TRACE_PACKET_DATA) {
+ ipmi_dissect_arg_t arg;
+
+ /* setup IPMI protocol argument */
+ arg.context = IPMI_E_NONE;
+ arg.channel = chn_num;
+ arg.flags = tvb_get_guint8(tvb, 8);
+
+ if (!dissector_try_uint_new(proto_dissector_table,
+ data_type, next_tvb, pinfo, tree, TRUE, &arg)) {
+ call_dissector(data_dissector_handle, next_tvb,
+ pinfo, tree);
+ }
+ } else if (block_type == HPM2_CHN_STATE_NOTIFY
+ && data_type == IPMI_PROTO_IPMB_1_0) {
+ dissect_ipmb_state_notify(next_tvb, tree);
+ } else {
+ call_dissector(data_dissector_handle, next_tvb, pinfo, tree);
+ }
+}
+
+void
+proto_register_ipmi_trace(void)
+{
+ /* register protocol for HPM.2 trace data block */
+ proto_ipmi_trace = proto_register_protocol("IPMI Trace Data Collection",
+ "ipmi-trace", "ipmi-trace");
+
+ /* register HPM.2 header fields */
+ proto_register_field_array(proto_ipmi_trace, ipmi_trace_hf,
+ array_length(ipmi_trace_hf));
+
+ /* register HPM.2 sub-tree indices */
+ proto_register_subtree_array(ipmi_trace_ett,
+ array_length(ipmi_trace_ett));
+
+ /* register dissector table for IPMI messaging protocols */
+ proto_dissector_table = register_dissector_table("ipmi.protocol",
+ "IPMI Channel Protocol Type", FT_UINT8, BASE_HEX);
+}
+
+void
+proto_reg_handoff_ipmi_trace(void)
+{
+ dissector_handle_t ipmi_trace_handle;
+
+ ipmi_trace_handle = create_dissector_handle(dissect_ipmi_trace,
+ proto_ipmi_trace);
+
+ data_dissector_handle = find_dissector("data");
+
+ dissector_add_uint("wtap_encap", WTAP_ENCAP_IPMI_TRACE, ipmi_trace_handle);
+
+ dissector_add_uint("ipmi.protocol", IPMI_PROTO_IPMB_1_0,
+ find_dissector("ipmb"));
+ dissector_add_uint("ipmi.protocol", IPMI_PROTO_KCS,
+ find_dissector("kcs"));
+ dissector_add_uint("ipmi.protocol", IPMI_PROTO_TMODE,
+ find_dissector("tmode"));
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */
diff --git a/epan/dissectors/packet-ipmi-transport.c b/epan/dissectors/packet-ipmi-transport.c
index 30591496b1..acfa0bf97c 100644
--- a/epan/dissectors/packet-ipmi-transport.c
+++ b/epan/dissectors/packet-ipmi-transport.c
@@ -868,7 +868,7 @@ lan_19(tvbuff_t *tvb, proto_tree *tree)
return;
}
- proto_tree_add_item(tree, hf_ipmi_trn_lan19_address, tvb, 2, tvb_length(tvb) - 2, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_lan19_address, tvb, 2, -1, ENC_NA);
}
static void
@@ -956,7 +956,7 @@ lan_25(tvbuff_t *tvb, proto_tree *tree)
byte34, ENC_LITTLE_ENDIAN, 0);
break;
default:
- proto_tree_add_item(tree, hf_ipmi_trn_lan25_address, tvb, 2, tvb_length(tvb) - 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ipmi_trn_lan25_address, tvb, 2, -1, ENC_LITTLE_ENDIAN);
break;
}
}
@@ -1017,11 +1017,10 @@ rq01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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);
+ next = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_01_param_data, tvb, 2, -1, ENC_NA);
}
}
@@ -1044,9 +1043,10 @@ rq02(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
pno = tvb_get_guint8(tvb, 1);
+ ipmi_set_data(pinfo, 0, pno);
+ ipmi_set_data(pinfo, 1, tvb_get_guint8(tvb, 0) & 0x80);
+
if (!tree) {
- ipmi_setsaveddata(0, pno);
- ipmi_setsaveddata(1, tvb_get_guint8(tvb, 0) & 0x80);
return;
}
@@ -1078,18 +1078,18 @@ rs02(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
ett_ipmi_trn_02_rev, byte1, ENC_LITTLE_ENDIAN, 0);
- if (!ipmi_getsaveddata(0, &pno) || !ipmi_getsaveddata(1, &req)) {
+ if (!ipmi_get_data(pinfo, 0, &pno) || !ipmi_get_data(pinfo, 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, ENC_NA);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_trn_02_param_data, tvb, 1, -1, ENC_NA);
};
return;
}
- if ((req & 0x80) && tvb_length(tvb) > 1) {
+ if ((req & 0x80) && tvb_captured_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) {
+ } else if (!(req & 0x80) && tvb_captured_length(tvb) == 1) {
ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned");
PROTO_ITEM_SET_GENERATED(ti);
}
@@ -1105,13 +1105,12 @@ rs02(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc);
PROTO_ITEM_SET_GENERATED(ti);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
if (pno < array_length(lan_options)) {
- next = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
+ next = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_02_param_data, tvb, 1, -1, ENC_NA);
}
}
}
@@ -1271,7 +1270,7 @@ static void
serial_10(tvbuff_t *tvb, proto_tree *tree)
{
proto_tree_add_item(tree, hf_ipmi_trn_serial10_set_sel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ipmi_trn_serial10_init_str, tvb, 1, tvb_length(tvb) - 1, ENC_ASCII|ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_serial10_init_str, tvb, 1, -1, ENC_ASCII|ENC_NA);
}
static void
@@ -1574,7 +1573,7 @@ serial_40(tvbuff_t *tvb, proto_tree *tree)
int slen;
proto_tree_add_item(tree, hf_ipmi_trn_serial40_acct_sel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- slen = tvb_length(tvb) - 1;
+ slen = tvb_captured_length(tvb) - 1;
if (slen > 16) {
slen = 16;
}
@@ -1587,7 +1586,7 @@ serial_41(tvbuff_t *tvb, proto_tree *tree)
int slen;
proto_tree_add_item(tree, hf_ipmi_trn_serial41_acct_sel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- slen = tvb_length(tvb) - 1;
+ slen = tvb_captured_length(tvb) - 1;
if (slen > 16) {
slen = 16;
}
@@ -1600,7 +1599,7 @@ serial_42(tvbuff_t *tvb, proto_tree *tree)
int slen;
proto_tree_add_item(tree, hf_ipmi_trn_serial42_acct_sel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- slen = tvb_length(tvb) - 1;
+ slen = tvb_captured_length(tvb) - 1;
if (slen > 16) {
slen = 16;
}
@@ -1655,7 +1654,7 @@ serial_49(tvbuff_t *tvb, proto_tree *tree)
int slen;
proto_tree_add_item(tree, hf_ipmi_trn_serial49_blockno, tvb, 0, 1, ENC_LITTLE_ENDIAN);
- slen = tvb_length(tvb) - 1;
+ slen = tvb_captured_length(tvb) - 1;
if (slen > 16) {
slen = 16;
}
@@ -1784,11 +1783,10 @@ rq10(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
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);
+ next = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_10_param_data, tvb, 2, -1, ENC_NA);
}
}
@@ -1811,9 +1809,10 @@ rq11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
pno = tvb_get_guint8(tvb, 1);
+ ipmi_set_data(pinfo, 0, pno);
+ ipmi_set_data(pinfo, 1, tvb_get_guint8(tvb, 0));
+
if (!tree) {
- ipmi_setsaveddata(0, pno);
- ipmi_setsaveddata(1, tvb_get_guint8(tvb, 0));
return;
}
@@ -1845,10 +1844,10 @@ rs11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
ett_ipmi_trn_11_rev, byte1, ENC_LITTLE_ENDIAN, 0);
- if (!ipmi_getsaveddata(0, &pno) || !ipmi_getsaveddata(1, &req)) {
+ if (!ipmi_get_data(pinfo, 0, &pno) || !ipmi_get_data(pinfo, 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, ENC_NA);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_ipmi_trn_11_param_data, tvb, 1, -1, ENC_NA);
};
return;
}
@@ -1861,10 +1860,10 @@ rs11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
desc = "Reserved";
}
- if ((req & 0x80) && tvb_length(tvb) > 1) {
+ if ((req & 0x80) && tvb_captured_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) {
+ } else if (!(req & 0x80) && tvb_captured_length(tvb) == 1) {
ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned");
PROTO_ITEM_SET_GENERATED(ti);
}
@@ -1872,13 +1871,12 @@ rs11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc);
PROTO_ITEM_SET_GENERATED(ti);
- if (tvb_length(tvb) > 1) {
+ if (tvb_captured_length(tvb) > 1) {
if (pno < array_length(serial_options)) {
- next = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
+ next = tvb_new_subset_remaining(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, ENC_NA);
+ proto_tree_add_item(tree, hf_ipmi_trn_11_param_data, tvb, 1, -1, ENC_NA);
}
}
}
@@ -2001,9 +1999,9 @@ rq17(tvbuff_t *tvb, packet_info *pinfo _U_, 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 };
+ ipmi_set_data(pinfo, 0, tvb_get_guint8(tvb, 1) & 0x7f);
if (!tree) {
/* Save block number */
- ipmi_setsaveddata(0, tvb_get_guint8(tvb, 1) & 0x7f);
return;
}
@@ -2018,12 +2016,12 @@ rs17(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
guint32 bno;
- if (ipmi_getsaveddata(0, &bno) && bno == 0) {
+ if (ipmi_get_data(pinfo, 0, &bno) && bno == 0) {
/* Request for length */
proto_tree_add_item(tree, hf_ipmi_trn_17_size, tvb, 0, 2, ENC_LITTLE_ENDIAN);
} else {
proto_tree_add_item(tree, hf_ipmi_trn_17_data, tvb, 0,
- tvb_length(tvb) < 16 ? tvb_length(tvb) : 16, ENC_NA);
+ tvb_captured_length(tvb) < 16 ? tvb_captured_length(tvb) : 16, ENC_NA);
}
}
diff --git a/epan/dissectors/packet-ipmi-vita.c b/epan/dissectors/packet-ipmi-vita.c
new file mode 100755
index 0000000000..d41b33d654
--- /dev/null
+++ b/epan/dissectors/packet-ipmi-vita.c
@@ -0,0 +1,1325 @@
+/* packet-ipmi-vita.c
+ * Sub-dissectors for IPMI messages (netFn=Group, defining body = VSO)
+ * Copyright 2014, Dmitry Bazhenov, Pigeon Point Systems <dima_b@pigeonpoint.com>
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+
+#include "packet-ipmi.h"
+
+/* Tree type identifiers.
+*/
+static gint ett_vita_ipmc = -1;
+static gint ett_vita_ipmb = -1;
+static gint ett_vita_vso = -1;
+static gint ett_vita_led_caps = -1;
+static gint ett_vita_led_color = -1;
+static gint ett_vita_led_flags = -1;
+static gint ett_vita_led_states = -1;
+static gint ett_vita_ipmb_state = -1;
+static gint ett_vita_fru_policy_bits = -1;
+static gint ett_vita_fan_properties = -1;
+static gint ett_vita_fru_control_caps = -1;
+static gint ett_vita_chassis_addr_type = -1;
+static gint ett_vita_chassis_addr = -1;
+static gint ett_vita_persistent_control_state = -1;
+static gint ett_vita_persistent_control_caps = -1;
+
+/* Field identifiers.
+*/
+static gint hf_vita_reserved = -1;
+static gint hf_vita_fruid = -1;
+static gint hf_vita_addr_key_type = -1;
+static gint hf_vita_addr_key = -1;
+static gint hf_vita_hw_addr = -1;
+static gint hf_vita_ipmb_addr = -1;
+static gint hf_vita_site_type = -1;
+static gint hf_vita_site_num = -1;
+static gint hf_vita_ipmbl_addr = -1;
+
+static gint hf_vita_ipmc = -1;
+static gint hf_vita_tier = -1;
+static gint hf_vita_layer = -1;
+static gint hf_vita_ipmb = -1;
+static gint hf_vita_ipmb_itfs = -1;
+static gint hf_vita_ipmb_freq = -1;
+static gint hf_vita_vso = -1;
+static gint hf_vita_vso_std = -1;
+static gint hf_vita_rev = -1;
+static gint hf_vita_max_fruid = -1;
+static gint hf_vita_ipmc_fruid = -1;
+static gint hf_vita_fru_control = -1;
+
+static gint hf_vita_led_count = -1;
+static gint hf_vita_led_id = -1;
+static gint hf_vita_led_caps = -1;
+static gint hf_vita_led_cap_blue = -1;
+static gint hf_vita_led_cap_red = -1;
+static gint hf_vita_led_cap_green = -1;
+static gint hf_vita_led_cap_amber = -1;
+static gint hf_vita_led_cap_orange = -1;
+static gint hf_vita_led_cap_white = -1;
+static gint hf_vita_led_def_loc_color = -1;
+static gint hf_vita_led_def_ovr_color = -1;
+static gint hf_vita_led_color = -1;
+static gint hf_vita_led_flags = -1;
+static gint hf_vita_led_flag_pwr = -1;
+static gint hf_vita_led_flag_hw_restrict = -1;
+static gint hf_vita_led_states = -1;
+static gint hf_vita_led_loc_func = -1;
+static gint hf_vita_led_loc_duration = -1;
+static gint hf_vita_led_loc_color = -1;
+static gint hf_vita_led_ovr_func = -1;
+static gint hf_vita_led_ovr_duration = -1;
+static gint hf_vita_led_ovr_color = -1;
+static gint hf_vita_led_lamp_test_duration = -1;
+static gint hf_vita_led_state_local = -1;
+static gint hf_vita_led_state_override = -1;
+static gint hf_vita_led_state_lamp_test = -1;
+static gint hf_vita_led_state_hw_restrict = -1;
+
+static gint hf_vita_ipmba_state = -1;
+static gint hf_vita_ipmbb_state = -1;
+static gint hf_vita_ipmb_state = -1;
+static gint hf_vita_ipmb_link_id = -1;
+
+static gint hf_vita_fru_policy_mask_bits = -1;
+static gint hf_vita_fru_policy_set_bits = -1;
+static gint hf_vita_fru_policy_bits = -1;
+static gint hf_vita_fru_activation_locked = -1;
+static gint hf_vita_fru_deactivation_locked = -1;
+static gint hf_vita_fru_commanded_deactivation_ignored = -1;
+static gint hf_vita_fru_default_activation_locked = -1;
+
+static gint hf_vita_fru_activation = -1;
+
+static gint hf_vita_record_id = -1;
+
+static gint hf_vita_fan_min_level = -1;
+static gint hf_vita_fan_max_level = -1;
+static gint hf_vita_fan_norm_level = -1;
+static gint hf_vita_fan_properties = -1;
+static gint hf_vita_fan_prop_local_control = -1;
+static gint hf_vita_fan_override_level = -1;
+static gint hf_vita_fan_local_level = -1;
+static gint hf_vita_fan_local_control = -1;
+
+static gint hf_vita_ipmb_link_key_type = -1;
+static gint hf_vita_ipmb_link_key_value = -1;
+static gint hf_vita_ipmb_link_number = -1;
+static gint hf_vita_ipmb_sensor_number = -1;
+
+static gint hf_vita_active_chmc_ipmb_addr = -1;
+static gint hf_vita_backup_chmc_ipmb_addr = -1;
+
+static gint hf_vita_fan_number = -1;
+static gint hf_vita_fan_policy = -1;
+static gint hf_vita_fan_policy_timeout = -1;
+static gint hf_vita_fan_coverage = -1;
+
+static gint hf_vita_fru_control_caps = -1;
+static gint hf_vita_fru_control_cap_cold = -1;
+static gint hf_vita_fru_control_cap_warm = -1;
+static gint hf_vita_fru_control_cap_grace = -1;
+static gint hf_vita_fru_control_cap_diag = -1;
+static gint hf_vita_fru_control_cap_pwr = -1;
+
+static gint hf_vita_fru_lock_operation = -1;
+static gint hf_vita_fru_lock_id = -1;
+static gint hf_vita_fru_lock_timestamp = -1;
+
+static gint hf_vita_fru_write_offset = -1;
+static gint hf_vita_fru_write_data = -1;
+static gint hf_vita_fru_write_count = -1;
+
+static gint hf_vita_chassis_addr_number = -1;
+static gint hf_vita_chassis_addr_timestamp = -1;
+static gint hf_vita_chassis_addr_count = -1;
+static gint hf_vita_chassis_max_unavail = -1;
+static gint hf_vita_chassis_addr_type = -1;
+static gint hf_vita_chassis_addr = -1;
+static gint hf_vita_chassis_addr_chmc = -1;
+static gint hf_vita_chassis_addr_format = -1;
+static gint hf_vita_ipv4_addr = -1;
+static gint hf_vita_rmcp_port = -1;
+
+static gint hf_vita_persistent_control_state = -1;
+static gint hf_vita_persistent_control_cold = -1;
+static gint hf_vita_persistent_control_warm = -1;
+static gint hf_vita_persistent_control_mask = -1;
+static gint hf_vita_persistent_control_set = -1;
+static gint hf_vita_persistent_control_caps = -1;
+static gint hf_vita_persistent_control_cap_cold = -1;
+static gint hf_vita_persistent_control_cap_warm = -1;
+
+static gint hf_vita_fru_state_sensor_num = -1;
+static gint hf_vita_fru_health_sensor_num = -1;
+static gint hf_vita_fru_voltage_sensor_num = -1;
+static gint hf_vita_fru_temp_sensor_num = -1;
+static gint hf_vita_payload_test_results_sensor_num = -1;
+static gint hf_vita_payload_test_status_sensor_num = -1;
+
+/* String values.
+*/
+static const value_string str_vita_ipmc_tiers[] = {
+ { 0x00, "Tier-1" },
+ { 0x01, "Tier-2" },
+ { 0x02, "Reserved" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_ipmc_layers[] = {
+ { 0x00, "IPMC" },
+ { 0x01, "Chassis Manager" },
+ { 0x02, "System Manager" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_ipmb_itfs[] = {
+ { 0x00, "1 IPMB interface" },
+ { 0x01, "2 IPMB interfaces" },
+ { 0x02, "Reserved" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_ipmb_freq[] = {
+ { 0x00, "100KHz" },
+ { 0x01, "400KHz" },
+ { 0x02, "Reserved" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_vso_std[] = {
+ { 0x00, "VITA 46.11" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_addr_key_types[] = {
+ { 0x00, "Hardware Address" },
+ { 0x01, "IPMB Address" },
+ { 0x02, "Reserved" },
+ { 0x03, "Physical Address" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_site_types[] = {
+ { 0x00, "Front Loading VPX Plug-In Module" },
+ { 0x01, "Power Entry Module" },
+ { 0x02, "Chassis FRU Information Module" },
+ { 0x03, "Dedicated ChMC" },
+ { 0x04, "Fan Tray" },
+ { 0x05, "Fan Tray Filter" },
+ { 0x06, "Alarm Panel" },
+ { 0x07, "XMC" },
+ { 0x08, "Reserved" },
+ { 0x09, "VPX Rear Transition Module" },
+ { 0x0A, "Reserved" },
+ { 0x0B, "Reserved" },
+ { 0x0C, "Power Supply" },
+ { 0x0D, "Reserved" },
+ { 0x0E, "Reserved" },
+ { 0x0F, "FMC" },
+ { 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 value_string_ext str_vita_site_types_ext = VALUE_STRING_EXT_INIT(str_vita_site_types);
+
+static const value_string str_vita_fru_controls[] = {
+ { 0x00, "Cold Reset" },
+ { 0x01, "Warm Reset" },
+ { 0x02, "Graceful Reboot" },
+ { 0x03, "Diagnostic Interrupt" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_led_colors[] = {
+ { 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 range_string str_vita_led_func[] = {
+ { 0x00, 0x00, "LED off" },
+ { 0x01, 0xFA, "LED BLINKING (off duration)" },
+ { 0xFB, 0xFB, "LAMP TEST" },
+ { 0xFC, 0xFC, "LED restored to Local Control state" },
+ { 0xFF, 0xFF, "LED on" },
+ { 0, 0, NULL }
+};
+
+static const range_string str_vita_ipmb_state[] = {
+ { 0x0, 0xFE, "System IPMB state" },
+ { 0xFF, 0xFF, "Do not change current state" },
+ { 0, 0, NULL }
+};
+
+static const true_false_string str_vita_ipmb_override = {
+ "Local Control State",
+ "Override state - Isolate(disable)"
+};
+
+static const range_string str_vita_ipmb_link_id[] = {
+ { 0x00, 0x00, "Select all System IPMB Links" },
+ { 0x01, 0x5F, "System IPMB Link Number" },
+ { 0x60, 0x7F, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const value_string str_vita_fru_activation[] = {
+ { 0x00, "Deactivate FRU" },
+ { 0x01, "Activate FRU" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fan_levels[] = {
+ { 0xFE, "Shut Down" },
+ { 0xFF, "Local Control" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fan_local_control[] = {
+ { 0x00, "Disabled" },
+ { 0x01, "Enabled" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_ipmb_link_key_types[] = {
+ { 0x00, "Key is IPMB Link Number" },
+ { 0x01, "Key is IPMB Sensor Number" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fan_policies[] = {
+ { 0x00, "Disable" },
+ { 0x01, "Enable" },
+ { 0xFF, "Indeterminate" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fan_policy_timeouts[] = {
+ { 0xFF, "Infinite" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fan_coverages[] = {
+ { 0x00, "Not Covered" },
+ { 0x01, "Covered" },
+ { 0, NULL }
+};
+
+static const value_string str_vita_fru_lock_operations[] = {
+ { 0x00, "Get Last Commit Timestamp" },
+ { 0x01, "Lock" },
+ { 0x02, "Unlock and Discard" },
+ { 0x03, "Unlock and Commit " },
+ { 0, NULL }
+};
+
+static const range_string str_vita_chassis_addr_formats[] = {
+ { 0x00, 0x00, "IPv4 Address" },
+ { 0x01, 0x5F, "Reserved" },
+ { 0x60, 0x7F, "OEM" },
+ { 0, 0, NULL }
+};
+
+
+static const value_string cc1F[] = {
+ { 0x80, "Invalid FRU Information" },
+ { 0x81, "Lock Failed" },
+ { 0, NULL }
+};
+
+static const value_string cc20[] = {
+ { 0x80, "Invalid Lock ID" },
+ { 0, NULL }
+};
+
+
+/* Array of sub-tree identifiers (needed for registration).
+*/
+static gint * const ett_ipmi_vita[] = {
+ &ett_vita_ipmc,
+ &ett_vita_ipmb,
+ &ett_vita_vso,
+ &ett_vita_led_caps,
+ &ett_vita_led_color,
+ &ett_vita_led_flags,
+ &ett_vita_led_states,
+ &ett_vita_ipmb_state,
+ &ett_vita_fru_policy_bits,
+ &ett_vita_fan_properties,
+ &ett_vita_fru_control_caps,
+ &ett_vita_chassis_addr_type,
+ &ett_vita_chassis_addr,
+ &ett_vita_persistent_control_state,
+ &ett_vita_persistent_control_caps
+};
+
+static const int * bits_vita_led_color[] = {
+ &hf_vita_led_color,
+ NULL
+};
+
+static const int * bits_vita_fru_policy_bits[] = {
+ &hf_vita_fru_activation_locked,
+ &hf_vita_fru_deactivation_locked,
+ &hf_vita_fru_commanded_deactivation_ignored,
+ &hf_vita_fru_default_activation_locked,
+ NULL
+};
+
+static const int * bits_vita_persistent_control_state[] = {
+ &hf_vita_persistent_control_cold,
+ &hf_vita_persistent_control_warm,
+ NULL
+};
+
+/* Array of field descriptors.
+*/
+static hf_register_info hf_ipmi_vita[] = {
+ { &hf_vita_ipmc,
+ { "IPMC Identifier", "ipmi.vita.ipmc",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_tier,
+ { "Tier Functionality", "ipmi.vita.ipmc.tier",
+ FT_UINT8, BASE_HEX, VALS(str_vita_ipmc_tiers), 0x3, NULL, HFILL }},
+ { &hf_vita_layer,
+ { "Layer Functionality", "ipmi.vita.ipmc.tier",
+ FT_UINT8, BASE_HEX, VALS(str_vita_ipmc_layers), 0x30, NULL, HFILL }},
+ { &hf_vita_ipmb,
+ { "IPMB Capabilities", "ipmi.vita.ipmb",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmb_itfs,
+ { "Number of supported interfaces", "ipmi.vita.ipmc.itfs",
+ FT_UINT8, BASE_HEX, VALS(str_vita_ipmb_itfs), 0x3, NULL, HFILL }},
+ { &hf_vita_ipmb_freq,
+ { "Maximum operating frequency", "ipmi.vita.ipmc.freq",
+ FT_UINT8, BASE_HEX, VALS(str_vita_ipmb_freq), 0x30, NULL, HFILL }},
+ { &hf_vita_vso,
+ { "VSO Standard", "ipmi.vita.vso",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_vso_std,
+ { "VSO Standard", "ipmi.vita.vso.std",
+ FT_UINT8, BASE_HEX, VALS(str_vita_vso_std), 0x3, NULL, HFILL }},
+ { &hf_vita_rev,
+ { "VSO Specification Revision", "ipmi.vita.vso.rev",
+ FT_UINT8, BASE_CUSTOM, ipmi_fmt_version, 0, NULL, HFILL }},
+ { &hf_vita_max_fruid,
+ { "Max FRU Device ID", "ipmi.vita.max.fruid",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmc_fruid,
+ { "FRU Device ID for IPMC", "ipmi.vita.ipmc.fruid",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fruid,
+ { "FRU Device ID", "ipmi.vita.fruid",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_addr_key_type,
+ { "Address Key Type", "ipmi.vita.key.type",
+ FT_UINT8, BASE_HEX, VALS(str_vita_addr_key_types), 0, NULL, HFILL }},
+ { &hf_vita_addr_key,
+ { "Address Key", "ipmi.vita.key",
+ FT_UINT8, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_site_type,
+ { "Site Type", "ipmi.vita.site.type",
+ FT_UINT8, BASE_HEX|BASE_EXT_STRING, &str_vita_site_types_ext, 0, NULL, HFILL }},
+ { &hf_vita_hw_addr,
+ { "Hardware Address", "ipmi.vita.hwaddr",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmb_addr,
+ { "IPMB Address", "ipmi.vita.ipmb.addr",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_site_num,
+ { "Site Number", "ipmi.vita.site.num",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmbl_addr,
+ { "Address on IPMI Channel 7", "ipmi.vita.ipmbl.addr",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_reserved,
+ { "Reserved", "ipmi.vita.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_control,
+ { "FRU Control", "ipmi.vita.fru.control",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fru_controls), 0, NULL, HFILL }},
+ { &hf_vita_led_count,
+ { "LED Count", "ipmi.vita.led.count",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_id,
+ { "LED ID", "ipmi.vita.led.id",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_caps,
+ { "LED Color Capabilities", "ipmi.vita.led.caps",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_cap_blue,
+ { "LED supports BLUE", "ipmi.vita.led.cap.blue",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_led_cap_red,
+ { "LED supports RED", "ipmi.vita.led.cap.red",
+ FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_vita_led_cap_green,
+ { "LED supports GREEN", "ipmi.vita.led.cap.green",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_vita_led_cap_amber,
+ { "LED supports AMBER", "ipmi.vita.led.cap.amber",
+ FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
+ { &hf_vita_led_cap_orange,
+ { "LED supports ORANGE", "ipmi.vita.led.cap.orange",
+ FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
+ { &hf_vita_led_cap_white,
+ { "LED supports WHITE", "ipmi.vita.led.cap.white",
+ FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
+ { &hf_vita_led_def_loc_color,
+ { "Default LED Color in Local Control State", "ipmi.vita.led.def.loc.color",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_def_ovr_color,
+ { "Default LED Color in Override State", "ipmi.vita.led.def.ovr.color",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_flags,
+ { "LED Flags", "ipmi.vita.led.flags",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_flag_pwr,
+ { "LED is powered from Payload power", "ipmi.vita.led.flag.pwr",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_led_flag_hw_restrict,
+ { "LED has other hardware restrictions", "ipmi.vita.led.flag.hw.restrict",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_led_color,
+ { "LED Color Value", "ipmi.vita.led.color",
+ FT_UINT8, BASE_HEX, VALS(str_vita_led_colors), 0x0F, NULL, HFILL }},
+ { &hf_vita_led_ovr_func,
+ { "Override State LED Function", "ipmi.vita.led.ovr.func",
+ FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(str_vita_led_func), 0, NULL, HFILL }},
+ { &hf_vita_led_ovr_duration,
+ { "Override State On-Duration", "ipmi.vita.led.ovr.diration",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_ovr_color,
+ { "Override State Color", "ipmi.vita.led.ovr.color",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_lamp_test_duration,
+ { "Lamp Test Duration", "ipmi.vita.led.lamp.duration",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_loc_func,
+ { "Local Control LED Function", "ipmi.vita.led.loc.func",
+ FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(str_vita_led_func), 0, NULL, HFILL }},
+ { &hf_vita_led_loc_duration,
+ { "Local Control On-Duration", "ipmi.vita.led.loc.diration",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_loc_color,
+ { "Local Control Color", "ipmi.vita.led.loc.color",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_states,
+ { "LED States", "ipmi.vita.led.states",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_led_state_local,
+ { "Local Control State", "ipmi.vita.led.state.loc",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_led_state_override,
+ { "Override State", "ipmi.vita.led.state.ovr",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_led_state_lamp_test,
+ { "Lamp Test", "ipmi.vita.led.state.lamp",
+ FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_vita_led_state_hw_restrict,
+ { "Hardware Restriction", "ipmi.vita.led.state.hw",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_vita_ipmba_state,
+ { "IPMB-A State", "ipmi.vita.ipmba.state",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(str_vita_ipmb_state), 0, NULL, HFILL }},
+ { &hf_vita_ipmbb_state,
+ { "IPMB-B State", "ipmi.vita.ipmbb.state",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(str_vita_ipmb_state), 0, NULL, HFILL }},
+ { &hf_vita_ipmb_state,
+ { "IPMB State", "ipmi.vita.ipmb.ovr",
+ FT_BOOLEAN, 8, TFS(&str_vita_ipmb_override), 0x01, NULL, HFILL }},
+ { &hf_vita_ipmb_link_id,
+ { "IPMB Link ID", "ipmi.vita.ipmb.link.id",
+ FT_UINT8, BASE_DEC_HEX|BASE_RANGE_STRING, RVALS(str_vita_ipmb_link_id), 0xFE, NULL, HFILL }},
+ { &hf_vita_fru_policy_mask_bits,
+ { "FRU Activation Policy Mask Bits", "ipmi.vita.fru.policy.mask",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_policy_set_bits,
+ { "FRU Activation Policy Set Bits", "ipmi.vita.fru.policy.set",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_policy_bits,
+ { "FRU Activation Policies", "ipmi.vita.fru.policy.bits",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_activation_locked,
+ { "Activation Locked", "ipmi.vita.fru.policy.al",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_fru_deactivation_locked,
+ { "Deactivation Locked", "ipmi.vita.fru.policy.dl",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_fru_commanded_deactivation_ignored,
+ { "Commanded Deactivation Ignored", "ipmi.vita.fru.policy.cdi",
+ FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_vita_fru_default_activation_locked,
+ { "Default Activation Locked", "ipmi.vita.fru.policy.dal",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_vita_fru_activation,
+ { "FRU Activation/Deactivation", "ipmi.vita.fru.activation",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fru_activation), 0, NULL, HFILL }},
+ { &hf_vita_record_id,
+ { "Record ID", "ipmi.vita.record.id",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_min_level,
+ { "Minimum Speed Level", "ipmi.vita.fan.min",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_max_level,
+ { "Maximum Speed Level", "ipmi.vita.fan.max",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_norm_level,
+ { "Normal Operating Level", "ipmi.vita.fan.norm",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_properties,
+ { "Fan Tray Properties", "ipmi.vita.fan.props",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_prop_local_control,
+ { "Local Control Supported", "ipmi.vita.fan.prop.lc",
+ FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
+ { &hf_vita_fan_override_level,
+ { "Override Fan Level", "ipmi.vita.fan.ovr",
+ FT_UINT8, BASE_HEX, VALS(str_vita_fan_levels), 0, NULL, HFILL }},
+ { &hf_vita_fan_local_level,
+ { "Local Control Fan Level", "ipmi.vita.fan.loc",
+ FT_UINT8, BASE_HEX, VALS(str_vita_fan_levels), 0, NULL, HFILL }},
+ { &hf_vita_fan_local_control,
+ { "Local Control Enable State", "ipmi.vita.fan.lc",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fan_local_control), 0, NULL, HFILL }},
+ { &hf_vita_ipmb_link_key_type,
+ { "IPMB Link Info Key Type", "ipmi.vita.ipmb.link.key.type",
+ FT_UINT8, BASE_DEC, VALS(str_vita_ipmb_link_key_types), 0, NULL, HFILL }},
+ { &hf_vita_ipmb_link_key_value,
+ { "IPMB Link Info Key", "ipmi.vita.ipmb.link.key.value",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmb_link_number,
+ { "IPMB Link Number", "ipmi.vita.ipmb.link.number",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_ipmb_sensor_number,
+ { "IPMB Sensor Number", "ipmi.vita.ipmb.sensor.number",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_active_chmc_ipmb_addr,
+ { "Active Chassis Manager IPMB Address", "ipmi.vita.active.chmc.ipmb.addr",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_backup_chmc_ipmb_addr,
+ { "Backup Chassis Manager IPMB Address", "ipmi.vita.backup.chmc.ipmb.addr",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_number,
+ { "Fan Tray Site Number", "ipmi.vita.fan.num",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fan_policy,
+ { "Fan Enable State", "ipmi.vita.fan.policy",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fan_policies), 0, NULL, HFILL }},
+ { &hf_vita_fan_policy_timeout,
+ { "Fan Policy Timeout", "ipmi.vita.fan.policy.timeout",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fan_policy_timeouts), 0, NULL, HFILL }},
+ { &hf_vita_fan_coverage,
+ { "Coverage", "ipmi.vita.fan.coverage",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fan_coverages), 0, NULL, HFILL }},
+ { &hf_vita_fru_control_caps,
+ { "FRU Control Capabilities Mask", "ipmi.vita.fru.control.caps",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_control_cap_cold,
+ { "Capable of issuing a cold reset", "ipmi.vita.fru.control.cap.cold",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_fru_control_cap_warm,
+ { "Capable of issuing a warm reset", "ipmi.vita.fru.control.cap.warm",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_fru_control_cap_grace,
+ { "Capable of issuing a graceful reboot", "ipmi.vita.fru.control.cap.grace",
+ FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
+ { &hf_vita_fru_control_cap_diag,
+ { "Capable of issuing a diagnostic interrupt", "ipmi.vita.fru.control.cap.diag",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
+ { &hf_vita_fru_control_cap_pwr,
+ { "Capable of controlling payload power", "ipmi.vita.fru.control.cap.pwr",
+ FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
+ { &hf_vita_fru_lock_operation,
+ { "FRU Inventory Device Lock Operation", "ipmi.vita.fru.lock.op",
+ FT_UINT8, BASE_DEC, VALS(str_vita_fru_lock_operations), 0, NULL, HFILL }},
+ { &hf_vita_fru_lock_id,
+ { "FRU Inventory Device Lock ID", "ipmi.vita.fru.lock.id",
+ FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_lock_timestamp,
+ { "FRU Inventory Device Last Commit Timestamp", "ipmi.vita.fru.lock.stamp",
+ FT_UINT32, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_write_offset,
+ { "FRU Inventory offset to write", "ipmi.vita.fru.write.offset",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_write_data,
+ { "Data to write", "ipmi.vita.fru.write.data",
+ FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_write_count,
+ { "Written byte count", "ipmi.vita.fru.write.count",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr_number,
+ { "Address Number", "ipmi.vita.chassis.addr.num",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr_timestamp,
+ { "Chassis IP Address Last Change Timestamp", "ipmi.vita.chassis.stamp",
+ FT_UINT32, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr_count,
+ { "Address Count", "ipmi.vita.chassis.addr.count",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_max_unavail,
+ { "Maximum Unavailable Time", "ipmi.vita.chassis.max.unavail",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr_type,
+ { "Address Type", "ipmi.vita.chassis.addr.type",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr,
+ { "Address", "ipmi.vita.chassis.addr",
+ FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_vita_chassis_addr_chmc,
+ { "Chassis Manager IP Address", "ipmi.vita.chassis.addr.chmc",
+ FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
+ { &hf_vita_chassis_addr_format,
+ { "Address Type", "ipmi.vita.chassis.addr.format",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(str_vita_chassis_addr_formats), 0x7F, NULL, HFILL }},
+ { &hf_vita_ipv4_addr,
+ { "IPv4 Address", "ipmi.vita.ipv4.addr",
+ FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &hf_vita_rmcp_port,
+ { "RMCP Port", "ipmi.vita.rmcp.port",
+ FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_vita_persistent_control_state,
+ { "FRU Persistent Control Current State", "ipmi.vita.pers.state",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_persistent_control_cold,
+ { "Persistent Cold Reset State", "ipmi.vita.pers.state.cold",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_persistent_control_warm,
+ { "Persistent Warm Reset State", "ipmi.vita.pers.state.warm",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_persistent_control_mask,
+ { "FRU Persistent Control Selection Mask", "ipmi.vita.pers.mask",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_persistent_control_set,
+ { "FRU Persistent Control Selection", "ipmi.vita.pers.set",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_persistent_control_caps,
+ { "FRU Persistent Control Capabilities Mask", "ipmi.vita.pers.caps",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_persistent_control_cap_cold,
+ { "Capable of asserting a persistent cold reset", "ipmi.vita.pers.cap.cold",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
+ { &hf_vita_persistent_control_cap_warm,
+ { "Capable of asserting a persistent warm reset", "ipmi.vita.pers.cap.warm",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
+ { &hf_vita_fru_state_sensor_num,
+ { "FRU State Sensor Number", "ipmi.vita.sensor.fru.state",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_health_sensor_num,
+ { "FRU Health Sensor Number", "ipmi.vita.sensor.fru.health",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_voltage_sensor_num,
+ { "FRU Voltage Sensor Number", "ipmi.vita.sensor.fru.voltage",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_fru_temp_sensor_num,
+ { "FRU Temperature Sensor Number", "ipmi.vita.sensor.fru.temp",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_payload_test_results_sensor_num,
+ { "Payload Test Results Sensor Number", "ipmi.vita.sensor.payload.test.res",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_vita_payload_test_status_sensor_num,
+ { "Payload Test Status Sensor Number", "ipmi.vita.sensor.payload.test.status",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}
+};
+
+/* Get VSO Capabilities (response).
+ */
+static void
+cmd00_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * bits_vita_ipmc[] = {
+ &hf_vita_tier, &hf_vita_layer, NULL
+ };
+ static const gint * bits_vita_ipmb[] = {
+ &hf_vita_ipmb_itfs, &hf_vita_ipmb_freq, NULL
+ };
+ static const gint * bits_vita_vso[] = {
+ &hf_vita_vso_std, NULL
+ };
+
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_ipmc,
+ ett_vita_ipmc, bits_vita_ipmc, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_vita_ipmb,
+ ett_vita_ipmb, bits_vita_ipmb, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_vita_vso,
+ ett_vita_vso, bits_vita_vso, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_rev, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_max_fruid, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_ipmc_fruid, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get Chassis Address Table Info (request).
+*/
+static void
+cmd01_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint len = tvb_captured_length(tvb);
+
+ if (len > 0) {
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (len > 1) {
+ proto_tree_add_item(tree, hf_vita_addr_key_type, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (len > 2) {
+ proto_tree_add_item(tree, hf_vita_addr_key, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (len > 3) {
+ proto_tree_add_item(tree, hf_vita_site_type, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get Chassis Address Table Info (response).
+ */
+static void
+cmd01_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_hw_addr, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_ipmb_addr, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_reserved, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_num, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_type, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 7) {
+ proto_tree_add_item(tree, hf_vita_reserved, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_ipmbl_addr, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get Chassis Identifier (response), Set Chassis Identifier (request)
+*/
+static void
+cmd02_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ ipmi_add_typelen(tree, "Chassis Identifier", tvb, 0, TRUE);
+}
+
+/* FRU Control (request)
+*/
+static void
+cmd04_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_control, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get FRU LED Properties (request)
+*/
+static void
+cmd05_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get FRU LED Properties (response)
+*/
+static void
+cmd05_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_reserved, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_count, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get LED Color Capabilities (request)
+*/
+static void
+cmd06_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_id, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get LED Color Capabilities (response)
+*/
+static void
+cmd06_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const gint * bits_vita_led_caps[] = {
+ &hf_vita_led_cap_white, &hf_vita_led_cap_orange,
+ &hf_vita_led_cap_amber, &hf_vita_led_cap_green,
+ &hf_vita_led_cap_red, &hf_vita_led_cap_blue,
+ NULL
+ };
+ static const int * bits_vita_led_flags[] = {
+ &hf_vita_led_flag_pwr,
+ &hf_vita_led_flag_hw_restrict,
+ NULL
+ };
+
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_led_caps,
+ ett_vita_led_caps, bits_vita_led_caps, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_vita_led_def_loc_color,
+ ett_vita_led_color, bits_vita_led_color, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_vita_led_def_ovr_color,
+ ett_vita_led_color, bits_vita_led_color, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 3, hf_vita_led_flags,
+ ett_vita_led_flags, bits_vita_led_flags, ENC_LITTLE_ENDIAN);
+}
+
+/* Set FRU LED State (request)
+*/
+static void
+cmd07_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_id, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_ovr_func, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_ovr_duration, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 4, hf_vita_led_ovr_color,
+ ett_vita_led_color, bits_vita_led_color, ENC_LITTLE_ENDIAN);
+}
+
+/* Get FRU LED State (response)
+*/
+static void
+cmd08_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * bits_vita_led_states[] = {
+ &hf_vita_led_state_local,
+ &hf_vita_led_state_override,
+ &hf_vita_led_state_lamp_test,
+ &hf_vita_led_state_hw_restrict,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_led_states,
+ ett_vita_led_states, bits_vita_led_states, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_loc_func, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_loc_duration, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 3, hf_vita_led_loc_color,
+ ett_vita_led_color, bits_vita_led_color, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 4) {
+ proto_tree_add_item(tree, hf_vita_led_ovr_func, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_led_ovr_duration, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 6, hf_vita_led_ovr_color,
+ ett_vita_led_color, bits_vita_led_color, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 7) {
+ proto_tree_add_item(tree, hf_vita_led_lamp_test_duration, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Set IPMB State (request)
+*/
+static void
+cmd09_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * bits_vita_ipmb_state[] = {
+ &hf_vita_ipmb_state,
+ &hf_vita_ipmb_link_id,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_ipmba_state,
+ ett_vita_ipmb_state, bits_vita_ipmb_state, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_vita_ipmbb_state,
+ ett_vita_ipmb_state, bits_vita_ipmb_state, ENC_LITTLE_ENDIAN);
+}
+
+/* Set FRU State Policy Bits (request)
+*/
+static void
+cmd0A_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_vita_fru_policy_mask_bits,
+ ett_vita_fru_policy_bits, bits_vita_fru_policy_bits,
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_vita_fru_policy_set_bits,
+ ett_vita_fru_policy_bits, bits_vita_fru_policy_bits,
+ ENC_LITTLE_ENDIAN);
+}
+
+/* Get FRU State Policy Bits (response)
+*/
+static void
+cmd0B_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_fru_policy_bits,
+ ett_vita_fru_policy_bits, bits_vita_fru_policy_bits,
+ ENC_LITTLE_ENDIAN);
+}
+
+/* Set FRU Activation (request)
+*/
+static void
+cmd0C_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_activation, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get FRU Device Locator Record ID (response)
+*/
+static void
+cmd0D_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_record_id, tvb, 0, 2, ENC_LITTLE_ENDIAN);
+}
+
+/* Get FAN Speed Properties (response)
+*/
+static void
+cmd14_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * bits_vita_fan_properties[] = {
+ &hf_vita_fan_prop_local_control,
+ NULL
+ };
+ proto_tree_add_item(tree, hf_vita_fan_min_level, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fan_max_level, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fan_norm_level, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 3, hf_vita_fan_properties,
+ ett_vita_fan_properties, bits_vita_fan_properties, ENC_LITTLE_ENDIAN);
+}
+
+/* Set FAN Level (request)
+*/
+static void
+cmd15_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fan_override_level, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_vita_fan_local_control, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get FAN Level (response)
+*/
+static void
+cmd16_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fan_override_level, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_vita_fan_local_level, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_vita_fan_local_control, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get IPMB Link Info (request)
+*/
+static void
+cmd18_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_ipmb_link_key_type, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_ipmb_link_key_value, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get IPMB Link Info (response)
+*/
+static void
+cmd18_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_ipmb_link_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_ipmb_sensor_number, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get Chassis Manager IPMB Address (response)
+*/
+static void
+cmd1B_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_active_chmc_ipmb_addr, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_backup_chmc_ipmb_addr, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Set FAN Policy (request)
+*/
+static void
+cmd1C_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fan_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fan_policy, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 2) {
+ proto_tree_add_item(tree, hf_vita_fan_policy_timeout, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+ if (tvb_captured_length(tvb) > 3) {
+ proto_tree_add_item(tree, hf_vita_site_num, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_type, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get FAN Policy (request)
+*/
+static void
+cmd1D_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fan_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_vita_site_num, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_type, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* Get FAN Policy (response)
+*/
+static void
+cmd1D_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fan_policy, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ if (tvb_captured_length(tvb) > 1) {
+ proto_tree_add_item(tree, hf_vita_fan_coverage, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ }
+}
+
+/* FRU Control Capabilities (response)
+*/
+static void
+cmd1E_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * bits_vita_fru_control_caps[] = {
+ &hf_vita_fru_control_cap_cold,
+ &hf_vita_fru_control_cap_warm,
+ &hf_vita_fru_control_cap_grace,
+ &hf_vita_fru_control_cap_diag,
+ &hf_vita_fru_control_cap_pwr,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_fru_control_caps,
+ ett_vita_fru_control_caps, bits_vita_fru_control_caps, ENC_LITTLE_ENDIAN);
+}
+
+/* FRU Inventory Device Lock Control (request)
+*/
+static void
+cmd1F_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_lock_operation, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_lock_id, tvb, 2, 2, ENC_LITTLE_ENDIAN);
+}
+
+/* FRU Inventory Device Lock Control (response)
+*/
+static void
+cmd1F_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fru_lock_id, tvb, 0, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_lock_timestamp, tvb, 2, 4, ENC_LITTLE_ENDIAN);
+}
+
+/* FRU Inventory Device Write (request)
+*/
+static void
+cmd20_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_lock_id, tvb, 1, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_write_offset, tvb, 3, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_write_data, tvb, 5,
+ tvb_captured_length(tvb) - 5, ENC_NA);
+}
+
+/* FRU Inventory Device Write (response)
+*/
+static void
+cmd20_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fru_write_count, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get Chassis Manager IP Address (request)
+*/
+static void
+cmd21_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_chassis_addr_number, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Get Chassis Manager IP Address (response)
+*/
+static void
+cmd21_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item * item;
+ static const int * bits_vita_chassis_addr_type[] = {
+ &hf_vita_chassis_addr_chmc,
+ &hf_vita_chassis_addr_format,
+ NULL
+ };
+ proto_tree_add_item(tree, hf_vita_chassis_addr_timestamp, tvb, 0, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_chassis_addr_count, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_type, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_site_num, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_chassis_max_unavail, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 8, hf_vita_chassis_addr_type,
+ ett_vita_chassis_addr_type, bits_vita_chassis_addr_type,
+ ENC_LITTLE_ENDIAN);
+ item = proto_tree_add_item(tree, hf_vita_chassis_addr, tvb, 8, -1, ENC_NA);
+
+ if (!(tvb_get_guint8(tvb, 8) & 0x7f)) {
+ proto_tree * sub = proto_item_add_subtree(item, ett_vita_chassis_addr);
+ proto_tree_add_item(sub, hf_vita_ipv4_addr, tvb, 9, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub, hf_vita_rmcp_port, tvb, 13, 2, ENC_BIG_ENDIAN);
+ }
+}
+
+/* Get FRU Persistent Control (response)
+*/
+static void
+cmd41_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_persistent_control_state,
+ ett_vita_persistent_control_state,
+ bits_vita_persistent_control_state,
+ ENC_LITTLE_ENDIAN);
+}
+
+/* Set FRU Persistent Control (request)
+*/
+static void
+cmd42_rq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fruid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 1, hf_vita_persistent_control_mask,
+ ett_vita_persistent_control_state,
+ bits_vita_persistent_control_state,
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_bitmask(tree, tvb, 2, hf_vita_persistent_control_set,
+ ett_vita_persistent_control_state,
+ bits_vita_persistent_control_state,
+ ENC_LITTLE_ENDIAN);
+}
+
+/* FRU Persistent Control capabilities (response)
+*/
+static void
+cmd43_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ static const int * bits_vita_persistent_control_caps[] = {
+ &hf_vita_persistent_control_cap_cold,
+ &hf_vita_persistent_control_cap_warm,
+ NULL
+ };
+ proto_tree_add_bitmask(tree, tvb, 0, hf_vita_persistent_control_caps,
+ ett_vita_persistent_control_caps,
+ bits_vita_persistent_control_caps,
+ ENC_LITTLE_ENDIAN);
+}
+
+/* Get Mandatory Sensor Numbers (response)
+*/
+static void
+cmd44_rs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_vita_fru_state_sensor_num, tvb, 0, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_health_sensor_num, tvb, 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_voltage_sensor_num, tvb, 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_fru_temp_sensor_num, tvb, 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_payload_test_results_sensor_num, tvb, 4, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_vita_payload_test_status_sensor_num, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+}
+
+/* Array of VITA 46.11 command descriptors.
+*/
+static ipmi_cmd_t cmd_vita[] = {
+ { 0x00, NULL, cmd00_rs, NULL, NULL, "[VITA] Get VSO Capabilities", 0 },
+ { 0x01, cmd01_rq, cmd01_rs, NULL, NULL, "[VITA] Get Chassis Address Table Info", 0 },
+ { 0x02, NULL, cmd02_rs, NULL, NULL, "[VITA] Get Chassis Identifier", 0 },
+ { 0x03, cmd02_rs, NULL, NULL, NULL, "[VITA] Set Chassis Identifier", 0 },
+ { 0x04, cmd04_rq, NULL, NULL, NULL, "[VITA] FRU Control", 0 },
+ { 0x05, cmd05_rq, cmd05_rs, NULL, NULL, "[VITA] Get FRU LED Properties", 0 },
+ { 0x06, cmd06_rq, cmd06_rs, NULL, NULL, "[VITA] Get LED Color Capabilities", 0 },
+ { 0x07, cmd07_rq, NULL, NULL, NULL, "[VITA] Set FRU LED State", 0 },
+ { 0x08, cmd06_rq, cmd08_rs, NULL, NULL, "[VITA] Get FRU LED State", 0 },
+ { 0x09, cmd09_rq, NULL, NULL, NULL, "[VITA] Set IPMB State", 0 },
+ { 0x0A, cmd0A_rq, NULL, NULL, NULL, "[VITA] Set FRU State Policy Bits", 0 },
+ { 0x0B, cmd05_rq, cmd0B_rs, NULL, NULL, "[VITA] Get FRU State Policy Bits", 0 },
+ { 0x0C, cmd0C_rq, NULL, NULL, NULL, "[VITA] Set FRU Activation", 0 },
+ { 0x0D, cmd05_rq, cmd0D_rs, NULL, NULL, "[VITA] Get Device Locator Record ID", 0 },
+ { 0x14, cmd05_rq, cmd14_rs, NULL, NULL, "[VITA] Get Fan Speed Properties", 0 },
+ { 0x15, cmd15_rq, NULL, NULL, NULL, "[VITA] Set Fan Level", 0 },
+ { 0x16, cmd05_rq, cmd16_rs, NULL, NULL, "[VITA] Get Fan Level", 0 },
+ { 0x18, cmd18_rq, cmd18_rs, NULL, NULL, "[VITA] Get IPMB Link Info", 0 },
+ { 0x1B, NULL, cmd1B_rs, NULL, NULL, "[VITA] Get Chassis Manager IPMB Address", 0 },
+ { 0x1C, cmd1C_rq, NULL, NULL, NULL, "[VITA] Set Fan Policy", 0 },
+ { 0x1D, cmd1D_rq, cmd1D_rs, NULL, NULL, "[VITA] Get Fan Policy", 0 },
+ { 0x1E, cmd05_rq, cmd1E_rs, NULL, NULL, "[VITA] FRU Control Capabilities", 0 },
+ { 0x1F, cmd1F_rq, cmd1F_rs, cc1F, NULL, "[VITA] FRU Inventory Device Lock Control", 0 },
+ { 0x20, cmd20_rq, cmd20_rs, cc20, NULL, "[VITA] FRU Inventory Device Write", 0 },
+ { 0x21, cmd21_rq, cmd21_rs, NULL, NULL, "[VITA] Get Chassis Manager IP Address", 0 },
+ { 0x40, cmd01_rq, cmd01_rs, NULL, NULL, "[VITA] Get FRU Address Info", 0 },
+ { 0x41, cmd05_rq, cmd41_rs, NULL, NULL, "[VITA] Get FRU Persistent Control", 0 },
+ { 0x42, cmd42_rq, NULL, NULL, NULL, "[VITA] Set FRU Persistent Control", 0 },
+ { 0x43, cmd05_rq, cmd43_rs, NULL, NULL, "[VITA] FRU Persistent Control Capabilities", 0 },
+ { 0x44, cmd05_rq, cmd44_rs, NULL, NULL, "[VITA] Get Mandatory Sensor Numbers", 0 }
+};
+
+/* VITA 46.11 command set registrator
+*/
+void
+ipmi_register_vita(gint proto_ipmi)
+{
+ static const guint8 sig_vita[1] = { 3 };
+
+ proto_register_field_array(proto_ipmi, hf_ipmi_vita,
+ array_length(hf_ipmi_vita));
+ proto_register_subtree_array(ett_ipmi_vita,
+ array_length(ett_ipmi_vita));
+ ipmi_register_netfn_cmdtab(IPMI_GROUP_REQ, IPMI_OEM_NONE,
+ sig_vita, 1, "VITA", cmd_vita, array_length(cmd_vita));
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */
diff --git a/epan/dissectors/packet-ipmi.c b/epan/dissectors/packet-ipmi.c
index 62f71049d3..54cc8ca174 100644
--- a/epan/dissectors/packet-ipmi.c
+++ b/epan/dissectors/packet-ipmi.c
@@ -24,8 +24,8 @@
#include "config.h"
#include <string.h>
-#include <time.h>
-#include <math.h>
+
+#include <stdio.h>
#include <epan/packet.h>
#include <epan/conversation.h>
@@ -54,24 +54,6 @@ struct ipmi_netfn_root {
guint32 siglen;
};
-#define NSAVED_DATA 2
-
-/* We need more than a conversation. Over the same RMCP session
- (or IPMB), there may be several addresses/SWIDs. Thus, in a single
- Wireshark-maintained conversation we might need to find our own... */
-struct ipmi_saved_data {
- guint32 set_data;
- guint32 saved_data[NSAVED_DATA];
-};
-
-enum {
- RQ = 0,
- RS,
- RS2,
-
- MAX_RQRS_FRAMES
-};
-
enum {
MSGFMT_NONE = 0,
MSGFMT_IPMB,
@@ -79,35 +61,84 @@ enum {
MSGFMT_GUESS
};
-struct ipmi_reqresp {
- struct ipmi_reqresp *next;
- struct ipmi_saved_data *data;
- int (*whichresponse)(struct ipmi_header *hdr, struct ipmi_reqresp *rr);
- struct {
- guint32 num;
- nstime_t time;
- } frames[MAX_RQRS_FRAMES];
- guint8 netfn;
- guint8 cmd;
-};
-
-struct ipmi_keyhead {
- struct ipmi_reqresp *rr;
-};
-
-struct ipmi_keytree {
- wmem_tree_t *heads;
-};
-
struct ipmi_parse_typelen {
void (*get_len)(guint *, guint *, tvbuff_t *, guint, guint, gboolean);
void (*parse)(char *, tvbuff_t *, guint, guint);
const char *desc;
};
-struct ipmi_header *ipmi_current_hdr;
+/* IPMI parsing context */
+typedef struct {
+ ipmi_header_t hdr;
+ guint hdr_len;
+ guint flags;
+ guint8 cks1;
+ guint8 cks2;
+} ipmi_context_t;
+
+/* Temporary request-response matching data. */
+typedef struct {
+ /* Request header */
+ ipmi_header_t hdr;
+ /* Frame number where the request resides */
+ guint32 frame_num;
+ /* Nest level of the request in the frame */
+ guint8 nest_level;
+} ipmi_request_t;
+
+/* List of request-response matching data */
+typedef wmem_list_t ipmi_request_list_t;
+
+#define NSAVED_DATA 2
+
+/* Per-command data */
+typedef struct {
+ guint32 matched_frame_num;
+ guint32 saved_data[NSAVED_DATA];
+} ipmi_cmd_data_t;
+
+/* Per-frame data */
+typedef struct {
+ ipmi_cmd_data_t * cmd_data[3];
+ nstime_t ts;
+} ipmi_frame_data_t;
+
+/* RB tree of frame data */
+typedef wmem_tree_t ipmi_frame_tree_t;
+
+/* cached dissector data */
+typedef struct {
+ /* tree of cached frame data */
+ ipmi_frame_tree_t * frame_tree;
+ /* list of cached requests */
+ ipmi_request_list_t * request_list;
+ /* currently dissected frame number */
+ guint32 curr_frame_num;
+ /* currently dissected frame */
+ ipmi_frame_data_t * curr_frame;
+ /* current nesting level */
+ guint8 curr_level;
+ /* subsequent nesting level */
+ guint8 next_level;
+ /* top level message channel */
+ guint8 curr_channel;
+ /* top level message direction */
+ guint8 curr_dir;
+ /* pointer to current command */
+ const ipmi_header_t * curr_hdr;
+ /* current completion code */
+ guint8 curr_ccode;
+} ipmi_packet_data_t;
+
+/* Maximum nest level where it worth caching data */
+#define MAX_NEST_LEVEL 3
+
+static dissector_handle_t data_dissector;
static gint proto_ipmi = -1;
+static gint proto_ipmb = -1;
+static gint proto_kcs = -1;
+static gint proto_tmode = -1;
static gboolean fru_langcode_is_english = TRUE;
static guint response_after_req = 5000;
@@ -115,15 +146,14 @@ static guint response_before_req = 0;
static guint message_format = MSGFMT_GUESS;
static guint selected_oem = IPMI_OEM_NONE;
-static gint hf_ipmi_message = -1;
static gint hf_ipmi_session_handle = -1;
-static gint hf_ipmi_header_broadcast = -1;
static gint hf_ipmi_header_trg = -1;
static gint hf_ipmi_header_trg_lun = -1;
static gint hf_ipmi_header_netfn = -1;
static gint hf_ipmi_header_crc = -1;
static gint hf_ipmi_header_src = -1;
static gint hf_ipmi_header_src_lun = -1;
+static gint hf_ipmi_header_bridged = -1;
static gint hf_ipmi_header_sequence = -1;
static gint hf_ipmi_header_command = -1;
static gint hf_ipmi_header_completion = -1;
@@ -132,7 +162,6 @@ static gint hf_ipmi_data_crc = -1;
static gint hf_ipmi_response_to = -1;
static gint hf_ipmi_response_in = -1;
static gint hf_ipmi_response_time = -1;
-static gint hf_ipmi_bad_checksum = -1;
static gint ett_ipmi = -1;
static gint ett_header = -1;
@@ -141,375 +170,660 @@ static gint ett_header_byte_4 = -1;
static gint ett_data = -1;
static gint ett_typelen = -1;
-static guint nest_level;
-static struct ipmi_saved_data *current_saved_data;
static struct ipmi_netfn_root ipmi_cmd_tab[IPMI_NETFN_MAX];
-/* Debug support */
-static void
-debug_printf(const gchar *fmt _U_, ...)
+static ipmi_packet_data_t *
+get_packet_data(packet_info * pinfo)
{
-#if defined(IPMI_DEBUG)
- va_list ap;
+ ipmi_packet_data_t * data;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-#endif
-}
+ /* get conversation data */
+ conversation_t * conv = find_or_create_conversation(pinfo);
-/* ----------------------------------------------------------------
- Support for request-response caching.
----------------------------------------------------------------- */
+ /* get protocol-specific data */
+ data = (ipmi_packet_data_t *)
+ conversation_get_proto_data(conv, proto_ipmi);
+
+ if (!data) {
+ /* allocate per-packet data */
+ data = wmem_new0(wmem_file_scope(), ipmi_packet_data_t);
+
+ /* allocate request list and frame tree */
+ data->frame_tree = wmem_tree_new(wmem_file_scope());
+ data->request_list = wmem_list_new(wmem_file_scope());
+
+ /* add protocol data */
+ conversation_add_proto_data(conv, proto_ipmi, data);
+ }
+
+ /* check if packet has changed */
+ if (pinfo->fd->num != data->curr_frame_num) {
+ data->curr_level = 0;
+ data->next_level = 0;
+ }
+
+ return data;
+}
-/* Key generation; returns the same key for requests and responses */
-static guint32
-makekey(struct ipmi_header *hdr)
+static ipmi_frame_data_t *
+get_frame_data(ipmi_packet_data_t * data, guint32 frame_num)
{
- guint32 trg, src, res;
+ ipmi_frame_data_t * frame = (ipmi_frame_data_t *)
+ wmem_tree_lookup32(data->frame_tree, frame_num);
+
+ if (frame == NULL) {
+ frame = wmem_new0(wmem_file_scope(), ipmi_frame_data_t);
- trg = (hdr->trg_sa << 2) | hdr->trg_lun;
- src = (hdr->src_sa << 2) | hdr->src_lun;
- res = trg < src ? (trg << 10) | src : (src << 10) | trg;
- return (hdr->seq << 20) | res;
+ wmem_tree_insert32(data->frame_tree, frame_num, frame);
+ }
+ return frame;
}
-static struct ipmi_reqresp *
-key_lookup_reqresp(struct ipmi_keyhead *kh, struct ipmi_header *hdr, frame_data *fd)
+static ipmi_request_t *
+get_matched_request(ipmi_packet_data_t * data, const ipmi_header_t * rs_hdr,
+ guint flags)
{
- struct ipmi_reqresp *rr, *best_rr = NULL;
- nstime_t delta;
- double d, best_d = (double)(2 * response_after_req);
- guint8 netfn = hdr->netfn & 0x3e; /* disregard 'response' bit */
- guint8 is_resp = hdr->netfn & 0x01;
- int i;
+ wmem_list_frame_t * iter = wmem_list_head(data->request_list);
+ ipmi_header_t rq_hdr;
+
+ /* reset message context */
+ rq_hdr.context = 0;
+
+ /* copy channel */
+ rq_hdr.channel = data->curr_channel;
+
+ /* toggle packet direction */
+ rq_hdr.dir = rs_hdr->dir ^ 1;
+
+ /* swap responder address/lun */
+ rq_hdr.rs_sa = rs_hdr->rq_sa;
+ rq_hdr.rs_lun = rs_hdr->rq_lun;
+
+ /* remove reply flag */
+ rq_hdr.netfn = rs_hdr->netfn & ~1;
+
+ /* swap requester address/lun */
+ rq_hdr.rq_sa = rs_hdr->rs_sa;
+ rq_hdr.rq_lun = rs_hdr->rs_lun;
+
+ /* copy sequence */
+ rq_hdr.rq_seq = rs_hdr->rq_seq;
+
+ /* copy command */
+ rq_hdr.cmd = rs_hdr->cmd;
+
+ /* TODO: copy prefix bytes */
+
+#ifdef DEBUG
+ fprintf(stderr, "%d, %d: rq_hdr : {\n"
+ "\tchannel=%d\n"
+ "\tdir=%d\n"
+ "\trs_sa=%x\n"
+ "\trs_lun=%d\n"
+ "\tnetfn=%x\n"
+ "\trq_sa=%x\n"
+ "\trq_lun=%d\n"
+ "\trq_seq=%x\n"
+ "\tcmd=%x\n}\n",
+ data->curr_frame_num, data->curr_level,
+ rq_hdr.channel, rq_hdr.dir, rq_hdr.rs_sa, rq_hdr.rs_lun,
+ rq_hdr.netfn, rq_hdr.rq_sa, rq_hdr.rq_lun, rq_hdr.rq_seq,
+ rq_hdr.cmd);
+#endif
- /* Source/target SA/LUN and sequence number are assumed to match; wmem_tree*
- ensure that. While checking for "being here", we can't rely on flags.visited,
- as we may have more than one IPMI message in a single frame. */
- for (rr = kh->rr; rr; rr = rr->next) {
- if (rr->netfn != netfn || rr->cmd != hdr->cmd) {
- continue;
- }
+ while (iter) {
+ ipmi_request_t * rq = (ipmi_request_t *) wmem_list_frame_data(iter);
- for (i = 0; i < MAX_RQRS_FRAMES; i++) {
- /* RQ=0 - 0th element is request frame number; RS/RS2 -
- responses are non zero */
- if (((!i) ^ is_resp) && rr->frames[i].num == fd->num) {
- /* Already been here */
- return rr;
- }
+ /* check if in Get Message context */
+ if (rs_hdr->context == IPMI_E_GETMSG && !(flags & IPMI_D_TRG_SA)) {
+ /* diregard rsSA */
+ rq_hdr.rq_sa = rq->hdr.rq_sa;
}
- /* Reject responses before requests or more than 5 seconds ahead */
- if (is_resp) {
- nstime_delta(&delta, &fd->abs_ts, &rr->frames[RQ].time);
- } else {
- /* Use RS here, not RS2 - frames[RS] is always filled if we had
- at least one response */ /* TBD */
- nstime_delta(&delta, &rr->frames[RS].time, &fd->abs_ts);
- }
- d = nstime_to_msec(&delta);
- if (d < -(double)response_before_req || d > (double)response_after_req) {
- continue;
+ /* compare command headers */
+ if (!memcmp(&rq_hdr, &rq->hdr, sizeof(rq_hdr))) {
+ return rq;
}
- if (fabs(d) < best_d) {
- best_rr = rr;
- best_d = fabs(d);
- }
+ /* proceed to next request */
+ iter = wmem_list_frame_next(iter);
}
- return best_rr;
+ return NULL;
}
static void
-key_insert_reqresp(struct ipmi_keyhead *kh, struct ipmi_reqresp *rr)
+remove_old_requests(ipmi_packet_data_t * data, const nstime_t * curr_time)
{
- /* Insert to head, so that the search would find most recent response */
- rr->next = kh->rr;
- kh->rr = rr;
-}
+ wmem_list_frame_t * iter = wmem_list_head(data->request_list);
-static inline gboolean
-set_framenums(struct ipmi_header *hdr, struct ipmi_reqresp *rr, frame_data *fd)
-{
- int which = hdr->netfn & 0x01 ? rr->whichresponse ? rr->whichresponse(hdr, rr) : RS : RQ;
+ while (iter) {
+ ipmi_request_t * rq = (ipmi_request_t *) wmem_list_frame_data(iter);
+ ipmi_frame_data_t * frame = get_frame_data(data, rq->frame_num);
+ nstime_t delta;
- if (rr->frames[which].num && rr->frames[which].num != fd->num) {
- return FALSE;
+ /* calculate time delta */
+ nstime_delta(&delta, curr_time, &frame->ts);
+
+ if (nstime_to_msec(&delta) > response_after_req) {
+ wmem_list_frame_t * del = iter;
+
+ /* proceed to next request */
+ iter = wmem_list_frame_next(iter);
+
+ /* free request data */
+ wmem_free(wmem_file_scope(), rq);
+
+ /* remove list item */
+ wmem_list_remove_frame(data->request_list, del);
+ } else {
+ break;
+ }
}
- rr->frames[which].num = fd->num;
- rr->frames[which].time = fd->abs_ts;
- return TRUE;
}
-#define IS_SENDMSG(hdr) (((hdr)->netfn & 0x3e) == IPMI_APP_REQ && (hdr)->cmd == 0x34)
-
-int
-ipmi_sendmsg_whichresponse(struct ipmi_header *hdr, struct ipmi_reqresp *rr)
+static void
+match_request_response(ipmi_packet_data_t * data, const ipmi_header_t * hdr,
+ guint flags)
{
- if (!IS_SENDMSG(hdr)) {
- /* Not a Send Message: just a simple response */
- return RS;
- }
+ /* get current frame */
+ ipmi_frame_data_t * rs_frame = data->curr_frame;
- if (hdr->data_len > 0) {
- /* Trivial case: response with non-null data can only be a
- response in AMC.0 style */
- return RS2;
- }
- /* Otherwise, we need to somehow determine 1st and 2nd responses. Note
- that both them may lack the data - in case that the embedded response
- returned with error. Thus, employ the following algo:
- - First, assign to [RS] frame (this also won't conflict with full response
- received - it could only happen if send message succeeded)
- - In case we see another data-less response, see that we assign the one
- with success completion code to [RS] and with non-success code to [RS2].
-
- We assume that we can't receive 2 responses with non-successful completion
- (if the outmost Send Message failed, how was the embedded one sent?)
- */
- if (!rr->frames[RS].num) {
- return RS;
- }
+ /* get current command data */
+ ipmi_cmd_data_t * rs_data = rs_frame->cmd_data[data->curr_level];
+
+ /* check if parse response for the first time */
+ if (!rs_data) {
+ ipmi_request_t * rq;
+
+ /* allocate command data */
+ rs_data = wmem_new0(wmem_file_scope(), ipmi_cmd_data_t);
- /* In case we received "success", move the other response to [RS2] */
- if (!hdr->ccode) {
- if (!rr->frames[RS2].num) {
- rr->frames[RS2] = rr->frames[RS];
+ /* search for matching request */
+ rq = get_matched_request(data, hdr, flags);
+
+ /* check if matching request is found */
+ if (rq) {
+ /* get request frame data */
+ ipmi_frame_data_t * rq_frame =
+ get_frame_data(data, rq->frame_num);
+
+ /* get command data */
+ ipmi_cmd_data_t * rq_data = rq_frame->cmd_data[rq->nest_level];
+
+ /* save matched frame numbers */
+ rq_data->matched_frame_num = data->curr_frame_num;
+ rs_data->matched_frame_num = rq->frame_num;
+
+ /* copy saved command data information */
+ rs_data->saved_data[0] = rq_data->saved_data[0];
+ rs_data->saved_data[1] = rq_data->saved_data[1];
+
+ /* remove request from the list */
+ wmem_list_remove(data->request_list, rq);
+
+ /* delete request data */
+ wmem_free(wmem_file_scope(), rq);
}
- return RS;
- }
- /* [RS] occupied, non-successful */
- return RS2;
+ /* save command data pointer in frame */
+ rs_frame->cmd_data[data->curr_level] = rs_data;
+ }
}
-int
-ipmi_sendmsg_otheridx(struct ipmi_header *hdr)
+static void
+add_request(ipmi_packet_data_t * data, const ipmi_header_t * hdr)
{
- return IS_SENDMSG(hdr) ? nest_level : RS;
+ /* get current frame */
+ ipmi_frame_data_t * rq_frame = data->curr_frame;
+
+ /* get current command data */
+ ipmi_cmd_data_t * rq_data = rq_frame->cmd_data[data->curr_level];
+
+ /* check if parse response for the first time */
+ if (!rq_data) {
+ ipmi_request_t * rq;
+
+ /* allocate command data */
+ rq_data = wmem_new0(wmem_file_scope(), ipmi_cmd_data_t);
+
+ /* set command data pointer */
+ rq_frame->cmd_data[data->curr_level] = rq_data;
+
+ /* allocate request data */
+ rq = wmem_new0(wmem_file_scope(), ipmi_request_t);
+
+ /* copy request header */
+ memcpy(&rq->hdr, hdr, sizeof(rq->hdr));
+
+ /* override context, channel and direction */
+ rq->hdr.context = 0;
+ rq->hdr.channel = data->curr_channel;
+ rq->hdr.dir = data->curr_dir;
+
+ /* set request frame number */
+ rq->frame_num = data->curr_frame_num;
+
+ /* set command nest level */
+ rq->nest_level = data->curr_level;
+
+ /* append request to list */
+ wmem_list_append(data->request_list, rq);
+
+#ifdef DEBUG
+ fprintf(stderr, "%d, %d: hdr : {\n"
+ "\tchannel=%d\n"
+ "\tdir=%d\n"
+ "\trs_sa=%x\n"
+ "\trs_lun=%d\n"
+ "\tnetfn=%x\n"
+ "\trq_sa=%x\n"
+ "\trq_lun=%d\n"
+ "\trq_seq=%x\n"
+ "\tcmd=%x\n}\n",
+ data->curr_frame_num, data->curr_level,
+ rq->hdr.channel, rq->hdr.dir, rq->hdr.rs_sa, rq->hdr.rs_lun,
+ rq->hdr.netfn, rq->hdr.rq_sa, rq->hdr.rq_lun, rq->hdr.rq_seq,
+ rq->hdr.cmd);
+#endif
+ }
}
-struct ipmi_header *
-ipmi_sendmsg_getheaders(struct ipmi_header *base, void *arg, guint i)
+static void
+add_command_info(packet_info *pinfo, ipmi_cmd_t * cmd,
+ gboolean resp, guint8 cc_val, const char * cc_str, gboolean broadcast)
{
- static struct ipmi_header hdr;
- struct ipmi_header *wrapper = (struct ipmi_header *)arg;
-
- /* The problem stems from the fact that the original IPMI
- specification (before errata came) did not specify the response
- to Send Message (and even the fact that there are 2 responses -
- to Send Message and to embedded command). Even then, there is
- one vagueness remaining - whether the response should use
- the sequence number from the wrapper or from the embedded message.
-
- Thus, there are 3 types of responses to Send Message
-
- * AMC.0-style: the response is embedded in a normal Send Message
- response. Easiest case: such responses will be correctly detected
- with the default code in ipmi_do_dissect.
-
- * IPMI-style, with both variants of sequence numbers. Note that
- most tools dealing with Send Message (e.g. ipmitool) circumvent
- this vagueness by using the same sequence number in both wrapper
- and embedded messages. If we detect such "smart" messages, we
- provide only one extra header. For correctness, we have to provide
- for both variants, however.
- */
-
- if (i >= 2 || (i == 1 && wrapper->seq == base->seq)) {
- return NULL;
+ if (resp) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Rsp, %s, %s (%02xh)",
+ cmd->desc, cc_str, cc_val);
+ } else {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Req, %s%s",
+ broadcast ? "Broadcast " : "", cmd->desc);
}
-
- /* Construct hybrid header */
- hdr.trg_sa = wrapper->trg_sa;
- hdr.trg_lun = wrapper->trg_lun;
- hdr.src_sa = wrapper->src_sa;
- hdr.src_lun = wrapper->src_lun;
- hdr.netfn = base->netfn;
- hdr.cmd = base->cmd;
- hdr.seq = i ? base->seq : wrapper->seq;
- hdr.ccode = base->ccode;
- hdr.data_len = base->data_len;
- return &hdr;
}
-static void
-maybe_insert_reqresp(packet_info *pinfo, ipmi_dissect_format_t *dfmt, struct ipmi_header *hdr)
+int dissect_ipmi_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gint hf_parent_item, gint ett_tree, const ipmi_context_t * ctx)
{
- conversation_t *cnv;
- struct ipmi_keytree *kt;
- struct ipmi_keyhead *kh;
- struct ipmi_reqresp *rr;
- guint32 key, i;
-
- cnv = find_or_create_conversation(pinfo);
-
- kt = (struct ipmi_keytree *)conversation_get_proto_data(cnv, proto_ipmi);
- if (!kt) {
- kt = wmem_new(wmem_file_scope(), struct ipmi_keytree);
- kt->heads = wmem_tree_new(wmem_file_scope());
- conversation_add_proto_data(cnv, proto_ipmi, kt);
+ ipmi_packet_data_t * data;
+ ipmi_netfn_t * cmd_list;
+ ipmi_cmd_t * cmd;
+ proto_item * ti;
+ proto_tree * cmd_tree = NULL, * tmp_tree;
+ guint8 prev_level, cc_val;
+ guint offset, siglen, is_resp;
+ const char * cc_str, * netfn_str;
+
+ /* get packet data */
+ data = get_packet_data(pinfo);
+ if (!data) {
+ return 0;
+ }
+
+ /* get prefix length */
+ siglen = ipmi_getsiglen(ctx->hdr.netfn);
+
+ /* get response flag */
+ is_resp = ctx->hdr.netfn & 1;
+
+ /* check message length */
+ if (tvb_captured_length(tvb) < ctx->hdr_len + siglen + is_resp
+ + !(ctx->flags & IPMI_D_NO_CKS)) {
+ /* don bother with anything */
+ return call_dissector(data_dissector, tvb, pinfo, tree);
}
- debug_printf("--> maybe_insert_reqresp( %d )\n", pinfo->fd->num);
- i = 0;
- do {
- debug_printf("Checking [ (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- hdr->netfn, hdr->cmd);
- key = makekey(hdr);
- kh = (struct ipmi_keyhead *)wmem_tree_lookup32(kt->heads, key);
- if (!kh) {
- kh = wmem_new0(wmem_file_scope(), struct ipmi_keyhead);
- wmem_tree_insert32(kt->heads, key, kh);
+ /* save nest level */
+ prev_level = data->curr_level;
+
+ /* assign next nest level */
+ data->curr_level = data->next_level;
+
+ /* increment next nest level */
+ data->next_level++;
+
+ /* check for the first invocation */
+ if (!data->curr_level) {
+ /* get current frame data */
+ data->curr_frame = get_frame_data(data, pinfo->fd->num);
+ data->curr_frame_num = pinfo->fd->num;
+
+ /* copy frame timestamp */
+ memcpy(&data->curr_frame->ts, &pinfo->fd->abs_ts, sizeof(nstime_t));
+
+ /* cache channel and direction */
+ data->curr_channel = ctx->hdr.channel;
+ data->curr_dir = ctx->hdr.dir;
+
+ /* remove requests which are too old */
+ remove_old_requests(data, &pinfo->fd->abs_ts);
+ }
+
+ if (data->curr_level < MAX_NEST_LEVEL) {
+ if (ctx->hdr.netfn & 1) {
+ /* perform request/response matching */
+ match_request_response(data, &ctx->hdr, ctx->flags);
+ } else {
+ /* add request to the list for later matching */
+ add_request(data, &ctx->hdr);
}
- if ((rr = key_lookup_reqresp(kh, hdr, pinfo->fd)) != NULL) {
- /* Already recorded - set frame number and be done. Look no
- further - even if there are several responses, we have
- found the right one. */
- debug_printf("Found existing [ <%d,%d,%d> (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- rr->frames[0].num, rr->frames[1].num, rr->frames[2].num,
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- rr->netfn, rr->cmd);
- if (!rr->whichresponse) {
- rr->whichresponse = dfmt->whichresponse;
+ }
+
+ /* get command list by network function code */
+ cmd_list = ipmi_getnetfn(ctx->hdr.netfn,
+ tvb_get_ptr(tvb, ctx->hdr_len + is_resp, siglen));
+
+ /* get command descriptor */
+ cmd = ipmi_getcmd(cmd_list, ctx->hdr.cmd);
+
+ /* check if response */
+ if (is_resp) {
+ /* get completion code */
+ cc_val = tvb_get_guint8(tvb, ctx->hdr_len);
+
+ /* get completion code desc */
+ cc_str = ipmi_get_completion_code(cc_val, cmd);
+ } else {
+ cc_val = 0;
+ cc_str = NULL;
+ }
+
+ /* check if not inside a message */
+ if (!data->curr_level) {
+ /* add packet info */
+ add_command_info(pinfo, cmd, is_resp, cc_val, cc_str,
+ ctx->flags & IPMI_D_BROADCAST ? TRUE : FALSE);
+ }
+
+ if (tree) {
+ /* add parent node */
+ if (!data->curr_level) {
+ ti = proto_tree_add_item(tree, hf_parent_item, tvb, 0, -1, ENC_NA);
+ } else {
+ char str[ITEM_LABEL_LENGTH];
+
+ if (is_resp) {
+ g_snprintf(str, ITEM_LABEL_LENGTH, "Rsp, %s, %s",
+ cmd->desc, cc_str);
+ } else {
+ g_snprintf(str, ITEM_LABEL_LENGTH, "Req, %s", cmd->desc);
}
- if (set_framenums(hdr, rr, pinfo->fd)) {
- debug_printf("Set frames [ <%d,%d,%d> (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- rr->frames[0].num, rr->frames[1].num, rr->frames[2].num,
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- rr->netfn, rr->cmd);
- current_saved_data = rr->data;
- return;
+
+ ti = proto_tree_add_string(tree, hf_parent_item, tvb, 0, -1, str);
+ }
+
+ /* add message sub-tree */
+ cmd_tree = proto_item_add_subtree(ti, ett_tree);
+
+ if (data->curr_level < MAX_NEST_LEVEL) {
+ /* check if response */
+ if (ctx->hdr.netfn & 1) {
+ /* get current command data */
+ ipmi_cmd_data_t * rs_data =
+ data->curr_frame->cmd_data[data->curr_level];
+
+ if (rs_data->matched_frame_num) {
+ nstime_t ns;
+
+ /* add "Request to:" field */
+ ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_to,
+ tvb, 0, 0, rs_data->matched_frame_num);
+
+ /* mark field as a generated one */
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ /* calculate delta time */
+ nstime_delta(&ns, &pinfo->fd->abs_ts,
+ &get_frame_data(data,
+ rs_data->matched_frame_num)->ts);
+
+ /* add "Response time" field */
+ ti = proto_tree_add_time(cmd_tree, hf_ipmi_response_time,
+ tvb, 0, 0, &ns);
+
+ /* mark field as a generated one */
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+ } else {
+ /* get current command data */
+ ipmi_cmd_data_t * rq_data =
+ data->curr_frame->cmd_data[data->curr_level];
+
+ if (rq_data->matched_frame_num) {
+ /* add "Response in:" field */
+ ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_in,
+ tvb, 0, 0, rq_data->matched_frame_num);
+
+ /* mark field as a generated one */
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
}
+ }
+
+ /* set starting offset */
+ offset = 0;
- /* Found, but already occupied. Fall through to allocating the structures */
- current_saved_data = NULL;
+ /* check if message is broadcast */
+ if (ctx->flags & IPMI_D_BROADCAST) {
+ /* skip first byte */
+ offset++;
}
- /* Not found; allocate new structures */
- if (!current_saved_data) {
- /* One 'ipmi_saved_data' for all 'ipmi_req_resp' allocated */
- current_saved_data = wmem_new0(wmem_file_scope(), struct ipmi_saved_data);
+
+ /* check if session handle is specified */
+ if (ctx->flags & IPMI_D_SESSION_HANDLE) {
+ /* add session handle field */
+ proto_tree_add_item(cmd_tree, hf_ipmi_session_handle,
+ tvb, offset++, 1, ENC_LITTLE_ENDIAN);
}
- rr = wmem_new0(wmem_file_scope(), struct ipmi_reqresp);
- rr->whichresponse = dfmt->whichresponse;
- rr->netfn = hdr->netfn & 0x3e;
- rr->cmd = hdr->cmd;
- rr->data = current_saved_data;
- set_framenums(hdr, rr, pinfo->fd);
- key_insert_reqresp(kh, rr);
- debug_printf("Inserted [ <%d,%d,%d> (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- rr->frames[0].num, rr->frames[1].num, rr->frames[2].num,
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- rr->netfn, rr->cmd);
-
- /* Do we have other headers to insert? */
- hdr = dfmt->getmoreheaders ? dfmt->getmoreheaders(hdr, dfmt->arg, i++) : NULL;
- } while (hdr);
-}
-static void
-add_reqresp_info(ipmi_dissect_format_t *dfmt, struct ipmi_header *hdr, proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo)
-{
- conversation_t *cnv;
- struct ipmi_keytree *kt;
- struct ipmi_keyhead *kh;
- struct ipmi_reqresp *rr = NULL;
- guint32 key, i, other_idx;
- proto_item *ti;
- nstime_t ns;
+ /* check if responder address is specified */
+ if (ctx->flags & IPMI_D_TRG_SA) {
+ /* add response address field */
+ proto_tree_add_item(cmd_tree, hf_ipmi_header_trg, tvb,
+ offset++, 1, ENC_LITTLE_ENDIAN);
+ }
- debug_printf("--> add_reqresp_info( %d )\n", pinfo->fd->num);
+ /* get NetFn string */
+ netfn_str = ipmi_getnetfnname(ctx->hdr.netfn, cmd_list);
- /* [0] is request; [1..MAX_RS_LEVEL] are responses */
- other_idx = (hdr->netfn & 0x01) ? RQ : dfmt->otheridx ? dfmt->otheridx(hdr) : RS;
+ /* Network function + target LUN */
+ ti = proto_tree_add_text(cmd_tree, tvb, offset, 1,
+ "Target LUN: 0x%02x, NetFN: %s %s (0x%02x)",
+ ctx->hdr.rs_lun, netfn_str,
+ is_resp ? "Response" : "Request", ctx->hdr.netfn);
+
+ /* make a sub-tree */
+ tmp_tree = proto_item_add_subtree(ti, ett_header_byte_1);
+
+ /* add Net Fn */
+ proto_tree_add_uint_format(tmp_tree, hf_ipmi_header_netfn, tvb,
+ offset, 1, ctx->hdr.netfn << 2,
+ "NetFn: %s %s (0x%02x)", netfn_str,
+ is_resp ? "Response" : "Request", ctx->hdr.netfn);
+
+ proto_tree_add_item(tmp_tree, hf_ipmi_header_trg_lun, tvb,
+ offset++, 1, ENC_LITTLE_ENDIAN);
+
+ /* check if cks1 is specified */
+ if (!(ctx->flags & IPMI_D_NO_CKS)) {
+ guint8 cks = tvb_get_guint8(tvb, offset);
+
+ /* Header checksum */
+ if (ctx->cks1) {
+ guint8 correct = cks - ctx->cks1;
+
+ proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
+ tvb, offset++, 1, cks,
+ "0x%02x (incorrect, expected 0x%02x)", cks, correct);
+ } else {
+ proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
+ tvb, offset++, 1, cks,
+ "0x%02x (correct)", cks);
+ }
+ }
- if (other_idx >= MAX_RQRS_FRAMES) {
- /* No chance; we don't look that deep into nested Send Message.
- Note that we'll use the other_idx value to distinguish
- request from response. */
- goto fallback;
- }
+ /* check if request address is specified */
+ if (!(ctx->flags & IPMI_D_NO_RQ_SA)) {
+ /* add request address field */
+ proto_tree_add_item(cmd_tree, hf_ipmi_header_src, tvb,
+ offset++, 1, ENC_LITTLE_ENDIAN);
+ }
- /* Here, we don't try to create any object - everything is assumed
- to be created in maybe_insert_reqresp() */
- if ((cnv = find_conversation(pinfo->fd->num, &pinfo->src,
- &pinfo->dst, pinfo->ptype,
- pinfo->srcport, pinfo->destport, 0)) == NULL) {
- goto fallback;
- }
- if ((kt = (struct ipmi_keytree *)conversation_get_proto_data(cnv, proto_ipmi)) == NULL) {
- goto fallback;
+ /* check if request sequence is specified */
+ if (!(ctx->flags & IPMI_D_NO_SEQ)) {
+ /* Sequence number + source LUN */
+ ti = proto_tree_add_text(cmd_tree, tvb, offset, 1,
+ "%s: 0x%02x, SeqNo: 0x%02x",
+ (ctx->flags & IPMI_D_TMODE) ? "Bridged" : "Source LUN",
+ ctx->hdr.rq_lun, ctx->hdr.rq_seq);
+
+ /* create byte 4 sub-tree */
+ tmp_tree = proto_item_add_subtree(ti, ett_header_byte_4);
+
+ if (ctx->flags & IPMI_D_TMODE) {
+ proto_tree_add_item(tmp_tree, hf_ipmi_header_bridged,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ } else {
+ proto_tree_add_item(tmp_tree, hf_ipmi_header_src_lun,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ /* print seq no */
+ proto_tree_add_item(tmp_tree, hf_ipmi_header_sequence, tvb,
+ offset++, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ /* command code */
+ proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_command,
+ tvb, offset++, 1, ctx->hdr.cmd, "%s (0x%02x)",
+ cmd->desc, ctx->hdr.cmd);
+
+ if (is_resp) {
+ /* completion code */
+ proto_tree_add_uint_format_value(cmd_tree,
+ hf_ipmi_header_completion, tvb, offset++, 1,
+ cc_val, "%s (0x%02x)", cc_str, cc_val);
+ }
+
+ if (siglen) {
+ /* command prefix (if present) */
+ ti = proto_tree_add_item(cmd_tree, hf_ipmi_header_sig, tvb,
+ offset, siglen, ENC_NA);
+ proto_item_append_text(ti, " (%s)", netfn_str);
+ }
}
- i = 0;
- while (1) {
- debug_printf("Looking for [ (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- hdr->netfn, hdr->cmd);
- key = makekey(hdr);
- if ((kh = (struct ipmi_keyhead *)wmem_tree_lookup32(kt->heads, key)) != NULL &&
- (rr = key_lookup_reqresp(kh, hdr, pinfo->fd)) != NULL) {
- debug_printf("Found [ <%d,%d,%d> (%02x,%1x <-> %02x,%1x : %02x) %02x %02x ]\n",
- rr->frames[0].num, rr->frames[1].num, rr->frames[2].num,
- hdr->trg_sa, hdr->trg_lun, hdr->src_sa, hdr->src_lun, hdr->seq,
- rr->netfn, rr->cmd);
- if (rr->frames[other_idx].num) {
- break;
+ if (tree || (cmd->flags & CMD_CALLRQ)) {
+ /* calculate message data length */
+ guint data_len = tvb_captured_length(tvb)
+ - ctx->hdr_len
+ - siglen
+ - (is_resp ? 1 : 0)
+ - !(ctx->flags & IPMI_D_NO_CKS);
+
+ /* create data subset */
+ tvbuff_t * data_tvb = tvb_new_subset_length(tvb,
+ ctx->hdr_len + siglen + (is_resp ? 1 : 0), data_len);
+
+ /* Select sub-handler */
+ ipmi_cmd_handler_t hnd = is_resp ? cmd->parse_resp : cmd->parse_req;
+
+ if (hnd && tvb_captured_length(data_tvb)) {
+ if (tree) {
+ /* create data field */
+ ti = proto_tree_add_text(cmd_tree, data_tvb, 0, -1, "Data");
+
+ /* create data sub-tree */
+ tmp_tree = proto_item_add_subtree(ti, ett_data);
+ } else {
+ tmp_tree = NULL;
}
- }
- /* Do we have other headers to check? */
- hdr = dfmt->getmoreheaders ? dfmt->getmoreheaders(hdr, dfmt->arg, i++) : NULL;
- if (!hdr) {
- goto fallback;
+ /* save current command */
+ data->curr_hdr = &ctx->hdr;
+
+ /* save current completion code */
+ data->curr_ccode = cc_val;
+
+ /* call command parser */
+ hnd(data_tvb, pinfo, tmp_tree);
}
}
- if (hdr->netfn & 0x01) {
- /* Response */
- ti = proto_tree_add_uint(tree, hf_ipmi_response_to,
- tvb, 0, 0, rr->frames[RQ].num);
- PROTO_ITEM_SET_GENERATED(ti);
- nstime_delta(&ns, &pinfo->fd->abs_ts, &rr->frames[RQ].time);
- ti = proto_tree_add_time(tree, hf_ipmi_response_time,
- tvb, 0, 0, &ns);
- PROTO_ITEM_SET_GENERATED(ti);
- } else {
- /* Request */
- ti = proto_tree_add_uint(tree, hf_ipmi_response_in,
- tvb, 0, 0, rr->frames[other_idx].num);
- PROTO_ITEM_SET_GENERATED(ti);
+ /* check if cks2 is specified */
+ if (tree && !(ctx->flags & IPMI_D_NO_CKS)) {
+ guint8 cks;
+
+ /* get cks2 offset */
+ offset = tvb_captured_length(tvb) - 1;
+
+ /* get cks2 */
+ cks = tvb_get_guint8(tvb, offset);
+
+ /* Header checksum */
+ if (ctx->cks2) {
+ guint8 correct = cks - ctx->cks2;
+
+ proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
+ tvb, offset, 1, cks,
+ "0x%02x (incorrect, expected 0x%02x)", cks, correct);
+ } else {
+ proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
+ tvb, offset, 1, cks,
+ "0x%02x (correct)", cks);
+ }
}
- return;
-fallback:
- ti = proto_tree_add_text(tree, tvb, 0, 0, "No corresponding %s",
- other_idx ? "response" : "request");
- PROTO_ITEM_SET_GENERATED(ti);
+ /* decrement next nest level */
+ data->next_level = data->curr_level;
+
+ /* restore previous nest level */
+ data->curr_level = prev_level;
+
+ return tvb_captured_length(tvb);
}
-/* Save data in request, retrieve in response */
-void
-ipmi_setsaveddata(guint idx, guint32 val)
+/* Get currently parsed message header */
+const ipmi_header_t * ipmi_get_hdr(packet_info * pinfo)
{
- DISSECTOR_ASSERT(idx < NSAVED_DATA);
- current_saved_data->saved_data[idx] = val;
- current_saved_data->set_data |= (1 << idx);
+ ipmi_packet_data_t * data = get_packet_data(pinfo);
+ return data->curr_hdr;
}
-gboolean
-ipmi_getsaveddata(guint idx, guint32 *pval)
+/* Get completion code for currently parsed message */
+guint8 ipmi_get_ccode(packet_info * pinfo)
{
- DISSECTOR_ASSERT(idx < NSAVED_DATA);
- if (current_saved_data->set_data & (1 << idx)) {
- *pval = current_saved_data->saved_data[idx];
- return TRUE;
+ ipmi_packet_data_t * data = get_packet_data(pinfo);
+ return data->curr_ccode;
+}
+
+/* Save request data for later use in response */
+void ipmi_set_data(packet_info *pinfo, guint idx, guint32 value)
+{
+ ipmi_packet_data_t * data = get_packet_data(pinfo);
+
+ /* check bounds */
+ if (data->curr_level >= MAX_NEST_LEVEL || idx >= NSAVED_DATA ) {
+ return;
+ }
+
+ /* save data */
+ data->curr_frame->cmd_data[data->curr_level]->saved_data[idx] = value;
+}
+
+/* Get saved request data */
+gboolean ipmi_get_data(packet_info *pinfo, guint idx, guint32 * value)
+{
+ ipmi_packet_data_t * data = get_packet_data(pinfo);
+
+ /* check bounds */
+ if (data->curr_level >= MAX_NEST_LEVEL || idx >= NSAVED_DATA ) {
+ return FALSE;
}
- return FALSE;
+
+ /* get data */
+ *value = data->curr_frame->cmd_data[data->curr_level]->saved_data[idx];
+ return TRUE;
}
/* ----------------------------------------------------------------
@@ -814,15 +1128,11 @@ ipmi_register_netfn_cmdtab(guint32 netfn, guint oem_selector,
netfn >>= 1; /* Requests and responses grouped together */
if (netfn >= IPMI_NETFN_MAX) {
- g_warning("NetFn too large: %x", netfn * 2);
return;
}
inr = &ipmi_cmd_tab[netfn];
if (inr->siglen != siglen) {
- /* All handlers per netFn should have the same signature length */
- g_warning("NetFn %d: different signature lengths: %d vs %d",
- netfn * 2, inr->siglen, siglen);
return;
}
@@ -1047,331 +1357,388 @@ ipmi_get_completion_code(guint8 completion, ipmi_cmd_t *cmd)
return val_to_str_const(completion, std_completion_codes, "Unknown");
}
-/* Guess the parsing flags for a message
- */
-int
-ipmi_guess_dissect_flags(tvbuff_t *tvb)
+static int
+dissect_tmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- int i;
- guint8 buf[6];
-
- switch (message_format) {
- case MSGFMT_NONE:
- return IPMI_D_NONE;
- case MSGFMT_IPMB:
- return IPMI_D_TRG_SA;
- case MSGFMT_LAN:
- return IPMI_D_TRG_SA|IPMI_D_SESSION_HANDLE;
+ ipmi_dissect_arg_t * arg = (ipmi_dissect_arg_t *) data;
+ ipmi_context_t ctx;
+ guint tvb_len = tvb_captured_length(tvb);
+ guint8 tmp;
+
+ /* TMode message is at least 3 bytes length */
+ if (tvb_len < 3) {
+ return 0;
}
- /* Try to guess the format */
- DISSECTOR_ASSERT(message_format == MSGFMT_GUESS);
+ memset(&ctx, 0, sizeof(ctx));
- /* 6 is shortest message - Get Message with empty data */
- if (tvb_length(tvb) < 6) {
- return IPMI_D_NONE;
- }
+ /* get Net Fn/RS LUN field */
+ tmp = tvb_get_guint8(tvb, 0);
- /* Fetch the beginning */
- for (i = 0; i < 6; i++) {
- buf[i] = tvb_get_guint8(tvb, i);
- }
+ /* set Net Fn */
+ ctx.hdr.netfn = tmp >> 2;
- if ((buf[0] + buf[1] + buf[2]) % 0x100 == 0) {
- /* Looks like IPMB: first 3 bytes are zero module 256 */
- return IPMI_D_TRG_SA;
- }
+ /*
+ * NOTE: request/response matching code swaps RQ LUN with RS LUN
+ * fields in IPMB-like manner in order to find corresponding request
+ * so, we set both RS LUN and RQ LUN here for correct
+ * request/response matching
+ */
+ ctx.hdr.rq_lun = tmp & 3;
+ ctx.hdr.rs_lun = tmp & 3;
+
+ /* get RQ Seq field */
+ ctx.hdr.rq_seq = tvb_get_guint8(tvb, 1) >> 2;
- if ((buf[1] + buf[2] + buf[3]) % 0x100 == 0) {
- /* Looks like LAN: like IPMB, prepended with extra byte (session handle) */
- return IPMI_D_TRG_SA|IPMI_D_SESSION_HANDLE;
+ /*
+ * NOTE: bridge field is ignored in request/response matching
+ */
+
+ /* get command code */
+ ctx.hdr.cmd = tvb_get_guint8(tvb, 2);
+
+ /* set dissect flags */
+ ctx.flags = IPMI_D_TMODE|IPMI_D_NO_CKS|IPMI_D_NO_RQ_SA;
+
+ /* set header length */
+ ctx.hdr_len = 3;
+
+ /* copy channel number and direction */
+ ctx.hdr.context = arg ? arg->context : IPMI_E_NONE;
+ ctx.hdr.channel = arg ? arg->channel : 0;
+ ctx.hdr.dir = arg ? arg->flags >> 7 : ctx.hdr.netfn & 1;
+
+ if (ctx.hdr.context == IPMI_E_NONE) {
+ /* set source column */
+ col_set_str(pinfo->cinfo, COL_DEF_SRC,
+ ctx.hdr.dir ? "Console" : "BMC");
+
+ /* set destination column */
+ col_set_str(pinfo->cinfo, COL_DEF_DST,
+ ctx.hdr.dir ? "BMC" : "Console");
}
- /* Can't guess */
- return IPMI_D_NONE;
+ /* dissect IPMI command */
+ return dissect_ipmi_cmd(tvb, pinfo, tree, proto_tmode, ett_ipmi, &ctx);
}
-/* Print out IPMB packet.
- */
-void
-ipmi_do_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ipmi_tree, ipmi_dissect_format_t *dfmt)
+static int
+dissect_kcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- proto_tree *hdr_tree, *data_tree, *s_tree;
- proto_item *ti;
- tvbuff_t *data_tvb;
- ipmi_netfn_t *in = NULL;
- ipmi_cmd_t *ic = NULL;
- ipmi_cmd_handler_t hnd = NULL;
- struct ipmi_saved_data *saved_saved_data;
- struct ipmi_header hdr, *saved_hdr;
- guint8 hdr_crc, hdr_exp_crc, data_crc, data_exp_crc;
- guint8 is_resp, is_broadcast = 0, tmp;
- guint i, len, siglen, hdrlen, offs, data_chk_offs;
- const char *bcast, *ndesc, *cdesc, *ccdesc;
-
- if (dfmt->flags & IPMI_D_NONE) {
- /* No parsing requested */
- g_snprintf(dfmt->info, ITEM_LABEL_LENGTH, "Unknown message (not parsed)");
- proto_tree_add_item(ipmi_tree, hf_ipmi_message, tvb, 0, tvb_length(tvb), ENC_NA);
- return;
+ ipmi_dissect_arg_t * arg = (ipmi_dissect_arg_t *) data;
+ ipmi_context_t ctx;
+ guint tvb_len = tvb_captured_length(tvb);
+ guint8 tmp;
+
+ /* KCS message is at least 2 bytes length */
+ if (tvb_len < 2) {
+ return 0;
}
- nest_level++;
- offs = 0;
- memset(&hdr, 0, sizeof(hdr));
- debug_printf("--> do_dissect(%d, nl %u, tree %s null)\n",
- pinfo->fd->num, nest_level, ipmi_tree ? "IS NOT" : "IS");
+ memset(&ctx, 0, sizeof(ctx));
+
+ /* get Net Fn/RS LUN field */
+ tmp = tvb_get_guint8(tvb, 0);
+
+ /* set Net Fn */
+ ctx.hdr.netfn = tmp >> 2;
+
+ /*
+ * NOTE: request/response matching code swaps RQ LUN with RS LUN
+ * fields in IPMB-like manner in order to find corresponding request
+ * so, we set both RS LUN and RQ LUN here for correct
+ * request/response matching
+ */
+ ctx.hdr.rq_lun = tmp & 3;
+ ctx.hdr.rs_lun = tmp & 3;
+
+ /* get command code */
+ ctx.hdr.cmd = tvb_get_guint8(tvb, 1);
+
+ /* set dissect flags */
+ ctx.flags = IPMI_D_NO_CKS|IPMI_D_NO_RQ_SA|IPMI_D_NO_SEQ;
- /* Optional byte: in Send Message targeted to session-based channels */
- if (dfmt->flags & IPMI_D_SESSION_HANDLE) {
- offs++;
+ /* set header length */
+ ctx.hdr_len = 2;
+
+ /* copy channel number and direction */
+ ctx.hdr.context = arg ? arg->context : 0;
+ ctx.hdr.channel = arg ? arg->channel : 0;
+ ctx.hdr.dir = arg ? arg->flags >> 7 : ctx.hdr.netfn & 1;
+
+ if (ctx.hdr.context == IPMI_E_NONE) {
+ /* set source column */
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, ctx.hdr.dir ? "HOST" : "BMC");
+
+ /* set destination column */
+ col_set_str(pinfo->cinfo, COL_DEF_DST, ctx.hdr.dir ? "BMC" : "HOST");
}
- /* Optional byte: 00 indicates General Call address - broadcast message */
- if ((dfmt->flags & IPMI_D_BROADCAST) && tvb_get_guint8(tvb, offs) == 0x00) {
- is_broadcast = 1;
- offs++;
+ /* dissect IPMI command */
+ return dissect_ipmi_cmd(tvb, pinfo, tree, proto_kcs, ett_ipmi, &ctx);
+}
+
+static guint8 calc_cks(guint8 start, tvbuff_t * tvb, guint off, guint len)
+{
+ while (len--) {
+ start += tvb_get_guint8(tvb, off++);
}
- /* Byte 1: target slave address, may be absent (in Get Message) */
- hdr.trg_sa = (dfmt->flags & IPMI_D_TRG_SA) ? tvb_get_guint8(tvb, offs++) : 0;
-
- /* Byte 2: network function + target LUN */
- tmp = tvb_get_guint8(tvb, offs++);
- hdr.trg_lun = tmp & 0x03;
- hdr.netfn = (tmp >> 2) & 0x3f;
- hdr_exp_crc = (0 - hdr.trg_sa - tmp) & 0xff;
-
- /* Byte 3: header checksum */
- hdr_crc = tvb_get_guint8(tvb, offs++);
-
- /* Byte 4: source slave address */
- hdr.src_sa = tvb_get_guint8(tvb, offs++);
-
- /* Byte 5: sequence number + source LUN */
- tmp = tvb_get_guint8(tvb, offs++);
- hdr.src_lun = tmp & 0x03;
- hdr.seq = (tmp >> 2) & 0x3f;
-
- /* Byte 6: command code */
- hdr.cmd = tvb_get_guint8(tvb, offs++);
-
- /* Byte 7: completion code (in response) */
- is_resp = (hdr.netfn & 0x1) ? 1 : 0;
- hdr.ccode = is_resp ? tvb_get_guint8(tvb, offs++) : 0;
-
- /* 0-3 bytes: signature of the defining body */
- siglen = ipmi_getsiglen(hdr.netfn);
- in = ipmi_getnetfn(hdr.netfn, tvb_get_ptr(tvb, offs, siglen));
- offs += siglen;
-
- /* Save header length */
- hdrlen = offs;
- hdr.data_len = tvb_length(tvb) - hdrlen - 1;
-
- /* Get some text descriptions */
- ic = ipmi_getcmd(in, hdr.cmd);
- ndesc = ipmi_getnetfnname(hdr.netfn, in);
- cdesc = ic->desc;
- ccdesc = ipmi_get_completion_code(hdr.ccode, ic);
- if (!is_broadcast) {
- bcast = "";
- } else if (ic->flags & CMD_MAYBROADCAST) {
- bcast = " (BROADCAST: command may not be broadcast)";
+ return start;
+}
+
+static gboolean guess_imb_format(tvbuff_t *tvb, guint8 env,
+ guint8 channel, guint * imb_flags, guint8 * cks1, guint8 * cks2)
+{
+ gboolean check_bc = FALSE;
+ gboolean check_sh = FALSE;
+ gboolean check_sa = FALSE;
+ guint tvb_len;
+ guint sh_len;
+ guint sa_len;
+ guint rs_sa;
+
+ if (message_format == MSGFMT_NONE) {
+ return FALSE;
+ } else if (message_format == MSGFMT_IPMB) {
+ *imb_flags = IPMI_D_TRG_SA;
+ } else if (message_format == MSGFMT_LAN) {
+ *imb_flags = IPMI_D_TRG_SA|IPMI_D_SESSION_HANDLE;
+ /* channel 0 is primary IPMB */
+ } else if (!channel) {
+ /* check for broadcast if not in send message command */
+ if (env == IPMI_E_NONE) {
+ /* check broadcast */
+ check_bc = 1;
+
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+ /* check if in send message command */
+ } else if (env != IPMI_E_GETMSG) {
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+ } else /* IPMI_E_GETMSG */ {
+ *imb_flags = 0;
+ }
+ /* channel 15 is System Interface */
+ } else if (channel == 15) {
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+
+ /* check if in get message command */
+ if (env == IPMI_E_GETMSG) {
+ /* session handle must be present */
+ *imb_flags |= IPMI_D_SESSION_HANDLE;
+ }
+ /* for other channels */
} else {
- bcast = " (BROADCAST)";
+ if (env == IPMI_E_NONE) {
+ /* check broadcast */
+ check_bc = 1;
+
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+ } else if (env == IPMI_E_SENDMSG_RQ) {
+ /* check session handle */
+ check_sh = 1;
+
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+ } else if (env == IPMI_E_SENDMSG_RS) {
+ /* slave address must be present */
+ *imb_flags = IPMI_D_TRG_SA;
+ } else /* IPMI_E_GETMSG */ {
+ /* check session handle */
+ check_sh = 1;
+
+ /* check slave address presence */
+ check_sa = 1;
+
+ /* no pre-requisites */
+ *imb_flags = 0;
+ }
+ }
+
+ /* get message length */
+ tvb_len = tvb_captured_length(tvb);
+
+ /*
+ * broadcast message starts with null,
+ * does not contain session handle
+ * but contains responder address
+ */
+ if (check_bc
+ && tvb_len >= 8
+ && !tvb_get_guint8(tvb, 0)
+ && !calc_cks(0, tvb, 1, 3)
+ && !calc_cks(0, tvb, 4, tvb_len - 4)) {
+ *imb_flags = IPMI_D_BROADCAST|IPMI_D_TRG_SA;
+ *cks1 = 0;
+ *cks2 = 0;
+ return TRUE;
}
+ /*
+ * message with the starts with session handle
+ * and contain responder address
+ */
+ if (check_sh
+ && tvb_len >= 8
+ && !calc_cks(0, tvb, 1, 3)
+ && !calc_cks(0, tvb, 4, tvb_len - 4)) {
+ *imb_flags = IPMI_D_SESSION_HANDLE|IPMI_D_TRG_SA;
+ *cks1 = 0;
+ *cks2 = 0;
+ return TRUE;
+ }
- /* Save globals - we may be called recursively */
- saved_hdr = ipmi_current_hdr;
- ipmi_current_hdr = &hdr;
- saved_saved_data = current_saved_data;
- current_saved_data = NULL;
+ /*
+ * message with responder address
+ */
+ if (check_sa
+ && tvb_len >= 7
+ && !calc_cks(0, tvb, 0, 3)
+ && !calc_cks(0, tvb, 3, tvb_len - 3)) {
+ *imb_flags = IPMI_D_TRG_SA;
+ *cks1 = 0;
+ *cks2 = 0;
+ return TRUE;
+ }
- /* Select sub-handler */
- hnd = is_resp ? ic->parse_resp : ic->parse_req;
- /* Start new conversation if needed */
- if (!is_resp && (ic->flags & CMD_NEWCONV)) {
- conversation_new(pinfo->fd->num, &pinfo->src,
- &pinfo->dst, pinfo->ptype,
- pinfo->srcport, pinfo->destport, 0);
+ if (*imb_flags & IPMI_D_SESSION_HANDLE) {
+ sh_len = 1;
+ sa_len = 1;
+ rs_sa = 0;
+ } else if (*imb_flags & IPMI_D_TRG_SA) {
+ sh_len = 0;
+ sa_len = 1;
+ rs_sa = 0;
+ } else {
+ sh_len = 0;
+ sa_len = 0;
+ rs_sa = 0x20;
}
- /* Check if we need to insert request-response pair */
- maybe_insert_reqresp(pinfo, dfmt, &hdr);
+ /* check message length */
+ if (tvb_len < 6 + sh_len + sa_len) {
+ return FALSE;
+ }
- /* Create data subset: all but header and last byte (checksum) */
- data_tvb = tvb_new_subset(tvb, hdrlen, hdr.data_len, hdr.data_len);
+ /* calculate checksum deltas */
+ *cks1 = calc_cks(rs_sa, tvb, sh_len, sa_len + 2);
+ *cks2 = calc_cks(0, tvb, sh_len + sa_len + 2,
+ tvb_len - sh_len - sa_len - 2);
- /* Brief description of a packet */
- g_snprintf(dfmt->info, ITEM_LABEL_LENGTH, "%s, %s, seq 0x%02x%s%s%s",
- is_resp ? "Rsp" : "Req", cdesc, hdr.seq, bcast,
- hdr.ccode ? ", " : "", hdr.ccode ? ccdesc : "");
+ return TRUE;
+}
- if (!is_resp && (ic->flags & CMD_CALLRQ)) {
- hnd(data_tvb, pinfo, NULL);
- }
+int
+do_dissect_ipmb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gint hf_parent_item, gint ett_tree, ipmi_dissect_arg_t * arg)
+{
+ ipmi_context_t ctx;
+ guint offset = 0;
+ guint8 tmp;
- if (ipmi_tree) {
- add_reqresp_info(dfmt, &hdr, ipmi_tree, tvb, pinfo);
+ memset(&ctx, 0, sizeof(ctx));
- ti = proto_tree_add_text(ipmi_tree, tvb, 0, hdrlen,
- "Header: %s (%s) from 0x%02x to 0x%02x%s", cdesc,
- is_resp ? "Response" : "Request", hdr.src_sa, hdr.trg_sa, bcast);
- hdr_tree = proto_item_add_subtree(ti, ett_header);
+ /* copy message context and channel */
+ ctx.hdr.context = arg ? arg->context : 0;
+ ctx.hdr.channel = arg ? arg->channel : 0;
- offs = 0;
+ /* guess IPMB message format */
+ if (!guess_imb_format(tvb, ctx.hdr.context, ctx.hdr.channel,
+ &ctx.flags, &ctx.cks1, &ctx.cks2)) {
+ return 0;
+ }
- if (dfmt->flags & IPMI_D_SESSION_HANDLE) {
- proto_tree_add_item(hdr_tree, hf_ipmi_session_handle,
- tvb, offs++, 1, ENC_LITTLE_ENDIAN);
- }
+ /* check if message is broadcast */
+ if (ctx.flags & IPMI_D_BROADCAST) {
+ /* skip first byte */
+ offset++;
+ }
- /* Broadcast byte (optional) */
- if (is_broadcast) {
- proto_tree_add_uint_format(hdr_tree, hf_ipmi_header_broadcast,
- tvb, offs++, 1, 0x00, "Broadcast message");
- }
+ /* check is session handle is specified */
+ if (ctx.flags & IPMI_D_SESSION_HANDLE) {
+ ctx.hdr.session = tvb_get_guint8(tvb, offset++);
+ }
- /* Target SA, if present */
- if (dfmt->flags & IPMI_D_TRG_SA) {
- proto_tree_add_item(hdr_tree, hf_ipmi_header_trg, tvb, offs++, 1, ENC_LITTLE_ENDIAN);
- }
+ /* check is response address is specified */
+ if (ctx.flags & IPMI_D_TRG_SA) {
+ ctx.hdr.rs_sa = tvb_get_guint8(tvb, offset++);
+ } else {
+ ctx.hdr.rs_sa = 0x20;
+ }
- /* Network function + target LUN */
- ti = proto_tree_add_text(hdr_tree, tvb, offs, 1,
- "Target LUN: 0x%02x, NetFN: %s %s (0x%02x)", hdr.trg_lun,
- ndesc, is_resp ? "Response" : "Request", hdr.netfn);
- s_tree = proto_item_add_subtree(ti, ett_header_byte_1);
-
- proto_tree_add_item(s_tree, hf_ipmi_header_trg_lun, tvb, offs, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_uint_format(s_tree, hf_ipmi_header_netfn, tvb, offs, 1,
- hdr.netfn << 2, "%sNetFn: %s %s (0x%02x)",
- ipmi_dcd8(hdr.netfn << 2, 0xfc),
- ndesc, is_resp ? "Response" : "Request", hdr.netfn);
- offs++;
+ /* get Net Fn/RS LUN field */
+ tmp = tvb_get_guint8(tvb, offset++);
- /* Header checksum */
- if (hdr_crc == hdr_exp_crc) {
- proto_tree_add_uint_format_value(hdr_tree, hf_ipmi_header_crc, tvb, offs++, 1,
- hdr_crc, "0x%02x (correct)", hdr_crc);
- }
- else {
- ti = proto_tree_add_boolean(hdr_tree, hf_ipmi_bad_checksum, tvb, 0, 0, TRUE);
- PROTO_ITEM_SET_HIDDEN(ti);
- proto_tree_add_uint_format_value(hdr_tree, hf_ipmi_header_crc, tvb, offs++, 1,
- hdr_crc, "0x%02x (incorrect, expected 0x%02x)",
- hdr_crc, hdr_exp_crc);
- }
+ /* set Net Fn and RS LUN */
+ ctx.hdr.netfn = tmp >> 2;
+ ctx.hdr.rs_lun = tmp & 3;
- /* Remember where chk2 bytes start */
- data_chk_offs = offs;
+ /* skip cks1 */
+ offset++;
- /* Source SA */
- proto_tree_add_item(hdr_tree, hf_ipmi_header_src, tvb, offs++, 1, ENC_LITTLE_ENDIAN);
+ /* get RQ SA */
+ ctx.hdr.rq_sa = tvb_get_guint8(tvb, offset++);
- /* Sequence number + source LUN */
- ti = proto_tree_add_text(hdr_tree, tvb, offs, 1,
- "Source LUN: 0x%02x, SeqNo: 0x%02x",
- hdr.src_lun, hdr.seq);
- s_tree = proto_item_add_subtree(ti, ett_header_byte_4);
+ /* get RQ Seq/RQ LUN field */
+ tmp = tvb_get_guint8(tvb, offset++);
- proto_tree_add_item(s_tree, hf_ipmi_header_src_lun, tvb, offs, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(s_tree, hf_ipmi_header_sequence, tvb, offs, 1, ENC_LITTLE_ENDIAN);
- offs++;
+ /* set RQ Seq and RQ LUN */
+ ctx.hdr.rq_seq = tmp >> 2;
+ ctx.hdr.rq_lun = tmp & 3;
- /* Command */
- proto_tree_add_uint_format_value(hdr_tree, hf_ipmi_header_command, tvb, offs++, 1,
- hdr.cmd, "%s (0x%02x)", cdesc, hdr.cmd);
+ /* get command code */
+ ctx.hdr.cmd = tvb_get_guint8(tvb, offset++);
- /* Response code (if present) */
- if (is_resp) {
- proto_tree_add_uint_format_value(hdr_tree, hf_ipmi_header_completion, tvb, offs++, 1,
- hdr.ccode, "%s (0x%02x)", ccdesc, hdr.ccode);
- }
+ /* set header length */
+ ctx.hdr_len = offset;
- /* Defining body signature (if present) */
- if (siglen) {
- ti = proto_tree_add_item(hdr_tree, hf_ipmi_header_sig, tvb, offs, siglen, ENC_NA);
- proto_item_append_text(ti, " (%s)", ndesc);
- /*offs += siglen;*/
- }
+ /* copy direction */
+ ctx.hdr.dir = arg ? arg->flags >> 7 : ctx.hdr.netfn & 1;
- /* Call data parser */
- if (tvb_length(data_tvb) && hnd) {
- ti = proto_tree_add_text(ipmi_tree, data_tvb, 0, -1, "Data");
- data_tree = proto_item_add_subtree(ti, ett_data);
- hnd(data_tvb, pinfo, data_tree);
- }
+ if (ctx.hdr.context == IPMI_E_NONE) {
+ guint red = arg ? (arg->flags & 0x40) : 0;
- /* Checksum all but the last byte */
- len = tvb_length(tvb) - 1;
- data_crc = tvb_get_guint8(tvb, len);
- data_exp_crc = 0;
- for (i = data_chk_offs; i < len; i++) {
- data_exp_crc += tvb_get_guint8(tvb, i);
+ if (!ctx.hdr.channel) {
+ col_add_fstr(pinfo->cinfo, COL_DEF_SRC,
+ "0x%02x(%s)", ctx.hdr.rq_sa, red ? "IPMB-B" : "IPMB-A");
+ } else {
+ col_add_fstr(pinfo->cinfo, COL_DEF_SRC,
+ "0x%02x", ctx.hdr.rq_sa);
}
- data_exp_crc = (0 - data_exp_crc) & 0xff;
- if (data_crc == data_exp_crc) {
- proto_tree_add_uint_format_value(ipmi_tree, hf_ipmi_data_crc, tvb, len, 1,
- data_crc, "0x%02x (correct)", data_crc);
- }
- else {
- ti = proto_tree_add_boolean(hdr_tree, hf_ipmi_bad_checksum, tvb, 0, 0, TRUE);
- PROTO_ITEM_SET_HIDDEN(ti);
- proto_tree_add_uint_format_value(ipmi_tree, hf_ipmi_data_crc, tvb, len, 1,
- data_crc, "0x%02x (incorrect, expected 0x%02x)",
- data_crc, data_exp_crc);
- }
+ col_add_fstr(pinfo->cinfo, COL_DEF_DST, "0x%02x", ctx.hdr.rs_sa);
}
- /* Restore globals, in case we've been called recursively */
- ipmi_current_hdr = saved_hdr;
- current_saved_data = saved_saved_data;
- nest_level--;
+ /* dissect IPMI command */
+ return dissect_ipmi_cmd(tvb, pinfo, tree, hf_parent_item, ett_tree, &ctx);
}
-static void
-dissect_ipmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_ipmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- proto_tree *ipmi_tree = NULL;
- proto_item *ti;
- ipmi_dissect_format_t dfmt;
-
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPMI/ATCA");
-
- if (tree) {
- ti = proto_tree_add_item(tree, proto_ipmi, tvb, 0, -1, ENC_NA);
- ipmi_tree = proto_item_add_subtree(ti, ett_ipmi);
- }
-
- memset(&dfmt, 0, sizeof(dfmt));
- dfmt.flags = IPMI_D_BROADCAST | IPMI_D_TRG_SA;
- ipmi_do_dissect(tvb, pinfo, ipmi_tree, &dfmt);
-
- col_add_str(pinfo->cinfo, COL_INFO, dfmt.info);
-
+ return do_dissect_ipmb(tvb, pinfo, tree, proto_ipmb, ett_ipmi,
+ (ipmi_dissect_arg_t *) data);
}
/* Register IPMB protocol.
*/
-
void
proto_register_ipmi(void)
{
static hf_register_info hf[] = {
- { &hf_ipmi_message, { "Message", "ipmi.message", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_session_handle, { "Session handle", "ipmi.session_handle", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
- { &hf_ipmi_header_broadcast, { "Broadcast message", "ipmi.header.broadcast", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_header_trg, { "Target Address", "ipmi.header.target", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_ipmi_header_trg_lun, { "Target LUN", "ipmi.header.trg_lun", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }},
{ &hf_ipmi_header_netfn, { "NetFN", "ipmi.header.netfn", FT_UINT8, BASE_HEX, NULL, 0xfc, NULL, HFILL }},
{ &hf_ipmi_header_crc, { "Header Checksum", "ipmi.header.crc", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_header_src, { "Source Address", "ipmi.header.source", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_header_src_lun, { "Source LUN", "ipmi.header.src_lun", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }},
+ { &hf_ipmi_header_bridged, { "Bridged", "ipmi.header.bridged", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }},
{ &hf_ipmi_header_sequence, { "Sequence Number", "ipmi.header.sequence", FT_UINT8, BASE_HEX, NULL, 0xfc, NULL, HFILL }},
{ &hf_ipmi_header_command, { "Command", "ipmi.header.command", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_header_completion, { "Completion Code", "ipmi.header.completion", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
@@ -1379,8 +1746,7 @@ proto_register_ipmi(void)
{ &hf_ipmi_data_crc, { "Data checksum", "ipmi.data.crc", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_response_to, { "Response to", "ipmi.response_to", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_ipmi_response_in, { "Response in", "ipmi.response_in", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }},
- { &hf_ipmi_response_time, { "Responded in", "ipmi.response_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }},
- { &hf_ipmi_bad_checksum, { "Bad checksum", "ipmi.bad_checksum", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}
+ { &hf_ipmi_response_time, { "Responded in", "ipmi.response_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }}
};
static gint *ett[] = {
&ett_ipmi,
@@ -1406,9 +1772,19 @@ proto_register_ipmi(void)
guint32 i;
proto_ipmi = proto_register_protocol("Intelligent Platform Management Interface",
- "IPMI/ATCA",
+ "IPMI",
"ipmi");
+ proto_ipmb = proto_register_protocol("Intelligent Platform Management Bus",
+ "IPMB",
+ "ipmb");
+ proto_kcs = proto_register_protocol("Keyboard Controller Style Interface",
+ "KCS",
+ "kcs");
+ proto_tmode = proto_register_protocol("Serial Terminal Mode Interface",
+ "TMode",
+ "tmode");
+
proto_register_field_array(proto_ipmi, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
@@ -1434,8 +1810,14 @@ proto_register_ipmi(void)
ipmi_register_transport(proto_ipmi);
ipmi_register_picmg(proto_ipmi);
ipmi_register_pps(proto_ipmi);
+ ipmi_register_vita(proto_ipmi);
+
+ new_register_dissector("ipmi", dissect_ipmi, proto_ipmi);
+ new_register_dissector("ipmb", dissect_ipmi, proto_ipmb);
+ new_register_dissector("kcs", dissect_kcs, proto_kcs);
+ new_register_dissector("tmode", dissect_tmode, proto_tmode);
- register_dissector("ipmi", dissect_ipmi, proto_ipmi);
+ data_dissector = find_dissector("data");
m = prefs_register_protocol(proto_ipmi, NULL);
prefs_register_bool_preference(m, "fru_langcode_is_english", "FRU Language Code is English",
diff --git a/epan/dissectors/packet-ipmi.h b/epan/dissectors/packet-ipmi.h
index 840506f737..f28a994c09 100644
--- a/epan/dissectors/packet-ipmi.h
+++ b/epan/dissectors/packet-ipmi.h
@@ -54,23 +54,36 @@ enum {
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;
+/*
+ * Command context (environment).
+ */
+enum {
+ IPMI_E_NONE, /* no surround environment */
+ IPMI_E_SENDMSG_RQ, /* encapsulated into Send Message request */
+ IPMI_E_SENDMSG_RS, /* encapsulated into Send Message response */
+ IPMI_E_GETMSG /* encapsulated into Get Message response */
};
-extern struct ipmi_header *ipmi_current_hdr;
+/*
+ * Cached IPMI message header.
+ */
+typedef struct {
+ guint8 context;
+ guint8 channel;
+ guint8 dir;
+ guint8 session;
+ guint8 rs_sa;
+ guint8 rs_lun;
+ guint8 netfn;
+ guint8 rq_sa;
+ guint8 rq_lun;
+ guint8 rq_seq;
+ guint8 cmd;
+} ipmi_header_t;
/* Sub-parser */
-typedef void (*ipmi_cmd_handler_t)(tvbuff_t *, packet_info *, proto_tree *);
+typedef void (*ipmi_cmd_handler_t)(tvbuff_t *,
+ packet_info *, proto_tree *);
/* IPMI command structure. */
typedef struct {
@@ -84,12 +97,19 @@ typedef struct {
} 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);
+/* Get currently parsed message header */
+const ipmi_header_t * ipmi_get_hdr(packet_info * pinfo);
+
+/* Get completion code for currently parsed message */
+guint8 ipmi_get_ccode(packet_info * pinfo);
+
+/* Save request data for later use in response */
+void ipmi_set_data(packet_info *pinfo, guint idx, guint32 data);
+
+/* Get saved request data */
+gboolean ipmi_get_data(packet_info *pinfo, guint idx, guint32 * data);
/* Top-level search structure: signatures (if any) + command table */
typedef struct ipmi_netfn_handler {
@@ -154,35 +174,30 @@ void ipmi_register_se(int proto);
void ipmi_register_storage(int proto);
void ipmi_register_transport(int proto);
void ipmi_register_update(int proto);
+void ipmi_register_vita(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;
-
+#define IPMI_D_NONE 0x0001 /* Do not parse at all */
+#define IPMI_D_SESSION_HANDLE 0x0002 /* Session handle */
+#define IPMI_D_BROADCAST 0x0004 /* Check for broadcast message */
+#define IPMI_D_TRG_SA 0x0008 /* Target slave addr is present */
+#define IPMI_D_TMODE 0x0010 /* Bridged field instead of Rq LUN */
+#define IPMI_D_NO_CKS 0x0020 /* Checksum bytes are not present */
+#define IPMI_D_NO_RQ_SA 0x0040 /* RQ SA is not present */
+#define IPMI_D_NO_SEQ 0x0080 /* RQ Seq is not present */
+
+/* IPMI dissector argument */
typedef struct {
- 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, packet_info *pinfo, 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);
+ guint8 context;
+ guint8 channel;
+ guint8 flags;
+} ipmi_dissect_arg_t;
-#endif
+int
+do_dissect_ipmb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gint hf_parent_item, gint ett_tree, ipmi_dissect_arg_t * arg);
+#endif /* __PACKET_IPMI_H__ */
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html