+ ND_PRINT((ndo, "[|esis]"));
+}
+
+static void
+isis_print_mcid(netdissect_options *ndo,
+ const struct isis_spb_mcid *mcid)
+{
+ int i;
+
+ ND_TCHECK(*mcid);
+ ND_PRINT((ndo, "ID: %d, Name: ", mcid->format_id));
+
+ if (fn_printzp(ndo, mcid->name, 32, ndo->ndo_snapend))
+ goto trunc;
+
+ ND_PRINT((ndo, "\n\t Lvl: %d", EXTRACT_BE_U_2(mcid->revision_lvl)));
+
+ ND_PRINT((ndo, ", Digest: "));
+
+ for(i=0;i<16;i++)
+ ND_PRINT((ndo, "%.2x ", mcid->digest[i]));
+
+trunc:
+ ND_PRINT((ndo, "%s", tstr));
+}
+
+static int
+isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
+ const uint8_t *tptr, int len)
+{
+ int stlv_type, stlv_len;
+ const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
+ int i;
+
+ while (len > 2)
+ {
+ ND_TCHECK_2(tptr);
+ stlv_type = EXTRACT_U_1(tptr);
+ stlv_len = EXTRACT_U_1(tptr + 1);
+
+ /* first lets see if we know the subTLVs name*/
+ ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u",
+ tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type),
+ stlv_type,
+ stlv_len));
+
+ tptr = tptr + 2;
+ /*len -= TLV_TYPE_LEN_OFFSET;*/
+ len = len - 2;
+
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
+ switch (stlv_type)
+ {
+ case ISIS_SUBTLV_SPB_MCID:
+ {
+ if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
+ goto trunc;
+
+ subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
+
+ ND_PRINT((ndo, "\n\t MCID: "));
+ isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid));
+
+ /*tptr += SPB_MCID_MIN_LEN;
+ len -= SPB_MCID_MIN_LEN; */
+
+ ND_PRINT((ndo, "\n\t AUX-MCID: "));
+ isis_print_mcid(ndo, &(subtlv_spb_mcid->aux_mcid));
+
+ /*tptr += SPB_MCID_MIN_LEN;
+ len -= SPB_MCID_MIN_LEN; */
+ tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+
+ break;
+ }
+
+ case ISIS_SUBTLV_SPB_DIGEST:
+ {
+ if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
+ goto trunc;
+
+ ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
+ (EXTRACT_U_1(tptr) >> 5),
+ ((EXTRACT_U_1(tptr) >> 4) & 0x01),
+ ((EXTRACT_U_1(tptr) >> 2) & 0x03),
+ (EXTRACT_U_1(tptr) & 0x03)));
+
+ tptr++;
+
+ ND_PRINT((ndo, "\n\t Digest: "));
+
+ for(i=1;i<=8; i++)
+ {
+ ND_PRINT((ndo, "%08x ", EXTRACT_BE_U_4(tptr)));
+ if (i%4 == 0 && i != 8)
+ ND_PRINT((ndo, "\n\t "));
+ tptr = tptr + 4;
+ }
+
+ len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+
+ break;
+ }
+
+ case ISIS_SUBTLV_SPB_BVID:
+ {
+ while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
+ {
+ ND_PRINT((ndo, "\n\t ECT: %08x",
+ EXTRACT_BE_U_4(tptr)));
+
+ tptr = tptr+4;
+
+ ND_PRINT((ndo, " BVID: %d, U:%01x M:%01x ",
+ (EXTRACT_BE_U_2(tptr) >> 4) ,
+ (EXTRACT_BE_U_2(tptr) >> 3) & 0x01,
+ (EXTRACT_BE_U_2(tptr) >> 2) & 0x01));
+
+ tptr = tptr + 2;
+ len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ tptr += stlv_len;
+ len -= stlv_len;
+ }
+
+ return 0;
+
+ trunc:
+ ND_PRINT((ndo, "\n\t\t"));
+ ND_PRINT((ndo, "%s", tstr));
+ return(1);
+}
+
+static int
+isis_print_mt_capability_subtlv(netdissect_options *ndo,
+ const uint8_t *tptr, int len)
+{
+ int stlv_type, stlv_len, tmp;
+
+ while (len > 2)
+ {
+ ND_TCHECK_2(tptr);
+ stlv_type = EXTRACT_U_1(tptr);
+ stlv_len = EXTRACT_U_1(tptr + 1);
+ tptr = tptr + 2;
+ len = len - 2;
+
+ /* first lets see if we know the subTLVs name*/
+ ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u",
+ tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type),
+ stlv_type,
+ stlv_len));
+
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
+ switch (stlv_type)
+ {
+ case ISIS_SUBTLV_SPB_INSTANCE:
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
+ goto trunc;
+
+ ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_BE_U_4(tptr)));
+ tptr = tptr+4;
+ ND_PRINT((ndo, " %08x", EXTRACT_BE_U_4(tptr)));
+ tptr = tptr+4;
+ ND_PRINT((ndo, ", Path Cost: %08x", EXTRACT_BE_U_4(tptr)));
+ tptr = tptr+4;
+ ND_PRINT((ndo, ", Prio: %d", EXTRACT_BE_U_2(tptr)));
+ tptr = tptr + 2;
+ ND_PRINT((ndo, "\n\t RES: %d",
+ EXTRACT_BE_U_2(tptr) >> 5));
+ ND_PRINT((ndo, ", V: %d",
+ (EXTRACT_BE_U_2(tptr) >> 4) & 0x0001));
+ ND_PRINT((ndo, ", SPSource-ID: %d",
+ (EXTRACT_BE_U_4(tptr) & 0x000fffff)));
+ tptr = tptr+4;
+ ND_PRINT((ndo, ", No of Trees: %x", EXTRACT_U_1(tptr)));
+
+ tmp = EXTRACT_U_1(tptr);
+ tptr++;
+
+ len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+
+ while (tmp)
+ {
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
+ goto trunc;
+
+ ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
+ EXTRACT_U_1(tptr) >> 7,
+ (EXTRACT_U_1(tptr) >> 6) & 0x01,
+ (EXTRACT_U_1(tptr) >> 5) & 0x01,
+ (EXTRACT_U_1(tptr) & 0x1f)));
+
+ tptr++;
+
+ ND_PRINT((ndo, ", ECT: %08x", EXTRACT_BE_U_4(tptr)));
+
+ tptr = tptr + 4;
+
+ ND_PRINT((ndo, ", BVID: %d, SPVID: %d",
+ (EXTRACT_BE_U_3(tptr) >> 12) & 0x000fff,
+ EXTRACT_BE_U_3(tptr) & 0x000fff));
+
+ tptr = tptr + 3;
+ len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+ tmp--;
+ }
+
+ break;
+
+ case ISIS_SUBTLV_SPBM_SI:
+ if (stlv_len < 8)
+ goto trunc;
+
+ ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_BE_U_4(tptr)));
+ tptr = tptr+4;
+ ND_PRINT((ndo, "%04x", EXTRACT_BE_U_2(tptr)));
+ tptr = tptr+2;
+
+ ND_PRINT((ndo, ", RES: %d, VID: %d", EXTRACT_BE_U_2(tptr) >> 12,
+ (EXTRACT_BE_U_2(tptr)) & 0x0fff));
+
+ tptr = tptr+2;
+ len = len - 8;
+ stlv_len = stlv_len - 8;
+
+ while (stlv_len >= 4) {
+ ND_TCHECK_4(tptr);
+ ND_PRINT((ndo, "\n\t T: %d, R: %d, RES: %d, ISID: %d",
+ (EXTRACT_BE_U_4(tptr) >> 31),
+ (EXTRACT_BE_U_4(tptr) >> 30) & 0x01,
+ (EXTRACT_BE_U_4(tptr) >> 24) & 0x03f,
+ (EXTRACT_BE_U_4(tptr)) & 0x0ffffff));
+
+ tptr = tptr + 4;
+ len = len - 4;
+ stlv_len = stlv_len - 4;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ tptr += stlv_len;
+ len -= stlv_len;
+ }
+ return 0;
+
+ trunc:
+ ND_PRINT((ndo, "\n\t\t"));
+ ND_PRINT((ndo, "%s", tstr));
+ return(1);
+}