X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/6799b9b248e6b5d13962c0e7b645a5d457e9a205..1ee09c1510704191a14df4eb914dba3d5dc9ab58:/print-ospf.c diff --git a/print-ospf.c b/print-ospf.c index 025b65c3..6fd33b28 100644 --- a/print-ospf.c +++ b/print-ospf.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.50 2004-01-27 13:33:24 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.57 2005-04-20 21:55:14 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -51,6 +51,7 @@ static struct tok ospf_option_values[] = { { OSPF_OPTION_EA, "Advertise External" }, { OSPF_OPTION_DC, "Demand Circuit" }, { OSPF_OPTION_O, "Opaque" }, + { OSPF_OPTION_DN, "Up/Down" }, { 0, NULL } }; @@ -103,6 +104,7 @@ static struct tok ospf_dd_flag_values[] = { static struct tok lsa_opaque_values[] = { { LS_OPAQUE_TYPE_TE, "Traffic Engineering" }, { LS_OPAQUE_TYPE_GRACE, "Graceful restart" }, + { LS_OPAQUE_TYPE_RI, "Router Information" }, { 0, NULL } }; @@ -151,6 +153,25 @@ static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = { { 0, NULL } }; +static struct tok lsa_opaque_ri_tlv_values[] = { + { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_ri_tlv_cap_values[] = { + { 1, "Reserved" }, + { 2, "Reserved" }, + { 4, "Reserved" }, + { 8, "Reserved" }, + { 16, "graceful restart capable" }, + { 32, "graceful restart helper" }, + { 64, "Stub router support" }, + { 128, "Traffic engineering" }, + { 256, "p2p over LAN" }, + { 512, "path computation server" }, + { 0, NULL } +}; + static char tstr[] = " [|ospf]"; #ifdef WIN32 @@ -361,6 +382,7 @@ ospf_print_lsa(register const struct lsa *lsap) break; case LS_TYPE_ASE: + case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ TCHECK(lsap->lsa_un.un_nla.nla_mask); printf("\n\t Mask %s", ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); @@ -425,12 +447,59 @@ ospf_print_lsa(register const struct lsa *lsap) case LS_TYPE_OPAQUE_DW: switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { + case LS_OPAQUE_TYPE_RI: + tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type); + + while (ls_length != 0) { + TCHECK2(*tptr, 4); + if (ls_length < 4) { + printf("\n\t Remaining LS length %u < 4", ls_length); + return(ls_end); + } + tlv_type = EXTRACT_16BITS(tptr); + tlv_length = EXTRACT_16BITS(tptr+2); + tptr+=4; + ls_length-=4; + + printf("\n\t %s TLV (%u), length: %u, value: ", + tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), + tlv_type, + tlv_length); + + if (tlv_length > ls_length) { + printf("\n\t Bogus length %u > %u", tlv_length, + ls_length); + return(ls_end); + } + ls_length-=tlv_length; + TCHECK2(*tptr, tlv_length); + switch(tlv_type) { + + case LS_OPAQUE_RI_TLV_CAP: + if (tlv_length != 4) { + printf("\n\t Bogus length %u != 4", tlv_length); + return(ls_end); + } + printf("Capabilities: %s", + bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr))); + break; + default: + if (vflag <= 1) { + if(!print_unknown_data(tptr,"\n\t ",tlv_length)) + return(ls_end); + } + break; + + } + tptr+=tlv_length; + } + + break; case LS_OPAQUE_TYPE_GRACE: tptr = (u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type); while (ls_length != 0) { - if (!TTEST2(*tptr, 4)) - goto trunc; + TCHECK2(*tptr, 4); if (ls_length < 4) { printf("\n\t Remaining LS length %u < 4", ls_length); return(ls_end); @@ -451,6 +520,7 @@ ospf_print_lsa(register const struct lsa *lsap) return(ls_end); } ls_length-=tlv_length; + TCHECK2(*tptr, tlv_length); switch(tlv_type) { case LS_OPAQUE_GRACE_TLV_PERIOD: @@ -492,8 +562,7 @@ ospf_print_lsa(register const struct lsa *lsap) tptr = (u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type); while (ls_length != 0) { - if (!TTEST2(*tptr, 4)) - goto trunc; + TCHECK2(*tptr, 4); if (ls_length < 4) { printf("\n\t Remaining LS length %u < 4", ls_length); return(ls_end); @@ -522,8 +591,7 @@ ospf_print_lsa(register const struct lsa *lsap) tlv_length); return(ls_end); } - if (!TTEST2(*tptr, 4)) - goto trunc; + TCHECK2(*tptr, 4); subtlv_type = EXTRACT_16BITS(tptr); subtlv_length = EXTRACT_16BITS(tptr+2); tptr+=4; @@ -534,8 +602,7 @@ ospf_print_lsa(register const struct lsa *lsap) subtlv_type, subtlv_length); - if (!TTEST2(*tptr, subtlv_length)) - goto trunc; + TCHECK2(*tptr, subtlv_length); switch(subtlv_type) { case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: printf(", 0x%08x", EXTRACT_32BITS(tptr)); @@ -568,8 +635,11 @@ ospf_print_lsa(register const struct lsa *lsap) } break; case LS_OPAQUE_TE_LINK_SUBTLV_DIFFSERV_TE: - printf("\n\t\tBandwidth Constraints Model ID: (%u)", *tptr); - for (bandwidth_constraint = 0; bandwidth_constraint < 8; bandwidth_constraint++) { + printf("\n\t\tBandwidth Constraints Model ID: %s (%u)", + tok2str(diffserv_te_bc_values, "unknown", *tptr), + *tptr); + /* decode BCs until the subTLV ends */ + for (bandwidth_constraint = 0; bandwidth_constraint < (subtlv_length-4)/4; bandwidth_constraint++) { bw.i = EXTRACT_32BITS(tptr+4+bandwidth_constraint*4); printf("\n\t\t Bandwidth constraint %d: %.3f Mbps", bandwidth_constraint, @@ -634,6 +704,11 @@ ospf_print_lsa(register const struct lsa *lsap) break; case LS_OPAQUE_TE_TLV_ROUTER: + if (tlv_length < 4) { + printf("\n\t TLV length %u < 4", tlv_length); + return(ls_end); + } + TCHECK2(*tptr, 4); printf(", %s", ipaddr_string(tptr)); break; @@ -798,15 +873,13 @@ trunc: void ospf_print(register const u_char *bp, register u_int length, - register const u_char *bp2) + const u_char *bp2 _U_) { register const struct ospfhdr *op; - register const struct ip *ip; register const u_char *dataend; register const char *cp; op = (struct ospfhdr *)bp; - ip = (struct ip *)bp2; /* XXX Before we do anything else, strip off the MD5 trailer */ TCHECK(op->ospf_authtype); @@ -819,10 +892,9 @@ ospf_print(register const u_char *bp, register u_int length, /* value. If it's not valid, say so and return */ TCHECK(op->ospf_type); cp = tok2str(type2str, "unknown LS-type", op->ospf_type); - printf("OSPFv%u, %s (%u), length: %u", + printf("OSPFv%u, %s, length: %u", op->ospf_version, cp, - op->ospf_type, length); if (*cp == 'u') return;