aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-bpdu.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-10-29 21:01:57 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-10-29 21:01:57 +0000
commitdc473022830f7be911dc3dd7fc3016f686cf3b09 (patch)
treef00f31daee0b3516c996f12e82626aa8aca90c9f /epan/dissectors/packet-bpdu.c
parented9c9cc01a67df9d75d084302eb5c42a69f36c47 (diff)
from sake blok
Hi, The attached file is a patch to packet-bpdu.c so that Wireshark is able to dissect the Cisco MST BPDU's that I encountered last week. Cheers, Sake svn path=/trunk/; revision=19734
Diffstat (limited to 'epan/dissectors/packet-bpdu.c')
-rw-r--r--epan/dissectors/packet-bpdu.c496
1 files changed, 334 insertions, 162 deletions
diff --git a/epan/dissectors/packet-bpdu.c b/epan/dissectors/packet-bpdu.c
index 837c474127..84b2495a9f 100644
--- a/epan/dissectors/packet-bpdu.c
+++ b/epan/dissectors/packet-bpdu.c
@@ -40,40 +40,57 @@
/* Offsets of fields within a BPDU */
-#define BPDU_IDENTIFIER 0
-#define BPDU_VERSION_IDENTIFIER 2
-#define BPDU_TYPE 3
-#define BPDU_FLAGS 4
-#define BPDU_ROOT_IDENTIFIER 5
-#define BPDU_ROOT_PATH_COST 13
-#define BPDU_BRIDGE_IDENTIFIER 17
-#define BPDU_PORT_IDENTIFIER 25
-#define BPDU_MESSAGE_AGE 27
-#define BPDU_MAX_AGE 29
-#define BPDU_HELLO_TIME 31
-#define BPDU_FORWARD_DELAY 33
-#define BPDU_VERSION_1_LENGTH 35
-#define BPDU_VERSION_3_LENGTH 36
-#define BPDU_MST_CONFIG_FORMAT_SELECTOR 38
-#define BPDU_MST_CONFIG_NAME 39
-#define BPDU_MST_CONFIG_REVISION_LEVEL 71
-#define BPDU_MST_CONFIG_DIGEST 73
-#define BPDU_CIST_INTERNAL_ROOT_PATH_COST 89
-#define BPDU_CIST_BRIDGE_IDENTIFIER 93
-#define BPDU_CIST_REMAINING_HOPS 101
-#define BPDU_MSTI 102
-#define MSTI_FLAGS 0
-#define MSTI_REGIONAL_ROOT 1
-#define MSTI_INTERNAL_ROOT_PATH_COST 9
-#define MSTI_BRIDGE_IDENTIFIER_PRIORITY 13
-#define MSTI_PORT_IDENTIFIER_PRIORITY 14
-#define MSTI_REMAINING_HOPS 15
-
-#define CONF_BPDU_SIZE 35
-#define TC_BPDU_SIZE 4
-#define RST_BPDU_SIZE 36
-#define VERSION_3_STATIC_LENGTH 64
-#define MSTI_MESSAGE_SIZE 16
+#define BPDU_IDENTIFIER 0
+#define BPDU_VERSION_IDENTIFIER 2
+#define BPDU_TYPE 3
+#define BPDU_FLAGS 4
+#define BPDU_ROOT_IDENTIFIER 5
+#define BPDU_ROOT_PATH_COST 13
+#define BPDU_BRIDGE_IDENTIFIER 17
+#define BPDU_PORT_IDENTIFIER 25
+#define BPDU_MESSAGE_AGE 27
+#define BPDU_MAX_AGE 29
+#define BPDU_HELLO_TIME 31
+#define BPDU_FORWARD_DELAY 33
+#define BPDU_VERSION_1_LENGTH 35
+#define BPDU_VERSION_3_LENGTH 36
+#define BPDU_MST_CONFIG_FORMAT_SELECTOR 38
+#define BPDU_MST_CONFIG_NAME 39
+#define BPDU_MST_CONFIG_REVISION_LEVEL 71
+#define BPDU_MST_CONFIG_DIGEST 73
+#define BPDU_CIST_INTERNAL_ROOT_PATH_COST 89
+#define BPDU_CIST_BRIDGE_IDENTIFIER 93
+#define BPDU_CIST_REMAINING_HOPS 101
+#define BPDU_MSTI 102
+
+#define MSTI_FLAGS 0
+#define MSTI_REGIONAL_ROOT 1
+#define MSTI_INTERNAL_ROOT_PATH_COST 9
+#define MSTI_BRIDGE_IDENTIFIER_PRIORITY 13
+#define MSTI_PORT_IDENTIFIER_PRIORITY 14
+#define MSTI_REMAINING_HOPS 15
+
+
+#define CONF_BPDU_SIZE 35
+#define TC_BPDU_SIZE 4
+#define MST_BPDU_SIZE 38
+#define VERSION_3_STATIC_LENGTH 64
+#define MSTI_MESSAGE_SIZE 16
+
+/* Values for the Alternative MSTI format */
+
+#define ALT_BPDU_CIST_BRIDGE_IDENTIFIER 89
+#define ALT_BPDU_CIST_INTERNAL_ROOT_PATH_COST 97
+
+#define ALT_MSTI_MSTID 0
+#define ALT_MSTI_FLAGS 2
+#define ALT_MSTI_REGIONAL_ROOT 3
+#define ALT_MSTI_INTERNAL_ROOT_PATH_COST 11
+#define ALT_MSTI_BRIDGE_IDENTIFIER 15
+#define ALT_MSTI_PORT_IDENTIFIER 23
+#define ALT_MSTI_REMAINING_HOPS 25
+
+#define ALT_MSTI_MESSAGE_SIZE 26
/* Flag bits */
@@ -120,6 +137,7 @@ static int hf_bpdu_msti_regional_root_mac = -1;
static int hf_bpdu_msti_internal_root_path_cost = -1;
static int hf_bpdu_msti_bridge_identifier_priority = -1;
static int hf_bpdu_msti_port_identifier_priority = -1;
+static int hf_bpdu_msti_port_id = -1;
static int hf_bpdu_msti_remaining_hops = -1;
static gint ett_bpdu = -1;
@@ -151,6 +169,10 @@ static const value_string bpdu_type_vals[] = {
#define PROTO_VERSION_RSTP 2
#define PROTO_VERSION_MSTP 3
+#define MSTI_FORMAT_UNKNOWN 0
+#define MSTI_FORMAT_IEEE_8021S 1
+#define MSTI_FORMAT_ALTERNATIVE 2
+
static const value_string version_id_vals[] = {
{ PROTO_VERSION_STP, "Spanning Tree" },
{ PROTO_VERSION_RSTP, "Rapid Spanning Tree" },
@@ -195,14 +217,18 @@ dissect_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
double forward_delay;
guint8 version_1_length;
guint16 version_3_length;
+ guint8 config_format_selector;
guint16 cist_bridge_identifier_bridge_priority;
const guint8 *cist_bridge_identifier_mac;
gchar *cist_bridge_identifier_mac_str;
+ guint16 msti_mstid;
guint32 msti_regional_root_mstid, msti_regional_root_priority;
const guint8 *msti_regional_root_mac;
gchar *msti_regional_root_mac_str;
- guint8 msti_bridge_identifier_priority, msti_port_identifier_priority;
- int total_msti_length, offset, msti;
+ guint16 msti_bridge_identifier_priority, msti_port_identifier_priority;
+ const guint8 *msti_bridge_identifier_mac;
+ gchar *msti_bridge_identifier_mac_str;
+ int total_msti_length, offset, msti, msti_format;
proto_tree *bpdu_tree;
proto_tree *mstp_tree, *msti_tree;
@@ -461,43 +487,66 @@ dissect_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* 0000 0000", "Protocol Version Identifier is 3 or
* greater", "BPDU Type is 0000 0010", "contains 102 or
* more octets", and "a Version 1 Length of 0" tests.
- * Fetch the Version 3 Length, and see whether it's a
- * multiple of the MSTI Configuration Message length.
*/
version_3_length = tvb_get_ntohs(tvb, BPDU_VERSION_3_LENGTH);
proto_tree_add_uint(bpdu_tree, hf_bpdu_version_3_length, tvb,
BPDU_VERSION_3_LENGTH, 2, version_3_length);
- if (version_3_length >= VERSION_3_STATIC_LENGTH) {
- set_actual_length(tvb, RST_BPDU_SIZE + 2 + version_3_length);
- total_msti_length = version_3_length - VERSION_3_STATIC_LENGTH;
+
+ /*
+ * Check the Version 3 Length, and see whether it's a
+ * multiple of the MSTI Configuration Message length. Also
+ * check the config_format_selector because some MST BPDU's
+ * have BPDU_VERSION_3_LENGTH set to 0 and use the
+ * field BPDU_MST_CONFIG_FORMAT_SELECTOR as a length-field
+ * for the MSTI data.
+ */
+ config_format_selector = tvb_get_guint8(tvb, BPDU_MST_CONFIG_FORMAT_SELECTOR);
+ if (version_3_length != 0) {
+ msti_format = MSTI_FORMAT_IEEE_8021S;
+ if (version_3_length >= VERSION_3_STATIC_LENGTH) {
+ total_msti_length = version_3_length - VERSION_3_STATIC_LENGTH;
+ } else {
+ /*
+ * XXX - there appears to be an ambiguity in the 802.3Q-2003
+ * standard and at least some of the 802.3s drafts.
+ *
+ * The "Version 3 Length" field is defined to be "the number of
+ * octets taken by the parameters that follow in the BPDU", but
+ * it's spoken of as "representing an integral number, from 0 to
+ * 64 inclusive, of MSTI Configuration Messages".
+ *
+ * According to mail from a member of the stds-802-1@ieee.org list,
+ * the latter of those is just saying that the length must not have
+ * a value that implies that there's a partial MSTI message in the
+ * packet; it's still in units of octets, not messages.
+ *
+ * However, it appears that Cisco's C3550 software (C3550-I5Q3L2-M,
+ * Version 12.1(12c)EA1) might be sending out lengths in units of
+ * messages.
+ *
+ * This length can't be the number of octets taken by the parameters
+ * that follow in the BPDU, because it's less than the fixed-length
+ * portion of those parameters, so we assume the length is a count of
+ * messages.
+ */
+ total_msti_length = version_3_length * MSTI_MESSAGE_SIZE;
+ }
} else {
- /*
- * XXX - there appears to be an ambiguity in the 802.3Q-2003
- * standard and at least some of the 802.3s drafts.
- *
- * The "Version 3 Length" field is defined to be "the number of
- * octets taken by the parameters that follow in the BPDU", but
- * it's spoken of as "representing an integral number, from 0 to
- * 64 inclusive, of MSTI Configuration Messages".
- *
- * According to mail from a member of the stds-802-1@ieee.org list,
- * the latter of those is just saying that the length must not have
- * a value that implies that there's a partial MSTI message in the
- * packet; it's still in units of octets, not messages.
- *
- * However, it appears that Cisco's C3550 software (C3550-I5Q3L2-M,
- * Version 12.1(12c)EA1) might be sending out lengths in units of
- * messages.
- *
- * This length can't be the number of octets taken by the parameters
- * that follow in the BPDU, because it's less than the fixed-length
- * portion of those parameters, so we assume the length is a count of
- * messages.
- */
- set_actual_length(tvb, RST_BPDU_SIZE + 2 + VERSION_3_STATIC_LENGTH +
- version_3_length * MSTI_MESSAGE_SIZE);
- total_msti_length = version_3_length * MSTI_MESSAGE_SIZE;
+ if (tvb_reported_length(tvb) == config_format_selector + MST_BPDU_SIZE + 1 ) {
+ msti_format = MSTI_FORMAT_ALTERNATIVE;
+ total_msti_length = config_format_selector - VERSION_3_STATIC_LENGTH;
+ } else {
+ /*
+ * XXX - Unknown MSTI format, since version_3_length is 0
+ * lets assume there are no msti instances in the packet.
+ */
+ msti_format = MSTI_FORMAT_UNKNOWN;
+ total_msti_length = 0;
+ }
+
}
+ set_actual_length(tvb, BPDU_MSTI + total_msti_length);
+
mstp_item = proto_tree_add_text(bpdu_tree, tvb, BPDU_VERSION_3_LENGTH,
-1, "MST Extension");
mstp_tree = proto_item_add_subtree(mstp_item, ett_mstp);
@@ -512,109 +561,228 @@ dissect_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(mstp_tree, hf_bpdu_mst_config_digest, tvb,
BPDU_MST_CONFIG_DIGEST, 16, FALSE);
- proto_tree_add_item(mstp_tree, hf_bpdu_cist_internal_root_path_cost, tvb,
- BPDU_CIST_INTERNAL_ROOT_PATH_COST, 4, FALSE);
-
- cist_bridge_identifier_bridge_priority = tvb_get_ntohs(tvb,BPDU_CIST_BRIDGE_IDENTIFIER);
- cist_bridge_identifier_mac = tvb_get_ptr(tvb, BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6);
- cist_bridge_identifier_mac_str = ether_to_str(cist_bridge_identifier_mac);
- proto_tree_add_text(mstp_tree, tvb, BPDU_CIST_BRIDGE_IDENTIFIER, 8,
- "CIST Bridge Identifier: %d / %s",
- cist_bridge_identifier_bridge_priority,
- cist_bridge_identifier_mac_str);
- proto_tree_add_ether_hidden(mstp_tree, hf_bpdu_cist_bridge_identifier_mac, tvb,
- BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6,
- cist_bridge_identifier_mac);
+ switch(msti_format) {
+
+ case MSTI_FORMAT_IEEE_8021S:
+ proto_tree_add_item(mstp_tree, hf_bpdu_cist_internal_root_path_cost, tvb,
+ BPDU_CIST_INTERNAL_ROOT_PATH_COST, 4, FALSE);
+
+ cist_bridge_identifier_bridge_priority = tvb_get_ntohs(tvb,BPDU_CIST_BRIDGE_IDENTIFIER);
+ cist_bridge_identifier_mac = tvb_get_ptr(tvb, BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6);
+ cist_bridge_identifier_mac_str = ether_to_str(cist_bridge_identifier_mac);
+ proto_tree_add_text(mstp_tree, tvb, BPDU_CIST_BRIDGE_IDENTIFIER, 8,
+ "CIST Bridge Identifier: %d / %s",
+ cist_bridge_identifier_bridge_priority,
+ cist_bridge_identifier_mac_str);
+ proto_tree_add_ether_hidden(mstp_tree, hf_bpdu_cist_bridge_identifier_mac, tvb,
+ BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6,
+ cist_bridge_identifier_mac);
+ break;
+
+ case MSTI_FORMAT_ALTERNATIVE:
+ cist_bridge_identifier_bridge_priority = tvb_get_ntohs(tvb,ALT_BPDU_CIST_BRIDGE_IDENTIFIER);
+ cist_bridge_identifier_mac = tvb_get_ptr(tvb, ALT_BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6);
+ cist_bridge_identifier_mac_str = ether_to_str(cist_bridge_identifier_mac);
+ proto_tree_add_text(mstp_tree, tvb, ALT_BPDU_CIST_BRIDGE_IDENTIFIER, 8,
+ "CIST Bridge Identifier: %d / %s",
+ cist_bridge_identifier_bridge_priority,
+ cist_bridge_identifier_mac_str);
+ proto_tree_add_ether_hidden(mstp_tree, hf_bpdu_cist_bridge_identifier_mac, tvb,
+ ALT_BPDU_CIST_BRIDGE_IDENTIFIER + 2, 6,
+ cist_bridge_identifier_mac);
+
+ proto_tree_add_item(mstp_tree, hf_bpdu_cist_internal_root_path_cost, tvb,
+ ALT_BPDU_CIST_INTERNAL_ROOT_PATH_COST, 4, FALSE);
+
+ break;
+ }
proto_tree_add_item(mstp_tree, hf_bpdu_cist_remaining_hops, tvb,
BPDU_CIST_REMAINING_HOPS, 1, FALSE);
-
/* MSTI messages */
offset = BPDU_MSTI;
msti = 1;
while (total_msti_length > 0) {
- msti_regional_root_mstid = tvb_get_guint8(tvb, offset+ MSTI_REGIONAL_ROOT);
- msti_regional_root_priority = (msti_regional_root_mstid &0xf0) << 8;
- msti_regional_root_mstid = ((msti_regional_root_mstid & 0x0f) << 8) +
- tvb_get_guint8(tvb, offset+ MSTI_REGIONAL_ROOT+1);
- msti_regional_root_mac = tvb_get_ptr(tvb, offset+ MSTI_REGIONAL_ROOT + 2, 6);
- msti_regional_root_mac_str = ether_to_str(msti_regional_root_mac);
-
- msti_item = proto_tree_add_text(mstp_tree, tvb, offset, 16,
- "MSTID %d, Regional Root Identifier %d / %s",
- msti_regional_root_mstid,
- msti_regional_root_priority,
- msti_regional_root_mac_str);
- msti_tree = proto_item_add_subtree(msti_item, ett_msti);
-
- /* flags */
- flags = tvb_get_guint8(tvb, offset+MSTI_FLAGS);
- flags_item = proto_tree_add_uint(msti_tree, hf_bpdu_msti_flags, tvb,
- offset+MSTI_FLAGS, 1, flags);
- flags_tree = proto_item_add_subtree(flags_item, ett_bpdu_flags);
-
- sep = initial_sep;
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TCACK, flags_item, "%sMaster");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tcack, tvb,
- offset+MSTI_FLAGS, 1, flags);
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_AGREEMENT, flags_item, "%sAgreement");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_agreement, tvb,
- offset+MSTI_FLAGS, 1, flags);
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_FORWARDING, flags_item, "%sForwarding");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_forwarding, tvb,
- offset+MSTI_FLAGS, 1, flags);
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_LEARNING, flags_item, "%sLearning");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_learning, tvb,
- offset+MSTI_FLAGS, 1, flags);
- if (flags_item) {
- guint8 port_role;
- port_role = (flags & BPDU_FLAGS_PORT_ROLE_MASK) >> BPDU_FLAGS_PORT_ROLE_SHIFT;
- proto_item_append_text(flags_item, "%sPort Role: %s", sep,
- val_to_str(port_role, role_vals,
- "Unknown (%u)"));
- }
- proto_tree_add_uint(flags_tree, hf_bpdu_flags_port_role, tvb,
- offset+MSTI_FLAGS, 1, flags);
- sep = cont_sep;
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_PROPOSAL, flags_item, "%sProposal");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_proposal, tvb,
- offset+MSTI_FLAGS, 1, flags);
- APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TC, flags_item, "%sTopology Change");
- proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tc, tvb,
- offset+MSTI_FLAGS, 1, flags);
- if (sep != initial_sep) { /* We put something in; put in the terminating ")" */
- proto_item_append_text(flags_item, ")");
- }
+ switch(msti_format) {
+
+ case MSTI_FORMAT_IEEE_8021S:
+ msti_regional_root_mstid = tvb_get_guint8(tvb, offset+ MSTI_REGIONAL_ROOT);
+ msti_regional_root_priority = (msti_regional_root_mstid &0xf0) << 8;
+ msti_regional_root_mstid = ((msti_regional_root_mstid & 0x0f) << 8) +
+ tvb_get_guint8(tvb, offset+ MSTI_REGIONAL_ROOT+1);
+ msti_regional_root_mac = tvb_get_ptr(tvb, offset+ MSTI_REGIONAL_ROOT + 2, 6);
+ msti_regional_root_mac_str = ether_to_str(msti_regional_root_mac);
+
+ msti_item = proto_tree_add_text(mstp_tree, tvb, offset, 16,
+ "MSTID %d, Regional Root Identifier %d / %s",
+ msti_regional_root_mstid,
+ msti_regional_root_priority,
+ msti_regional_root_mac_str);
+ msti_tree = proto_item_add_subtree(msti_item, ett_msti);
+
+ /* flags */
+ flags = tvb_get_guint8(tvb, offset+MSTI_FLAGS);
+ flags_item = proto_tree_add_uint(msti_tree, hf_bpdu_msti_flags, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ flags_tree = proto_item_add_subtree(flags_item, ett_bpdu_flags);
+
+ sep = initial_sep;
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TCACK, flags_item, "%sMaster");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tcack, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_AGREEMENT, flags_item, "%sAgreement");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_agreement, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_FORWARDING, flags_item, "%sForwarding");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_forwarding, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_LEARNING, flags_item, "%sLearning");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_learning, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ if (flags_item) {
+ guint8 port_role;
+ port_role = (flags & BPDU_FLAGS_PORT_ROLE_MASK) >> BPDU_FLAGS_PORT_ROLE_SHIFT;
+ proto_item_append_text(flags_item, "%sPort Role: %s", sep,
+ val_to_str(port_role, role_vals,
+ "Unknown (%u)"));
+ }
+ proto_tree_add_uint(flags_tree, hf_bpdu_flags_port_role, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ sep = cont_sep;
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_PROPOSAL, flags_item, "%sProposal");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_proposal, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TC, flags_item, "%sTopology Change");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tc, tvb,
+ offset+MSTI_FLAGS, 1, flags);
+ if (sep != initial_sep) { /* We put something in; put in the terminating ")" */
+ proto_item_append_text(flags_item, ")");
+ }
+
+ /* pri, MSTID, Regional root */
+ proto_tree_add_ether_hidden(msti_tree, hf_bpdu_msti_regional_root_mac, tvb,
+ offset + MSTI_REGIONAL_ROOT + 2, 6,
+ msti_regional_root_mac);
+ proto_tree_add_text(msti_tree, tvb, offset + MSTI_REGIONAL_ROOT, 8,
+ "MSTID %d, priority %d Root Identifier %s",
+ msti_regional_root_mstid,
+ msti_regional_root_priority,
+ msti_regional_root_mac_str);
+
+
+ proto_tree_add_item(msti_tree, hf_bpdu_msti_internal_root_path_cost, tvb,
+ offset+MSTI_INTERNAL_ROOT_PATH_COST, 4, FALSE);
+
+ msti_bridge_identifier_priority = tvb_get_guint8(tvb, offset+MSTI_BRIDGE_IDENTIFIER_PRIORITY) >> 4;
+ msti_port_identifier_priority = tvb_get_guint8(tvb, offset+MSTI_PORT_IDENTIFIER_PRIORITY) >> 4;
+
+ proto_tree_add_uint(msti_tree, hf_bpdu_msti_bridge_identifier_priority, tvb,
+ offset+MSTI_BRIDGE_IDENTIFIER_PRIORITY, 1,
+ msti_bridge_identifier_priority);
+ proto_tree_add_uint(msti_tree, hf_bpdu_msti_port_identifier_priority, tvb,
+ offset+MSTI_PORT_IDENTIFIER_PRIORITY, 1,
+ msti_port_identifier_priority);
+
+ proto_tree_add_item(msti_tree, hf_bpdu_msti_remaining_hops, tvb,
+ offset + MSTI_REMAINING_HOPS, 1, FALSE);
+
+ total_msti_length -= MSTI_MESSAGE_SIZE;
+ offset += MSTI_MESSAGE_SIZE;
+ break;
+
+ case MSTI_FORMAT_ALTERNATIVE:
+ msti_regional_root_mstid = tvb_get_guint8(tvb, offset+ ALT_MSTI_REGIONAL_ROOT);
+ msti_regional_root_priority = (msti_regional_root_mstid &0xf0) << 8;
+ msti_regional_root_mstid = ((msti_regional_root_mstid & 0x0f) << 8) +
+ tvb_get_guint8(tvb, offset+ ALT_MSTI_REGIONAL_ROOT+1);
+ msti_regional_root_mac = tvb_get_ptr(tvb, offset+ ALT_MSTI_REGIONAL_ROOT + 2, 6);
+ msti_regional_root_mac_str = ether_to_str(msti_regional_root_mac);
+
+ msti_item = proto_tree_add_text(mstp_tree, tvb, offset, 16,
+ "MSTID %d, Regional Root Identifier %d / %s",
+ msti_regional_root_mstid,
+ msti_regional_root_priority,
+ msti_regional_root_mac_str);
+ msti_tree = proto_item_add_subtree(msti_item, ett_msti);
+
+ msti_mstid = tvb_get_ntohs(tvb, offset+ ALT_MSTI_MSTID);
+ proto_tree_add_text(msti_tree, tvb, offset+ALT_MSTI_MSTID, 2,
+ "MSTID: %d", msti_mstid);
+
+ /* flags */
+ flags = tvb_get_guint8(tvb, offset+ALT_MSTI_FLAGS);
+ flags_item = proto_tree_add_uint(msti_tree, hf_bpdu_msti_flags, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ flags_tree = proto_item_add_subtree(flags_item, ett_bpdu_flags);
+
+ sep = initial_sep;
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TCACK, flags_item, "%sMaster");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tcack, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_AGREEMENT, flags_item, "%sAgreement");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_agreement, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_FORWARDING, flags_item, "%sForwarding");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_forwarding, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_LEARNING, flags_item, "%sLearning");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_learning, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ if (flags_item) {
+ guint8 port_role;
+ port_role = (flags & BPDU_FLAGS_PORT_ROLE_MASK) >> BPDU_FLAGS_PORT_ROLE_SHIFT;
+ proto_item_append_text(flags_item, "%sPort Role: %s", sep,
+ val_to_str(port_role, role_vals,
+ "Unknown (%u)"));
+ }
+ proto_tree_add_uint(flags_tree, hf_bpdu_flags_port_role, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ sep = cont_sep;
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_PROPOSAL, flags_item, "%sProposal");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_proposal, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TC, flags_item, "%sTopology Change");
+ proto_tree_add_boolean(flags_tree, hf_bpdu_flags_tc, tvb,
+ offset+ALT_MSTI_FLAGS, 1, flags);
+ if (sep != initial_sep) { /* We put something in; put in the terminating ")" */
+ proto_item_append_text(flags_item, ")");
+ }
+
+ /* pri, MSTID, Regional root */
+ proto_tree_add_ether_hidden(msti_tree, hf_bpdu_msti_regional_root_mac, tvb,
+ offset + ALT_MSTI_REGIONAL_ROOT + 2, 6,
+ msti_regional_root_mac);
+ proto_tree_add_text(msti_tree, tvb, offset + ALT_MSTI_REGIONAL_ROOT, 8,
+ "MSTI Regional Root Identifier: %d / %d / %s",
+ msti_regional_root_mstid,
+ msti_regional_root_priority,
+ msti_regional_root_mac_str);
+
+
+ proto_tree_add_item(msti_tree, hf_bpdu_msti_internal_root_path_cost, tvb,
+ offset+ALT_MSTI_INTERNAL_ROOT_PATH_COST, 4, FALSE);
+
+ msti_bridge_identifier_priority = tvb_get_ntohs(tvb, offset+ALT_MSTI_BRIDGE_IDENTIFIER);
+ msti_bridge_identifier_mac = tvb_get_ptr(tvb, offset+ALT_MSTI_BRIDGE_IDENTIFIER + 2, 6);
+ msti_bridge_identifier_mac_str = ether_to_str(msti_bridge_identifier_mac);
+ proto_tree_add_text(msti_tree, tvb, offset+ALT_MSTI_BRIDGE_IDENTIFIER, 8,
+ "MSTI Bridge Identifier: %d / %d / %s",
+ msti_bridge_identifier_priority & 0x0fff,
+ msti_bridge_identifier_priority & 0xf000,
+ msti_bridge_identifier_mac_str);
+
+ msti_port_identifier_priority = tvb_get_ntohs(tvb, offset+ALT_MSTI_PORT_IDENTIFIER);
+ proto_tree_add_uint(msti_tree, hf_bpdu_msti_port_id, tvb,
+ offset+ALT_MSTI_PORT_IDENTIFIER, 2, msti_port_identifier_priority);
+
+ proto_tree_add_item(msti_tree, hf_bpdu_msti_remaining_hops, tvb,
+ offset + ALT_MSTI_REMAINING_HOPS, 1, FALSE);
+
+ total_msti_length -= ALT_MSTI_MESSAGE_SIZE;
+ offset += ALT_MSTI_MESSAGE_SIZE;
+ break;
- /* pri, MSTID, Regional root */
- proto_tree_add_ether_hidden(msti_tree, hf_bpdu_msti_regional_root_mac, tvb,
- offset + MSTI_REGIONAL_ROOT + 2, 6,
- msti_regional_root_mac);
- proto_tree_add_text(msti_tree, tvb, offset + MSTI_REGIONAL_ROOT, 8,
- "MSTID %d, priority %d Root Identifier %s",
- msti_regional_root_mstid,
- msti_regional_root_priority,
- msti_regional_root_mac_str);
-
-
- proto_tree_add_item(msti_tree, hf_bpdu_msti_internal_root_path_cost, tvb,
- offset+MSTI_INTERNAL_ROOT_PATH_COST, 4, FALSE);
-
- msti_bridge_identifier_priority = tvb_get_guint8(tvb, offset+MSTI_BRIDGE_IDENTIFIER_PRIORITY) >> 4;
- msti_port_identifier_priority = tvb_get_guint8(tvb, offset+MSTI_PORT_IDENTIFIER_PRIORITY) >> 4;
-
- proto_tree_add_uint(msti_tree, hf_bpdu_msti_bridge_identifier_priority, tvb,
- offset+MSTI_BRIDGE_IDENTIFIER_PRIORITY, 1,
- msti_bridge_identifier_priority);
- proto_tree_add_uint(msti_tree, hf_bpdu_msti_port_identifier_priority, tvb,
- offset+MSTI_PORT_IDENTIFIER_PRIORITY, 1,
- msti_port_identifier_priority);
-
- proto_tree_add_item(msti_tree, hf_bpdu_msti_remaining_hops, tvb,
- offset + MSTI_REMAINING_HOPS, 1, FALSE);
-
- total_msti_length -= MSTI_MESSAGE_SIZE;
- offset += MSTI_MESSAGE_SIZE;
+ }
msti++;
}
}
@@ -763,6 +931,10 @@ proto_register_bpdu(void)
{ "Port identifier priority", "mstp.msti.port_priority",
FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL }},
+ { &hf_bpdu_msti_port_id,
+ { "Port identifier", "mstp.msti.port",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
{ &hf_bpdu_msti_remaining_hops,
{ "Remaining hops", "mstp.msti.remaining_hops",
FT_UINT8, BASE_DEC, NULL, 0x0,