+/*
+ * this is the common IP-REACH subTLV decoder it is called
+ * from various EXTD-IP REACH TLVs (135,235,236,237)
+ */
+
+static int
+isis_print_ip_reach_subtlv (const u_char *tptr,int subt,int subl,const char *lf) {
+
+ switch(subt) {
+ case SUBTLV_IP_REACH_ADMIN_TAG32:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%s32-Bit Administrative tag: 0x%08x",
+ lf,
+ EXTRACT_32BITS(tptr));
+ break;
+ case SUBTLV_IP_REACH_ADMIN_TAG64:
+ if (!TTEST2(*tptr,8))
+ goto trunctlv;
+ printf("%s64-Bit Administrative tag: 0x%08x%08x",
+ lf,
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr+4));
+ break;
+ default:
+ printf("%sunknown subTLV, type %d, length %d",
+ lf,
+ subt,
+ subl);
+ if(!isis_print_unknown_data(tptr,"\n\t\t\t ",
+ subl))
+ return(0);
+ break;
+ }
+ return(1);
+
+trunctlv:
+ printf("%spacket exceeded snapshot",lf);
+ return(0);
+}
+
+/*
+ * this is the common IS-REACH subTLV decoder it is called
+ * from various EXTD-IS REACH TLVs (22,24,222)
+ */
+
+static int
+isis_print_is_reach_subtlv (const u_char *tptr,int subt,int subl,const char *lf) {
+
+ int i,j;
+ float bw; /* copy buffer for several subTLVs */
+
+ switch(subt) {
+ case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sAdministrative groups: 0x%08x",
+ lf,
+ EXTRACT_32BITS(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sLink Local Identifier: 0x%08x",
+ lf,
+ EXTRACT_32BITS(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sLink Remote Identifier: 0x%08x",
+ lf,
+ EXTRACT_32BITS(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ j = EXTRACT_32BITS(tptr);
+ memcpy (&bw, &j, 4);
+ printf("%sMaximum link bandwidth : %.3f Mbps",
+ lf,
+ bw*8/1000000 );
+ break;
+ case SUBTLV_EXT_IS_REACH_RESERVABLE_BW :
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ j = EXTRACT_32BITS(tptr);
+ memcpy (&bw, &j, 4);
+ printf("%sReservable link bandwidth: %.3f Mbps",
+ lf,
+ bw*8/1000000 );
+ break;
+ case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
+ printf("%sUnreserved bandwidth:",lf);
+ for (i = 0; i < 8; i++) {
+ if (!TTEST2(*(tptr+i*4),4))
+ goto trunctlv;
+ j = EXTRACT_32BITS(tptr);
+ memcpy (&bw, &j, 4);
+ printf("%s priority level %d: %.3f Mbps",
+ lf,
+ i,
+ bw*8/1000000 );
+ }
+ break;
+ case SUBTLV_EXT_IS_REACH_TE_METRIC:
+ if (!TTEST2(*tptr,3))
+ goto trunctlv;
+ printf("%sTraffic Engineering Metric: %d",
+ lf,
+ EXTRACT_24BITS(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sIPv4 interface address: %s",
+ lf,
+ ipaddr_string(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sIPv4 neighbor address: %s",
+ lf,
+ ipaddr_string(tptr));
+ break;
+ case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
+ if (!TTEST2(*tptr,2))
+ goto trunctlv;
+ i = 0;
+ j = (ISIS_8BIT_MASK(*tptr)); /* fetch the typecode and make sure
+ that no high-order LSBs are set */
+ printf("%sLink Protection Type: %s",
+ lf,
+ (j) ? "" : "none" );
+ /* scan through the bits until the typecode is zero */
+ while(!j) {
+ printf("%s", isis_gmpls_link_prot_values[i]);
+ j=j>>1;
+ if (j) /*any other bit set ?*/
+ printf(", ");
+ i++;
+ }
+ printf(", Priority %u", *(tptr+1));
+ break;
+ case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
+ printf("%sInterface Switching Capability",lf);
+
+ if (!TTEST2(*tptr,1))
+ goto trunctlv;
+ printf("%s Interface Switching Capability:%s",
+ lf,
+ tok2str(isis_gmpls_sw_cap_values, "Unknown", *(tptr)));
+
+ if (!TTEST2(*(tptr+1),1))
+ goto trunctlv;
+ printf(", LSP Encoding: %s",
+ tok2str(isis_gmpls_lsp_enc_values, "Unknown", *(tptr+1)));
+
+ if (!TTEST2(*(tptr+2),2)) /* skip 2 res. bytes */
+ goto trunctlv;
+
+ printf("%s Max LSP Bandwidth:",lf);
+ for (i = 0; i < 8; i++) {
+ if (!TTEST2(*(tptr+(i*4)+4),4))
+ goto trunctlv;
+ j = EXTRACT_32BITS(tptr);
+ memcpy (&bw, &j, 4);
+ printf("%s priority level %d: %.3f Mbps",
+ lf,
+ i,
+ bw*8/1000000 );
+ }
+ subl-=36;
+ /* there is some optional stuff left to decode but this is as of yet
+ not specified so just lets hexdump what is left */
+ if(subl>0){
+ if(!isis_print_unknown_data(tptr,"\n\t\t\t ",
+ subl-36))
+ return(0);
+ }
+ break;
+ case 250:
+ case 251:
+ case 252:
+ case 253:
+ case 254:
+ printf("%sReserved for cisco specific extensions, type %d, length %d",
+ lf,
+ subt,
+ subl);
+ break;
+ case 255:
+ printf("%sReserved for future expansion, type %d, length %d",
+ lf,
+ subt,
+ subl);
+ break;
+ default:
+ printf("%sunknown subTLV, type %d, length %d",
+ lf,
+ subt,
+ subl);
+ if(!isis_print_unknown_data(tptr,"\n\t\t\t ",
+ subl))
+ return(0);
+ break;
+ }
+ return(1);
+
+trunctlv:
+ printf("%spacket exceeded snapshot",lf);
+ return(0);
+}
+
+