diff options
-rw-r--r-- | epan/dissectors/packet-isis-clv.c | 10 | ||||
-rw-r--r-- | epan/dissectors/packet-isis-clv.h | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-isis-hello.c | 186 | ||||
-rw-r--r-- | epan/dissectors/packet-isis-lsp.c | 263 |
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, |