aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-isis-clv.c10
-rw-r--r--epan/dissectors/packet-isis-clv.h8
-rw-r--r--epan/dissectors/packet-isis-hello.c186
-rw-r--r--epan/dissectors/packet-isis-lsp.c263
4 files changed, 464 insertions, 3 deletions
diff --git a/epan/dissectors/packet-isis-clv.c b/epan/dissectors/packet-isis-clv.c
index 9d32631033..ad78e7f522 100644
--- a/epan/dissectors/packet-isis-clv.c
+++ b/epan/dissectors/packet-isis-clv.c
@@ -476,8 +476,14 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length)
proto_item_append_text(ti, ", ");
}
proto_item_append_text(ti, "%s (0x%02x)",
- val_to_str(tvb_get_guint8(tvb, offset), nlpid_vals,
- "Unknown"), tvb_get_guint8(tvb, offset));
+ /* NLPID_IEEE_8021AQ conflicts with NLPID_SNDCF.
+ * In this context, we want the former.
+ */
+ (tvb_get_guint8(tvb, offset) == NLPID_IEEE_8021AQ
+ ? "IEEE 802.1aq (SPB)"
+ : val_to_str(tvb_get_guint8(tvb, offset), nlpid_vals,
+ "Unknown")),
+ tvb_get_guint8(tvb, offset));
offset++;
first = FALSE;
}
diff --git a/epan/dissectors/packet-isis-clv.h b/epan/dissectors/packet-isis-clv.h
index f64ab99424..984409851d 100644
--- a/epan/dissectors/packet-isis-clv.h
+++ b/epan/dissectors/packet-isis-clv.h
@@ -59,6 +59,13 @@
#define ISIS_CLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */
#define ISIS_CLV_HOSTNAME 137 /* rfc2763 */
#define ISIS_CLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */
+#define ISIS_GRP_ADDR 142 /* draft-ieft-trill-isis-05*//* Our sub-packet dismantle structure for CLV's */
+#define ISIS_CLV_MT_PORT_CAP 143 /* MT port capability (draft-ietf-isis-layer2-11) */
+#define ISIS_CLV_MT_CAP 144 /* MT capability (draft-ietf-isis-ieee-aq-05)
+ * also: IEEE P802.1aq/D3.6,
+ * http://www.ietf.org/mail-archive/web/spb-isis/current/msg00007.html
+ * http://www.iana.org/assignments/isis-tlv-codepoints/isis-tlv-codepoints.xml#tlv-143,
+ */
#define ISIS_CLV_RESTART 211 /* draft-ietf-isis-restart-01 */
#define ISIS_CLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
#define ISIS_CLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
@@ -70,7 +77,6 @@
#define ISIS_CLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
#define ISIS_CLV_RT_CAPABLE 242 /* TRILL use of IS-IS RFC 6326 */
#define ISIS_CLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */
-#define ISIS_GRP_ADDR 142 /*draft-ieft-trill-isis-05*//* Our sub-packet dismantle structure for CLV's */
/*
* Our sub-packet dismantle structure for CLV's
diff --git a/epan/dissectors/packet-isis-hello.c b/epan/dissectors/packet-isis-hello.c
index 294787dd2a..76b4f3a2e2 100644
--- a/epan/dissectors/packet-isis-hello.c
+++ b/epan/dissectors/packet-isis-hello.c
@@ -79,6 +79,11 @@ static gint ett_isis_hello_clv_ptp_adj = -1;
static gint ett_isis_hello_clv_mt = -1;
static gint ett_isis_hello_clv_restart = -1;
static gint ett_isis_hello_clv_restart_flags = -1;
+static gint ett_isis_hello_clv_mt_port_cap = -1;
+static gint ett_isis_hello_clv_mt_port_cap_spb_mcid = -1;
+static gint ett_isis_hello_clv_mt_port_cap_spb_aux_mcid = -1;
+static gint ett_isis_hello_clv_mt_port_cap_spb_digest = -1;
+static gint ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples = -1;
static gint ett_isis_hello_clv_checksum = -1;
static const value_string isis_hello_circuit_type_vals[] = {
@@ -115,6 +120,8 @@ static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_hello_restart_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
+static void dissect_hello_mt_port_cap_clv(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int id_length, int length);
static const isis_clv_handle_t clv_l1_hello_opts[] = {
@@ -311,6 +318,12 @@ static const isis_clv_handle_t clv_ptp_hello_opts[] = {
dissect_hello_ip_authentication_clv
},
{
+ ISIS_CLV_MT_PORT_CAP,
+ "MT Port Capability",
+ &ett_isis_hello_clv_mt_port_cap,
+ dissect_hello_mt_port_cap_clv
+ },
+ {
ISIS_CLV_RESTART,
"Restart Option",
&ett_isis_hello_clv_restart,
@@ -342,6 +355,174 @@ static const isis_clv_handle_t clv_ptp_hello_opts[] = {
}
};
+static void
+dissect_hello_mt_port_cap_spb_mcid_clv(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ const int MCID_LEN = 51;
+ const int SUBLEN = 2 * MCID_LEN;
+
+ if (sublen != SUBLEN) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short SPB MCID TLV (%d vs %d)", sublen, SUBLEN);
+ return;
+ }
+ else {
+ proto_tree *subtree, *ti;
+ const guint8 *mcid = tvb_get_ptr(tvb, offset, MCID_LEN);
+ const guint8 *aux_mcid = tvb_get_ptr(tvb, offset + MCID_LEN, MCID_LEN);
+ int i;
+
+ ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+ "SPB MCID: Type: 0x%02x, Length: %d", subtype, sublen);
+ subtree = proto_item_add_subtree(ti, ett_isis_hello_clv_mt_port_cap_spb_mcid);
+
+ /* MCID: */
+ proto_tree_add_text( subtree, tvb, offset, MCID_LEN, "MCID:");
+ for (i = 0 ; i < 48 ; i+= 8, offset += 8) {
+ proto_tree_add_text( subtree, tvb, offset, 8,
+ " %02x %02x %02x %02x %02x %02x %02x %02x",
+ mcid[i+0], mcid[i+1], mcid[i+2], mcid[i+3],
+ mcid[i+4], mcid[i+5], mcid[i+6], mcid[i+7]);
+ }
+ proto_tree_add_text( subtree, tvb, offset, 3,
+ " %02x %02x %02x",
+ mcid[i+0], mcid[i+1], mcid[i+2]);
+ offset += 3;
+
+ /* Aux MCID: */
+ ti = proto_tree_add_text( subtree, tvb, offset, MCID_LEN, "Aux MCID:");
+ for (i = 0 ; i < 48 ; i+= 8, offset += 8) {
+ proto_tree_add_text( subtree, tvb, offset, 8,
+ " %02x %02x %02x %02x %02x %02x %02x %02x",
+ aux_mcid[i+0], aux_mcid[i+1], aux_mcid[i+2], aux_mcid[i+3],
+ aux_mcid[i+4], aux_mcid[i+5], aux_mcid[i+6], aux_mcid[i+7]);
+ }
+ proto_tree_add_text( subtree, tvb, offset, 3,
+ " %02x %02x %02x",
+ aux_mcid[i+0], aux_mcid[i+1], aux_mcid[i+2]);
+ offset += 3;
+ }
+}
+
+static void
+dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ const int DIGEST_LEN = 32;
+ const int SUBLEN = 1 + DIGEST_LEN;
+ if (sublen != SUBLEN) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short SPB Digest TLV (%d vs %d)", sublen, SUBLEN);
+ return;
+ }
+ else {
+ proto_tree *subtree, *ti;
+ const guint8 vad = tvb_get_guint8(tvb, offset);
+ const guint8 *digest = tvb_get_ptr(tvb, offset + 1, DIGEST_LEN);
+ int i;
+
+ ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+ "SPB Digest: Type: 0x%02x, Length: %d", subtype, sublen);
+ subtree = proto_item_add_subtree(ti, ett_isis_hello_clv_mt_port_cap_spb_digest);
+
+ proto_tree_add_text( subtree, tvb, offset, 1,
+ "V: %d, A: %d, D: %d",
+ (vad >> 4) & 0x1,
+ (vad >> 2) & 0x3,
+ (vad >> 0) & 0x3);
+ ++offset;
+
+ /* Digest: */
+ proto_tree_add_text( tree, tvb, offset, DIGEST_LEN, "Digest:");
+ for (i = 0 ; i < DIGEST_LEN ; i+= 8, offset += 8) {
+ proto_tree_add_text( subtree, tvb, offset, 8,
+ " %02x %02x %02x %02x %02x %02x %02x %02x",
+ digest[i+0], digest[i+1], digest[i+2], digest[i+3],
+ digest[i+4], digest[i+5], digest[i+6], digest[i+7]);
+ }
+ }
+}
+
+static void
+dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ proto_tree *subtree, *ti;
+ int subofs = offset;
+
+ ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+ "SPB Base Vlan Identifiers: Type: 0x%02x, Length: %d", subtype, sublen);
+ subtree = proto_item_add_subtree(ti, ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples);
+
+ while (sublen > 0) {
+ if (sublen < 6) {
+ isis_dissect_unknown( tvb, subtree, offset,
+ "Short SPB BVID header entry (%d vs %d)", sublen, 6);
+ return;
+ }
+ else {
+ const guint8 *ect_tlv = tvb_get_ptr(tvb, subofs, 6);
+ guint16 word = (ect_tlv[4] << 8) | ect_tlv[5];
+ guint16 bvid = (word >> 4) & 0xfff;
+ int u_bit = (ect_tlv[5] & 8) ? 1 : 0;
+ int m_bit = (ect_tlv[5] & 4) ? 1 : 0;
+ proto_tree_add_text( subtree, tvb, subofs, 6,
+ "ECT: %02x-%02x-%02x-%02x, BVID: 0x%03x (%d),%s U: %d, M: %d",
+ ect_tlv[0], ect_tlv[1], ect_tlv[2], ect_tlv[3],
+ bvid, bvid,
+ ( bvid < 10 ? " "
+ : bvid < 100 ? " "
+ : bvid < 1000 ? " "
+ : ""),
+ u_bit,
+ m_bit);
+ }
+ sublen -= 6;
+ subofs += 6;
+ }
+}
+
+static void
+dissect_hello_mt_port_cap_clv(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int id_length _U_, int length)
+{
+ if (length >= 2) {
+ /* mtid */
+ guint16 mtid = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text( tree, tvb, offset, 2,
+ "MTID: 0x%03x",
+ (mtid & 0xfff));
+ length -= 2;
+ offset += 2;
+ while (length >= 2) {
+ guint8 subtype = tvb_get_guint8(tvb, offset);
+ guint8 subtlvlen = tvb_get_guint8(tvb, offset+1);
+ length -= 2;
+ offset += 2;
+ if (subtlvlen > length) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short type 0x%02x TLV (%d vs %d)", subtype, subtlvlen, length);
+ return;
+ }
+ if (subtype == 0x04) { /* SPB MCID */
+ dissect_hello_mt_port_cap_spb_mcid_clv(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else if (subtype == 0x05) { /* SPB Digest */
+ dissect_hello_mt_port_cap_spb_digest_clv(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else if (subtype == 0x06) { /* SPB BVID Tuples */
+ dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen);
+ }
+ length -= subtlvlen;
+ offset += subtlvlen;
+ }
+ }
+}
/*
* The Restart CLV is documented in RFC 3847 (Restart Signaling for
@@ -1034,6 +1215,11 @@ isis_register_hello(int proto_isis) {
&ett_isis_hello_clv_mt,
&ett_isis_hello_clv_restart,
&ett_isis_hello_clv_restart_flags,
+ &ett_isis_hello_clv_mt_port_cap,
+ &ett_isis_hello_clv_mt_port_cap_spb_mcid,
+ &ett_isis_hello_clv_mt_port_cap_spb_aux_mcid,
+ &ett_isis_hello_clv_mt_port_cap_spb_digest,
+ &ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples,
&ett_isis_hello_clv_checksum
};
diff --git a/epan/dissectors/packet-isis-lsp.c b/epan/dissectors/packet-isis-lsp.c
index 6dc70c1053..6b4117940e 100644
--- a/epan/dissectors/packet-isis-lsp.c
+++ b/epan/dissectors/packet-isis-lsp.c
@@ -102,6 +102,9 @@ static gint ett_isis_lsp_clv_authentication = -1;
static gint ett_isis_lsp_clv_ip_authentication = -1;
static gint ett_isis_lsp_clv_ipv4_int_addr = -1;
static gint ett_isis_lsp_clv_ipv6_int_addr = -1; /* CLV 232 */
+static gint ett_isis_lsp_clv_mt_cap = -1;
+static gint ett_isis_lsp_clv_mt_cap_spb_instance = -1;
+static gint ett_isis_lsp_clv_mt_cap_spbm_service_identifier = -1;
static gint ett_isis_lsp_clv_ip_reachability = -1;
static gint ett_isis_lsp_clv_ip_reach_subclv = -1;
static gint ett_isis_lsp_clv_ext_ip_reachability = -1; /* CLV 135 */
@@ -143,6 +146,8 @@ static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
+static void dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int id_length, int length);
static void dissect_lsp_authentication_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_lsp_ip_authentication_clv(tvbuff_t *tvb,
@@ -258,6 +263,12 @@ static const isis_clv_handle_t clv_l1_lsp_opts[] = {
dissect_lsp_ipv6_int_addr_clv
},
{
+ ISIS_CLV_MT_CAP,
+ "MT-Capability",
+ &ett_isis_lsp_clv_mt_cap,
+ dissect_isis_lsp_clv_mt_cap
+ },
+ {
ISIS_CLV_AUTHENTICATION,
"Authentication",
&ett_isis_lsp_clv_authentication,
@@ -400,6 +411,12 @@ static const isis_clv_handle_t clv_l2_lsp_opts[] = {
dissect_lsp_ipv6_int_addr_clv
},
{
+ ISIS_CLV_MT_CAP,
+ "MT-Capability",
+ &ett_isis_lsp_clv_mt_cap,
+ dissect_isis_lsp_clv_mt_cap
+ },
+ {
ISIS_CLV_AUTHENTICATION,
"Authentication",
&ett_isis_lsp_clv_authentication,
@@ -1533,6 +1550,249 @@ dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
hf_isis_lsp_clv_ipv6_int_addr );
}
+static void
+dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ const int CIST_ROOT_ID_LEN = 8; /* CIST Root Identifier */
+ const int CIST_EXT_ROOT_PATH_COST_LEN = 4; /* CIST External Root Path Cost */
+ const int BRIDGE_PRI_LEN = 2; /* Bridge Priority */
+ const int V_SPSOURCEID_LEN = 4; /* v | SPSourceID */
+ const int NUM_TREES_LEN = 1; /* num of trees */
+
+ const int CIST_ROOT_ID_OFFSET = 0;
+ const int CIST_EXT_ROOT_PATH_COST_OFFSET = CIST_ROOT_ID_OFFSET + CIST_ROOT_ID_LEN;
+ const int BRIDGE_PRI_OFFSET = CIST_EXT_ROOT_PATH_COST_OFFSET + CIST_EXT_ROOT_PATH_COST_LEN;
+ const int V_SPSOURCEID_OFFSET = BRIDGE_PRI_OFFSET + BRIDGE_PRI_LEN;
+ const int NUM_TREES_OFFSET = V_SPSOURCEID_OFFSET + V_SPSOURCEID_LEN;
+ const int FIXED_LEN = NUM_TREES_OFFSET + NUM_TREES_LEN;
+ const int VLAN_ID_TUPLE_LEN = 8;
+
+ if (sublen < FIXED_LEN) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short SPB Digest subTLV (%d vs %d)", sublen, FIXED_LEN);
+ return;
+ }
+ else {
+ proto_tree *subtree, *ti;
+ int subofs = offset;
+ const guint8 *cist_root_identifier = tvb_get_ptr (tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN);
+ const guint32 cist_root_path_cost = tvb_get_ntohl (tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET);
+ const guint16 bridge_priority = tvb_get_ntohs (tvb, subofs + BRIDGE_PRI_OFFSET);
+ const guint32 v_spsourceid = tvb_get_ntohl (tvb, subofs + V_SPSOURCEID_OFFSET);
+ guint8 num_trees = tvb_get_guint8(tvb, subofs + NUM_TREES_OFFSET);
+
+ /*************************/
+ ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+ "SPB Instance: Type: 0x%02x, Length: %d", subtype, sublen);
+ subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spb_instance);
+
+ /*************************/
+ proto_tree_add_text( subtree, tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN,
+ "CIST Root Identifier: %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x",
+ cist_root_identifier[0],
+ cist_root_identifier[1],
+ cist_root_identifier[2],
+ cist_root_identifier[3],
+ cist_root_identifier[4],
+ cist_root_identifier[5],
+ cist_root_identifier[6],
+ cist_root_identifier[7]);
+ proto_tree_add_text( subtree, tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET, CIST_EXT_ROOT_PATH_COST_LEN,
+ "CIST External Root Path Cost: 0x%08x (%u)",
+ cist_root_path_cost,
+ cist_root_path_cost);
+ proto_tree_add_text( subtree, tvb, subofs + BRIDGE_PRI_OFFSET, BRIDGE_PRI_LEN,
+ "Bridge Priority: 0x%04x (%u)",
+ bridge_priority,
+ bridge_priority);
+ proto_tree_add_text( subtree, tvb, subofs + V_SPSOURCEID_OFFSET, V_SPSOURCEID_LEN,
+ "V: %u, SPSourceId: 0x%05x (%u)",
+ (v_spsourceid & (1 << 20)) ? 1 : 0,
+ v_spsourceid & 0xfffff,
+ v_spsourceid & 0xfffff);
+ proto_tree_add_text( subtree, tvb, subofs + NUM_TREES_OFFSET, NUM_TREES_LEN,
+ "Number of Trees: 0x%02x (%u)%s",
+ num_trees,
+ num_trees,
+ num_trees ? "" : " Invalid subTLV: zero trees");
+
+ subofs += FIXED_LEN;
+ sublen -= FIXED_LEN;
+
+ /*************************/
+ if (sublen != (num_trees * VLAN_ID_TUPLE_LEN)) {
+ proto_tree_add_text( subtree, tvb, subofs, 0,
+ "SubTLV length doesn't match number of trees");
+ return;
+ }
+ while (sublen > 0 && num_trees > 0) {
+ if (sublen < VLAN_ID_TUPLE_LEN) {
+ isis_dissect_unknown( tvb, subtree, offset,
+ "Short VLAN_ID entry (%d vs %d)", sublen, VLAN_ID_TUPLE_LEN);
+ return;
+ }
+ else {
+ const guint8 flags = tvb_get_guint8(tvb, subofs);
+ const guint8 *ect_id = tvb_get_ptr(tvb, subofs + 1, 4);
+ const guint8 *bvid_spvid = tvb_get_ptr(tvb, subofs + 1 + 4, 3);
+ const guint16 bvid = (0xff0 & (((guint16)bvid_spvid[0]) << 4)) | (0x0f & (bvid_spvid[1] >> 4));
+ const guint16 spvid = (0xf00 & (((guint16)bvid_spvid[1]) << 8)) | (0xff & (bvid_spvid[2]));
+ proto_tree_add_text( subtree, tvb, subofs, VLAN_ID_TUPLE_LEN,
+ " U: %u, M: %u, A: %u, ECT: %02x-%02x-%02x-%02x, BVID: 0x%03x (%d),%s SPVID: 0x%03x (%d)",
+ (flags >> 7) & 1,
+ (flags >> 6) & 1,
+ (flags >> 5) & 1,
+ ect_id[0], ect_id[1], ect_id[2], ect_id[3],
+ bvid, bvid,
+ ( bvid < 10 ? " "
+ : bvid < 100 ? " "
+ : bvid < 1000 ? " "
+ : ""),
+ spvid, spvid);
+ subofs += VLAN_ID_TUPLE_LEN;
+ sublen -= VLAN_ID_TUPLE_LEN;
+ --num_trees;
+ }
+ }
+ if (num_trees) {
+ isis_dissect_unknown( tvb, subtree, offset,
+ "Short subTLV (%d vs %d)", sublen, num_trees * VLAN_ID_TUPLE_LEN);
+ return;
+ }
+ }
+}
+static void
+dissect_isis_lsp_clv_mt_cap_spb_oalg(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ isis_dissect_unknown( tvb, tree, offset,
+ "MT-Cap SPB Opaque Algorithm: Type: 0x%02x, Length: %d", subtype, sublen);
+}
+static void
+dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t *tvb,
+ proto_tree *tree, int offset, int subtype, int sublen)
+{
+ const int BMAC_LEN = 6; /* B-MAC Address */
+ const int BVID_LEN = 2; /* Base-VID */
+
+ const int BMAC_OFFSET = 0;
+ const int BVID_OFFSET = BMAC_OFFSET + BMAC_LEN;
+ const int FIXED_LEN = BVID_OFFSET + BVID_LEN;
+
+ const int ISID_LEN = 4;
+
+ if (sublen < FIXED_LEN) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short SPBM Service Identifier and Unicast Address subTLV (%d vs %d)", sublen, FIXED_LEN);
+ return;
+ }
+ else {
+ proto_tree *subtree, *ti;
+ int subofs = offset;
+ const guint8 *bmac = tvb_get_ptr (tvb, subofs + BMAC_OFFSET, BMAC_LEN);
+ const guint16 bvid = tvb_get_ntohs(tvb, subofs + BVID_OFFSET);
+
+ /*************************/
+ ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+ "SPB Service ID and Unicast Address: Type: 0x%02x, Length: %d", subtype, sublen);
+ subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spbm_service_identifier);
+
+ /*************************/
+ proto_tree_add_text( subtree, tvb, subofs + BMAC_OFFSET, BMAC_LEN,
+ "B-MAC: %02x-%02x-%02x-%02x-%02x-%02x",
+ bmac[0],
+ bmac[1],
+ bmac[2],
+ bmac[3],
+ bmac[4],
+ bmac[5]);
+ proto_tree_add_text( subtree, tvb, subofs + BVID_OFFSET, BVID_LEN,
+ "Base-VID: 0x%03x (%u)",
+ bvid, bvid);
+
+ subofs += FIXED_LEN;
+ sublen -= FIXED_LEN;
+
+ /*************************/
+ while (sublen > 0) {
+ if (sublen < ISID_LEN) {
+ isis_dissect_unknown( tvb, subtree, offset,
+ "Short ISID entry (%d vs %d)", sublen, ISID_LEN);
+ return;
+ }
+ else {
+ const guint32 isid = tvb_get_ntohl(tvb, subofs);
+ proto_tree_add_text( subtree, tvb, subofs, ISID_LEN,
+ " T: %u, R: %u, ISID: 0x%06x (%d)",
+ (isid >> 31) & 1,
+ (isid >> 30) & 1,
+ isid & 0x00ffffff,
+ isid & 0x00ffffff);
+ subofs += ISID_LEN;
+ sublen -= ISID_LEN;
+ }
+ }
+ }
+}
+/*
+ * Name: dissect_lsp_clv_mt_cap()
+ *
+ * Description: Decode an ISIS MT-CAP CLV - code 144.
+ *
+ * Input:
+ * tvbuff_t * : tvbuffer for packet data
+ * proto_tree * : proto tree to build on (may be null)
+ * int : current offset into packet data
+ * int : length of IDs in packet.
+ * int : length of this clv
+ *
+ * Output:
+ * void, will modify proto_tree if not null.
+ */
+static void
+dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, proto_tree *tree, int offset,
+ int id_length _U_, int length)
+{
+ if (length >= 2) {
+ /* mtid */
+ guint16 mtid = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text( tree, tvb, offset, 2,
+ "MTID: 0x%03x, Overload: %d",
+ (mtid & 0xfff),
+ (mtid & 0x8000) ? 1 : 0);
+ length -= 2;
+ offset += 2;
+ while (length >= 2) {
+ guint8 subtype = tvb_get_guint8(tvb, offset);
+ guint8 subtlvlen = tvb_get_guint8(tvb, offset+1);
+ length -= 2;
+ offset += 2;
+ if (subtlvlen > length) {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Short type 0x%02x TLV (%d vs %d)", subtype, subtlvlen, length);
+ return;
+ }
+ if (subtype == 0x01) { /* SPB Instance */
+ dissect_isis_lsp_clv_mt_cap_spb_instance(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else if (subtype == 0x02) { /* OALG */
+ dissect_isis_lsp_clv_mt_cap_spb_oalg(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else if (subtype == 0x03) { /* SPBM Service Identifier */
+ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvb, tree, offset, subtype, subtlvlen);
+ }
+ else {
+ isis_dissect_unknown( tvb, tree, offset,
+ "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen);
+ }
+ length -= subtlvlen;
+ offset += subtlvlen;
+ }
+
+ }
+}
+
/*
* Name: dissect_lsp_authentication_clv()
*
@@ -2532,6 +2792,9 @@ isis_register_lsp(int proto_isis) {
&ett_isis_lsp_clv_hostname,
&ett_isis_lsp_clv_ipv4_int_addr,
&ett_isis_lsp_clv_ipv6_int_addr, /* CLV 232 */
+ &ett_isis_lsp_clv_mt_cap,
+ &ett_isis_lsp_clv_mt_cap_spb_instance,
+ &ett_isis_lsp_clv_mt_cap_spbm_service_identifier,
&ett_isis_lsp_clv_te_router_id,
&ett_isis_lsp_clv_ip_reachability,
&ett_isis_lsp_clv_ip_reach_subclv,