hi all,
much of the subTLVs of the IS-reach and IP-reach decoders
can be re-used in several parts of the code;
- the subTLV decoder can now be called from various places
- plus added support for checking the checksum in the LSP PDU
- plus misc cleanups [use tok2str() for displaying
strings rather than switch/case chains]
/hannes
Index: print-isoclns.c
===================================================================
RCS file: /tcpdump/master/tcpdump/print-isoclns.c,v
retrieving revision 1.41
diff -u -r1.41 print-isoclns.c
--- print-isoclns.c 2002/03/20 07:00:03 1.41
+++ print-isoclns.c 2002/03/23 20:36:35
@@ -105,7 +105,7 @@
#define TLV_MT_IS_REACH 222
#define TLV_MT_SUPPORTED 229
#define TLV_IP6ADDR 232
-#define TLV_MT_REACH 235
+#define TLV_MT_IP_REACH 235
#define TLV_IP6_REACH 236
#define TLV_PTP_ADJ 240
@@ -121,6 +121,8 @@
#define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
#define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
+#define SUBTLV_EXT_IP_REACH_ADMIN_TAG 1
+
#define SUBTLV_AUTH_SIMPLE 1
#define SUBTLV_AUTH_MD5 54
#define SUBTLV_AUTH_MD5_LEN 16
@@ -194,6 +196,15 @@
{ 0, "unknown" }
};
+static struct tok isis_mt_values[] = {
+ { 0, "IPv4 unicast"},
+ { 1, "In-Band Management"},
+ { 2, "IPv6 unicast"},
+ { 3, "Multicast"},
+ { 4095, "Development, Experimental or Proprietary"},
+ { 0, "Reserved for IETF Consensus" }
+};
+
#define ISIS_LSP_TYPE_UNUSED0 0
#define ISIS_LSP_TYPE_LEVEL_1 1
#define ISIS_LSP_TYPE_UNUSED2 2
@@ -624,7 +635,7 @@
* this is a generic routine for printing unknown data;
* as it is called from various places (TLV and subTLV parsing routines)
* we pass on the linefeed plus indentation string to
- * get a proper output
+ * get a proper output - returns 0 on error
*/
static int
@@ -644,11 +655,11 @@
printf("%s0x%04x: ",lf,i);
}
}
- return(0); /* everything is ok */
+ return(1); /* everything is ok */
trunctlv:
printf("%spacket exceeded snapshot",lf);
- return(1);
+ return(0);
}
@@ -697,19 +708,13 @@
* lets dump the mask, otherwise print the prefix_len
*/
if (prefix_len == 34)
- printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u",
- (tlv_ip_reach->prefix)[0],
- (tlv_ip_reach->prefix)[1],
- (tlv_ip_reach->prefix)[2],
- (tlv_ip_reach->prefix)[3],
- (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1],
- (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]);
+ printf("\n\t\t\tIPv4 prefix: %s mask %s",
+ ipaddr_string((tlv_ip_reach->prefix)),
+ ipaddr_string((tlv_ip_reach->mask)));
else
- printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u",
- (tlv_ip_reach->prefix)[0],
- (tlv_ip_reach->prefix)[1],
- (tlv_ip_reach->prefix)[2],
- (tlv_ip_reach->prefix)[3], prefix_len);
+ printf("\n\t\t\tIPv4 prefix: %s/%u",
+ ipaddr_string((tlv_ip_reach->prefix)),
+ prefix_len);
printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default),
@@ -738,6 +743,214 @@
}
/*
+ * this is the common IP-REACH subTLV decoder it is called
+ * from various EXTD-IP REACH TLVs (135,236)
+ */
+
+static int
+isis_print_ip_reach_subtlv (const u_char *tptr,int subt,int subl,const u_char *lf) {
+
+ switch(subt) {
+ case SUBTLV_EXT_IP_REACH_ADMIN_TAG:
+ if (!TTEST2(*tptr,4))
+ goto trunctlv;
+ printf("%sAdministrative tag: 0x%08x",
+ lf,
+ EXTRACT_32BITS(tptr));
+ 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,222)
+ */
+
+static int
+isis_print_is_reach_subtlv (const u_char *tptr,int subt,int subl,const u_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);
+}
+
+
+/*
* isis_print
* Decode IS-IS packets. Return 0 on error.
*/
@@ -765,7 +978,6 @@
u_char prefix6[16]; /* copy buffer for ipv6 prefixes */
#endif
u_char off[2];
- float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV
*/
packet_len=length;
optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum
TLV */
@@ -961,9 +1173,14 @@
TCHECK(*header_lsp);
printf("\n\t\t lsp-id: ");
isis_print_lspid(header_lsp->lsp_id);
- printf(", sequence number:
0x%08x",EXTRACT_32BITS(header_lsp->sequence_number));
+ printf(", seq: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number));
printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime));
- printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum));
+ printf("\n\t\t chksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum));
+ /* verify the checksum */
+ if (osi_cksum(optr, length, off))
+ printf(" (incorrect)");
+ else
+ printf(" (correct)");
printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit
set, " : "");
@@ -1033,9 +1250,9 @@
default:
printf(", PDU type (0x%02x) not supported", pdu_type);
- if(isis_print_unknown_data(pptr,"\n\t\t ",length))
- return(1);
- return (1);
+ if(!isis_print_unknown_data(pptr,"\n\t\t ",length))
+ return(0);
+ return (0);
}
/*
@@ -1106,32 +1323,11 @@
printf("\n\t\t\t");
if (!TTEST2(*tptr, 2))
goto trunctlv;
- switch(EXTRACT_16BITS(tptr)&0x0fff) {
+
+ tok2str(isis_mt_values,
+ "Reserved for IETF Consensus",
+ (EXTRACT_16BITS(tptr))&0x0fff);
- case 0:
- printf("IPv4 unicast");
- break;
-
- case 1:
- printf("In-Band Management");
- break;
-
- case 2:
- printf("IPv6 unicast");
- break;
-
- case 3:
- printf("Multicast");
- break;
-
- case 4095:
- printf("Development, Experimental or Proprietary");
- break;
-
- default:
- printf("Reserved for IETF Consensus");
- break;
- }
printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff);
tptr+=2;
printf("\n\t\t\t IS Neighbor: ");
@@ -1146,15 +1342,21 @@
goto trunctlv;
tslen=*(tptr++);
printf(", %ssub-TLVs present",tslen ? "" : "no ");
- /* so far no decoding of subTLVs is supported
- * so lets print out a hexdump of the unknown subTLV data
- */
- if(!tslen){
- if(isis_print_unknown_data(tptr,"\n\t\t\t ",tslen))
- return(1);
- }
- tptr+=tslen;
- tmp-=(13+tslen);
+ if (tslen) {
+ printf(" (%u)",tslen);
+ while (tslen>0) {
+ if (!TTEST2(*tptr,2))
+ goto trunctlv;
+ subt=*(tptr++);
+ subl=*(tptr++);
+ if(!isis_print_is_reach_subtlv(tptr,subt,subl,"\n\t\t\t "))
+ return(0);
+ tptr+=subl;
+ tslen-=(subl+2);
+ tmp-=(subl+2);
+ }
+ }
+ tmp-=(SYSTEM_ID_LEN+7);
}
break;
@@ -1163,16 +1365,18 @@
tptr=pptr;
tmp=len;
while (tmp>0) {
- if (!TTEST2(*tptr, 7))
+ if (!TTEST2(*tptr, SYSTEM_ID_LEN+1))
goto trunctlv;
printf("\n\t\t\tIS Neighbor: ");
if (!isis_print_nodeid(tptr))
return (1);
tptr+=(SYSTEM_ID_LEN+1);
+
if (!TTEST2(*tptr, 3))
goto trunctlv;
printf(", Metric: %d",EXTRACT_24BITS(tptr));
tptr+=3;
+
if (!TTEST2(*tptr, 1))
goto trunctlv;
tslen=*(tptr++);
@@ -1182,142 +1386,20 @@
while (tslen>0) {
if (!TTEST2(*tptr,2))
goto trunctlv;
- printf("\n\t\t\t ");
subt=*(tptr++);
subl=*(tptr++);
- switch(subt) {
- case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
- if (!TTEST2(*tptr,4))
- goto trunctlv;
- printf("Administrative groups: 0x%08x",
EXTRACT_32BITS(tptr));
- break;
- case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID:
- if (!TTEST2(*tptr,4))
- goto trunctlv;
- printf("Link Local Identifier: 0x%08x",
EXTRACT_32BITS(tptr));
- break;
- case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
- if (!TTEST2(*tptr,4))
- goto trunctlv;
- printf("Link Remote Identifier: 0x%08x",
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("Maximum link bandwidth : %.3f Mbps",
- 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("Reservable link bandwidth: %.3f Mbps",
- bw*8/1000000 );
- break;
- case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
- printf("Unreserved bandwidth:");
- for (i = 0; i < 8; i++) {
- if (!TTEST2(*(tptr+i*4),4))
- goto trunctlv;
- j = EXTRACT_32BITS(tptr);
- memcpy (&bw, &j, 4);
- printf("\n\t\t\t priority level %d: %.3f Mbps",
- i, bw*8/1000000 );
- }
- break;
- case SUBTLV_EXT_IS_REACH_TE_METRIC:
- if (!TTEST2(*tptr,3))
- goto trunctlv;
- printf("Traffic Engineering Metric: %d",
EXTRACT_24BITS(tptr));
- break;
- case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
- if (!TTEST2(*tptr,4))
- goto trunctlv;
- printf("IPv4 interface address: %s", ipaddr_string(tptr));
- break;
- case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
- if (!TTEST2(*tptr,4))
- goto trunctlv;
- printf("IPv4 neighbor address: %s", 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("Link Protection Type: %s",(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("Interface Switching Capability");
-
- if (!TTEST2(*tptr,1))
- goto trunctlv;
- printf("\n\t\t\t Interface Switching Capability:%s",
- 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("\n\t\t\t Max LSP Bandwidth:");
- for (i = 0; i < 8; i++) {
- if (!TTEST2(*(tptr+(i*4)+4),4))
- goto trunctlv;
- j = EXTRACT_32BITS(tptr);
- memcpy (&bw, &j, 4);
- printf("\n\t\t\t priority level %d: %.3f Mbps",
- i, bw*8/1000000 );
- }
- /* 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){
- if(isis_print_unknown_data(tptr,"\n\t\t\t ",subl-36))
- return(1);
- }
- break;
- case 250:
- case 251:
- case 252:
- case 253:
- case 254:
- printf("Reserved for cisco specific extensions, type %d,
length %d", subt, subl);
- break;
- case 255:
- printf("Reserved for future expansion, type %d, length
%d", subt, subl);
- break;
- default:
- printf("unknown subTLV, type %d, length %d", subt, subl);
- if(isis_print_unknown_data(tptr,"\n\t\t\t ",subl))
- return(1);
- break;
- }
- tptr+=subl;
- tslen-=(subl+2);
+ if(!isis_print_is_reach_subtlv(tptr,subt,subl,"\n\t\t\t "))
+ return(0);
+ tptr+=subl;
+ tslen-=(subl+2);
+ tmp-=(subl+2);
}
}
- tmp-=(11+tslen);
+ tmp-=(SYSTEM_ID_LEN+5);
}
break;
case TLV_IS_REACH:
printf("IS Reachability (%u)",len);
-
tptr=pptr;
if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the
virtual flag */
@@ -1383,33 +1465,101 @@
return (1);
break;
+ case TLV_MT_IP_REACH:
+ printf("Multi-Topology IP reachability (%u)",len);
+ tmp=len;
+ tptr=pptr;
+
+ while (tmp>0) {
+ printf("\n\t\t\t");
+ if (!TTEST2(*tptr, 2))
+ goto trunctlv;
+
+ tok2str(isis_mt_values,
+ "Reserved for IETF Consensus",
+ (EXTRACT_16BITS(tptr))&0x0fff);
+
+ printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff);
+ tptr+=2;
+
+ memset (prefix, 0, 4);
+ if (!TTEST2(*tptr, 4))
+ return (1);
+ metric = EXTRACT_32BITS(tptr);
+ tptr+=4;
+
+ if (!TTEST2(*tptr, 1)) /* fetch status byte */
+ return (1);
+ j=*(tptr);
+ bit_length = (*(tptr)++&0x3f);
+ byte_length = (bit_length + 7) / 8; /* prefix has variable length
+encoding */
+
+ if (!TTEST2(*tptr, byte_length))
+ return (1);
+ memcpy(prefix,tptr,byte_length);
+ tptr+=byte_length;
+ printf("\n\t\t\tIPv4 prefix: %s/%d",
+ ipaddr_string(prefix),
+ bit_length);
+
+ printf("\n\t\t\t Metric: %u, Distribution: %s",
+ metric,
+ ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up");
+
+ printf(", %ssub-TLVs present",
+ ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
+
+ if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
+ /* assume that one prefix can hold more
+ than one subTLV - therefore the first byte must reflect
+ the aggregate bytecount of the subTLVs for this prefix
+ */
+ if (!TTEST2(*tptr, 1))
+ return (1);
+ tslen=*(tptr++);
+ tmp--;
+ printf(" (%u)",tslen); /* print out subTLV length */
+
+ while (tslen>0) {
+ if (!TTEST2(*tptr,2))
+ goto trunctlv;
+ subt=*(tptr++);
+ subl=*(tptr++);
+ if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t\t "))
+ return(0);
+ tptr+=subl;
+ tslen-=(subl+2);
+ tmp-=(subl+2);
+ }
+ }
+ tmp-=(7+byte_length);
+ }
+ break;
+
case TLV_EXT_IP_REACH:
printf("Extended IP reachability (%u)",len);
- i=len;
+ tmp=len;
tptr=pptr;
- while (i>0) {
+ while (tmp>0) {
memset (prefix, 0, 4);
if (!TTEST2(*tptr, 4))
return (1);
metric = EXTRACT_32BITS(tptr);
tptr+=4;
- if (!TTEST2(*tptr, 1))
+ if (!TTEST2(*tptr, 1)) /* fetch status byte */
return (1);
j=*(tptr);
bit_length = (*(tptr)++&0x3f);
- byte_length = (bit_length + 7) / 8;
+ byte_length = (bit_length + 7) / 8; /* prefix has variable length
+encoding */
+
if (!TTEST2(*tptr, byte_length))
return (1);
-
memcpy(prefix,tptr,byte_length);
-
- printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d",
- prefix[0],
- prefix[1],
- prefix[2],
- prefix[3],
+ tptr+=byte_length;
+ printf("\n\t\t\tIPv4 prefix: %s/%d",
+ ipaddr_string(prefix),
bit_length);
printf("\n\t\t\t Metric: %u, Distribution: %s",
@@ -1420,23 +1570,29 @@
ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
+ /* assume that one prefix can hold more
+ than one subTLV - therefore the first byte must reflect
+ the aggregate bytecount of the subTLVs for this prefix
+ */
if (!TTEST2(*tptr, 1))
- return (1);
- printf(" (%u)",*tptr); /* print out subTLV length */
+ return (1);
+ tslen=*(tptr++);
+ tmp--;
+ printf(" (%u)",tslen); /* print out subTLV length */
- /* so far no decoding of subTLVs is supported
- * so lets print out a hexdump of the unknown subTLV data
- */
- if(isis_print_unknown_data(tptr,"\n\t\t\t ",*tptr))
- return(1);
-
- i-=*tptr;
- tptr = tptr + *tptr;
- tptr++;
+ while (tslen>0) {
+ if (!TTEST2(*tptr,2))
+ goto trunctlv;
+ subt=*(tptr++);
+ subl=*(tptr++);
+ if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t\t "))
+ return(0);
+ tptr+=subl;
+ tslen-=(subl+2);
+ tmp-=(subl+2);
+ }
}
-
- i-=(5+byte_length);
- tptr+=byte_length;
+ tmp-=(5+byte_length);
}
break;
@@ -1444,10 +1600,10 @@
case TLV_IP6_REACH:
printf("IP6 reachability (%u)",len);
- i=len;
+ tmp=len;
tptr=pptr;
- while (i>0) {
+ while (tmp>0) {
if (!TTEST2(*tptr, 4))
return (1);
metric = EXTRACT_32BITS(tptr);
@@ -1463,7 +1619,7 @@
memset(prefix6, 0, 16);
memcpy(prefix6,tptr,byte_length);
-
+ tptr+=byte_length;
printf("\n\t\t\tIPv6 prefix: %s/%u",
ip6addr_string(prefix6),
bit_length);
@@ -1475,23 +1631,29 @@
ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no ");
if (ISIS_MASK_TLV_IP6_SUBTLV(j)) {
+ /* assume that one prefix can hold more
+ than one subTLV - therefore the first byte must reflect
+ the aggregate bytecount of the subTLVs for this prefix
+ */
if (!TTEST2(*tptr, 1))
- return (1);
- printf(" (%u)",*tptr); /* print out subTLV length */
+ return (1);
+ tslen=*(tptr++);
+ tmp--;
+ printf(" (%u)",tslen); /* print out subTLV length */
- /* so far no decoding of subTLVs is supported
- * so lets print out a hexdump of the unknown subTLV data
- */
- if(isis_print_unknown_tlv(tptr,"\n\t\t\t ",*tptr))
- return(1);
-
- i-=*tptr;
- tptr = tptr + *tptr;
- tptr++;
+ while (tslen>0) {
+ if (!TTEST2(*tptr,2))
+ goto trunctlv;
+ subt=*(tptr++);
+ subl=*(tptr++);
+ if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t\t "))
+ return(0);
+ tptr+=subl;
+ tslen-=(subl+2);
+ tmp-=(subl+2);
+ }
}
-
- i-=(6+byte_length);
- tptr+=byte_length;
+ tmp-=(6+byte_length);
}
break;
@@ -1540,13 +1702,13 @@
break;
case SUBTLV_AUTH_PRIVATE:
printf("\n\t\t\tRouting Domain private password: ");
- if(isis_print_unknown_data(pptr+1,"\n\t\t\t ",len-1))
- return(1);
+ if(!isis_print_unknown_data(pptr+1,"\n\t\t\t ",len-1))
+ return(0);
break;
default:
printf("\n\t\t\tunknown Authentication method");
- if(isis_print_unknown_data(pptr+1,"\n\t\t\t ",len-1))
- return(1);
+ if(!isis_print_unknown_data(pptr+1,"\n\t\t\t ",len-1))
+ return(0);
break;
}
break;
@@ -1705,41 +1867,20 @@
case TLV_MT_SUPPORTED:
printf("Multi Topology (%u)",len);
- i=len;
+ tmp=len;
tptr=pptr;
- while (i>1) {
+ while (tmp>1) {
/* length can only be a multiple of 2, otherwise there is
something broken -> so decode down until length is 1 */
- if (i!=1) {
+ if (tmp!=1) {
if (!TTEST2(*tptr, 2))
goto trunctlv;
printf("\n\t\t\t");
- switch(EXTRACT_16BITS(tptr)&0x0fff) {
+
+ tok2str(isis_mt_values,
+ "Reserved for IETF Consensus",
+ (EXTRACT_16BITS(tptr))&0x0fff);
- case 0:
- printf("IPv4 unicast");
- break;
-
- case 1:
- printf("In-Band Management");
- break;
-
- case 2:
- printf("IPv6 unicast");
- break;
-
- case 3:
- printf("Multicast");
- break;
-
- case 4095:
- printf("Development, Experimental or Proprietary");
- break;
-
- default:
- printf("Reserved for IETF Consensus");
- break;
- }
printf(" Topology (0x%03x)%s%s",
EXTRACT_16BITS(tptr)&0xfff,
(EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs
present",
@@ -1748,7 +1889,7 @@
printf("\n\t\t\tmalformed MT-ID");
break;
}
- i-=2;
+ tmp-=2;
tptr+=2;
}
break;
@@ -1770,8 +1911,8 @@
default:
printf("unknown TLV, type %d, length %d", type, len);
- if(isis_print_unknown_data(pptr,"\n\t\t\t",len))
- return(1);
+ if(!isis_print_unknown_data(pptr,"\n\t\t\t",len))
+ return(0);
break;
}