#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.113 2003-12-20 22:24:51 hannes Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.124 2004-10-19 15:27:55 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "addrtoname.h"
#include "ethertype.h"
#include "ether.h"
+#include "nlpid.h"
#include "extract.h"
#include "gmpls.h"
#include "oui.h"
-#define NLPID_CLNP 0x81 /* iso9577 */
-#define NLPID_ESIS 0x82 /* iso9577 */
-#define NLPID_ISIS 0x83 /* iso9577 */
-#define NLPID_IP6 0x8e
-#define NLPID_IP 0xcc
-#define NLPID_NULLNS 0
-
-static struct tok osi_nlpid_values[] = {
- { NLPID_NULLNS, "NULL-NS"},
- { NLPID_CLNP, "CLNP"},
- { NLPID_ESIS, "ES-IS"},
- { NLPID_ISIS, "IS-IS"},
- { NLPID_IP, "IPv4"},
- { NLPID_IP6, "IPv6"},
- { 0, NULL }
-};
-
#define IPV4 1 /* AFI value */
#define IPV6 2 /* AFI value */
#define ISIS_PDU_TYPE_MASK 0x1F
#define ESIS_PDU_TYPE_MASK 0x1F
+#define CLNP_PDU_TYPE_MASK 0x1F
#define ISIS_LAN_PRIORITY_MASK 0x7F
#define ISIS_PDU_L1_LAN_IIH 15
#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */
#define ISIS_TLV_NORTEL_PRIVATE1 176
#define ISIS_TLV_NORTEL_PRIVATE2 177
-#define ISIS_TLV_HOLDTIME 198 /* ES-IS */
#define ISIS_TLV_RESTART_SIGNALING 211 /* draft-ietf-isis-restart-01 */
#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */
#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
-#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */
+#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */
static struct tok isis_tlv_values[] = {
{ ISIS_TLV_AREA_ADDR, "Area address(es)"},
#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */
#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */
#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_DIFFSERV_TE 12 /* draft-ietf-tewg-diff-te-proto-06 */
#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */
#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* draft-ietf-isis-gmpls-extensions */
#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* draft-ietf-isis-gmpls-extensions */
{ ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" },
{ ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" },
{ ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" },
+ { ISIS_SUBTLV_EXT_IS_REACH_DIFFSERV_TE, "Diffserv TE" },
{ ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" },
{ ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" },
{ ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
};
static int osi_cksum(const u_int8_t *, u_int);
+static int clnp_print(const u_int8_t *, u_int);
static void esis_print(const u_int8_t *, u_int);
static int isis_print(const u_int8_t *, u_int);
return;
}
- printf("OSI, %s",tok2str(osi_nlpid_values,"Unknown NLPID (0x%02x)",*p));
+ if (eflag)
+ printf("nlpid %s (0x%02x), ",
+ tok2str(nlpid_values,"Unknown NLPID (0x%02x)",*p),
+ *p);
switch (*p) {
case NLPID_CLNP:
- (void)printf(", length %u", length);
+ if (!clnp_print(p, length))
+ print_unknown_data(p,"\n\t",caplen);
break;
case NLPID_ESIS:
(void)printf(", length: %u", length);
break;
+ case NLPID_IP:
+ ip_print(p+1, length-1);
+ break;
+
+#ifdef INET6
+ case NLPID_IP6:
+ ip6_print(p+1, length-1);
+ break;
+#endif
+
+ case NLPID_PPP:
+ ppp_print(p+1, length-1);
+ break;
+
default:
(void)printf(", length: %u", length);
if (caplen > 1)
}
}
+#define CLNP_PDU_ER 1
+#define CLNP_PDU_DT 28
+#define CLNP_PDU_MD 29
+#define CLNP_PDU_ERQ 30
+#define CLNP_PDU_ERP 31
+
+static struct tok clnp_pdu_values[] = {
+ { CLNP_PDU_ER, "Error Report"},
+ { CLNP_PDU_MD, "MD"},
+ { CLNP_PDU_DT, "Data"},
+ { CLNP_PDU_ERQ, "Echo Request"},
+ { CLNP_PDU_ERP, "Echo Response"},
+ { 0, NULL }
+};
+
+struct clnp_header_t {
+ u_int8_t nlpid;
+ u_int8_t length_indicator;
+ u_int8_t version;
+ u_int8_t lifetime; /* units of 500ms */
+ u_int8_t type;
+ u_int8_t segment_length[2];
+ u_int8_t cksum[2];
+};
+
+/*
+ * clnp_print
+ * Decode CLNP packets. Return 0 on error.
+ */
+
+static int clnp_print (const u_int8_t *pptr, u_int length)
+{
+ const u_int8_t *optr,*source_address,*dest_address;
+ u_int li,source_address_length,dest_address_length, clnp_pdu_type;
+ const struct clnp_header_t *clnp_header;
+
+ clnp_header = (const struct clnp_header_t *) pptr;
+ li = clnp_header->length_indicator;
+ optr = pptr;
+
+ if (!eflag)
+ printf("CLNP, ");
+
+ /*
+ * Sanity checking of the header.
+ */
+
+ /* FIXME */
+
+ clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK;
+
+ pptr += sizeof(struct clnp_header_t);
+ dest_address_length = *pptr;
+ dest_address = pptr + 1;
+
+ pptr += (1 + dest_address_length);
+ source_address_length = *pptr;
+ source_address = pptr +1;
+
+ pptr += (1 + source_address_length);
+
+ if (vflag < 1) {
+ printf("%s > %s, length %u",
+ print_nsap(source_address, source_address_length),
+ print_nsap(dest_address, dest_address_length),
+ length);
+ return (1);
+ }
+ printf("length %u", length);
+
+ printf("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, PDU length: %u, checksum: 0x%04x ",
+ tok2str(clnp_pdu_values,
+ "unknown (%u)",
+ clnp_pdu_type),
+ clnp_header->length_indicator,
+ clnp_header->version,
+ clnp_header->lifetime/2,
+ (clnp_header->lifetime%2)*5,
+ EXTRACT_16BITS(clnp_header->segment_length),
+ EXTRACT_16BITS(clnp_header->cksum));
+
+ /* do not attempt to verify the checksum if it is zero */
+ if (EXTRACT_16BITS(clnp_header->cksum) == 0)
+ printf("(unverified)");
+ else printf("(%s)", osi_cksum(optr, li) ? "incorrect" : "correct");
+
+ printf("\n\tsource address (length %u): %s\n\tdest address (length %u): %s",
+ source_address_length,
+ print_nsap(source_address, source_address_length),
+ dest_address_length,
+ print_nsap(dest_address, dest_address_length));
+
+ /* dump the remaining header data */
+ print_unknown_data(pptr,"\n\t",clnp_header->length_indicator-(pptr-optr));
+
+ switch (clnp_pdu_type) {
+
+ case CLNP_PDU_ER:
+ case CLNP_PDU_DT:
+ case CLNP_PDU_MD:
+ case CLNP_PDU_ERQ:
+ case CLNP_PDU_ERP:
+
+ default:
+ /* dump the PDU specific data */
+ print_unknown_data(optr+clnp_header->length_indicator,"\n\t ",length-clnp_header->length_indicator);
+
+ }
+
+ return (1);
+}
+
+
#define ESIS_PDU_REDIRECT 6
#define ESIS_PDU_ESH 2
#define ESIS_PDU_ISH 4
u_int li,esis_pdu_type,source_address_length, source_address_number;
const struct esis_header_t *esis_header;
+ if (!eflag)
+ printf("ES-IS, ");
+
if (length <= 2) {
if (qflag)
- printf(" bad pkt!");
+ printf("bad pkt!");
else
- printf(" no header at all!");
+ printf("no header at all!");
return;
}
/*
* Sanity checking of the header.
*/
-
+
+ if (esis_header->nlpid != NLPID_ESIS) {
+ printf("nlpid 0x%02x packet not supported", esis_header->nlpid);
+ return;
+ }
+
if (esis_header->version != ESIS_VERSION) {
- printf(", version %d packet not supported", esis_header->version);
+ printf("version %d packet not supported", esis_header->version);
return;
}
if (li > length) {
- printf(", length indicator(%d) > PDU size (%d)!", li, length);
+ printf("length indicator(%d) > PDU size (%d)!", li, length);
return;
}
if (li < sizeof(struct esis_header_t) + 2) {
- printf(", length indicator < min PDU size %d:", li);
+ printf("length indicator < min PDU size %d:", li);
while (--length != 0)
printf("%02X", *pptr++);
return;
esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK;
if (vflag < 1) {
- printf(", %s, length %u",
+ printf("%s, length %u",
tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type),
length);
return;
} else
- printf(", length %u\n\t%s (%u)",
+ printf("length %u\n\t%s (%u)",
length,
tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type),
esis_pdu_type);
switch (op) {
- case ISIS_TLV_AREA_ADDR:
- printf("\n\t %s", print_nsap(tptr, opli));
- break;
-
case ESIS_OPTION_ES_CONF_TIME:
printf("%us", EXTRACT_16BITS(tptr));
break;
case ESIS_OPTION_PROTOCOLS:
while (opli>0) {
printf("%s (0x%02x)",
- tok2str(osi_nlpid_values,
+ tok2str(nlpid_values,
"unknown",
*tptr),
*tptr);
static int
isis_print_is_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) {
- int priority_level;
+ int priority_level,bandwidth_constraint;
union { /* int to float conversion buffer for several subTLVs */
float f;
u_int32_t i;
case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID:
case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
- printf(", 0x%08x", EXTRACT_32BITS(tptr));
- if (subl == 8) /* draft-ietf-isis-gmpls-extensions */
- printf(", 0x%08x", EXTRACT_32BITS(tptr+4));
+ if (subl >= 4) {
+ printf(", 0x%08x", EXTRACT_32BITS(tptr));
+ if (subl == 8) /* draft-ietf-isis-gmpls-extensions */
+ printf(", 0x%08x", EXTRACT_32BITS(tptr+4));
+ }
break;
case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
- printf(", %s", ipaddr_string(tptr));
+ if (subl >= 4)
+ printf(", %s", ipaddr_string(tptr));
break;
case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW:
- bw.i = EXTRACT_32BITS(tptr);
- printf(", %.3f Mbps", bw.f*8/1000000 );
+ if (subl >= 4) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf(", %.3f Mbps", bw.f*8/1000000 );
+ }
break;
case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
- for (priority_level = 0; priority_level < 8; priority_level++) {
+ if (subl >= 32) {
+ for (priority_level = 0; priority_level < 8; priority_level++) {
bw.i = EXTRACT_32BITS(tptr);
printf("%s priority level %d: %.3f Mbps",
ident,
priority_level,
bw.f*8/1000000 );
tptr+=4;
+ }
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_DIFFSERV_TE:
+ printf("%sBandwidth Constraints Model ID: %s (%u)",
+ ident,
+ tok2str(diffserv_te_bc_values, "unknown", *tptr),
+ *tptr);
+ tptr++;
+ /* decode BCs until the subTLV ends */
+ for (bandwidth_constraint = 0; bandwidth_constraint < (subl-1)/4; bandwidth_constraint++) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s Bandwidth constraint %d: %.3f Mbps",
+ ident,
+ bandwidth_constraint,
+ bw.f*8/1000000 );
+ tptr+=4;
}
break;
case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC:
- printf(", %u", EXTRACT_24BITS(tptr));
+ if (subl >= 3)
+ printf(", %u", EXTRACT_24BITS(tptr));
break;
case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
- printf(", %s, Priority %u",
+ if (subl >= 2) {
+ printf(", %s, Priority %u",
bittok2str(gmpls_link_prot_values, "none", *tptr),
*(tptr+1));
+ }
break;
case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
- printf("%s Interface Switching Capability:%s",
+ if (subl >= 36) {
+ printf("%s Interface Switching Capability:%s",
ident,
tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
- printf(", LSP Encoding: %s",
+ printf(", LSP Encoding: %s",
tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
- tptr+=4;
- printf("%s Max LSP Bandwidth:",ident);
- for (priority_level = 0; priority_level < 8; priority_level++) {
+ tptr+=4;
+ printf("%s Max LSP Bandwidth:",ident);
+ for (priority_level = 0; priority_level < 8; priority_level++) {
bw.i = EXTRACT_32BITS(tptr);
printf("%s priority level %d: %.3f Mbps",
ident,
priority_level,
bw.f*8/1000000 );
tptr+=4;
- }
- 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){
+ }
+ 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(!print_unknown_data(tptr,"\n\t\t ",
subl-36))
return(0);
+ }
}
break;
default:
header_csnp = (const struct isis_csnp_header *)pptr;
header_psnp = (const struct isis_psnp_header *)pptr;
+ if (!eflag)
+ printf("IS-IS, ");
+
/*
* Sanity checking of the header.
*/
if (isis_header->version != ISIS_VERSION) {
- printf(", version %d packet not supported", isis_header->version);
+ printf("version %d packet not supported", isis_header->version);
return (0);
}
if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) {
- printf(", system ID length of %d is not supported",
+ printf("system ID length of %d is not supported",
isis_header->id_length);
return (0);
}
if (isis_header->pdu_version != ISIS_VERSION) {
- printf(", version %d packet not supported", isis_header->pdu_version);
+ printf("version %d packet not supported", isis_header->pdu_version);
return (0);
}
max_area = 3; /* silly shit */
break;
case 255:
- printf(", bad packet -- 255 areas");
+ printf("bad packet -- 255 areas");
return (0);
default:
break;
/* toss any non 6-byte sys-ID len PDUs */
if (id_length != 6 ) {
- printf(", bad packet -- illegal sys-ID length (%u)", id_length);
+ printf("bad packet -- illegal sys-ID length (%u)", id_length);
return (0);
}
/* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
if (vflag < 1) {
- printf(", %s", tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type));
+ printf("%s", tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type));
switch (pdu_type) {
break;
case ISIS_PDU_L1_CSNP:
case ISIS_PDU_L2_CSNP:
- printf(", src-id %s", isis_print_id(header_csnp->source_id,SYSTEM_ID_LEN));
+ printf(", src-id %s", isis_print_id(header_csnp->source_id,NODE_ID_LEN));
break;
case ISIS_PDU_L1_PSNP:
case ISIS_PDU_L2_PSNP:
- printf(", src-id %s", isis_print_id(header_psnp->source_id,SYSTEM_ID_LEN));
+ printf(", src-id %s", isis_print_id(header_psnp->source_id,NODE_ID_LEN));
break;
}
if (!TTEST2(*(tptr), 1))
goto trunctlv;
printf("%s (0x%02x)",
- tok2str(osi_nlpid_values,
+ tok2str(nlpid_values,
"unknown",
*tptr),
*tptr);