]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ospf.c
Backout CHANGES update - wrong branch
[tcpdump] / print-ospf.c
index fe20bcc976f119fc562d1c986f1c2eb8d4bf361d..8a6511462e6c6b28a4383342c7864b8f6fa1b70f 100644 (file)
  * OSPF support contributed by Jeffrey Honig ([email protected])
  */
 
+#ifndef lint
+static const char rcsid[] _U_ =
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.56.2.4 2006-12-13 08:24:27 hannes Exp $ (LBL)";
+#endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #include "extract.h"
 #include "gmpls.h"
 
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.46 2003-11-15 00:39:34 guy Exp $ (LBL)";
-#endif
 #include "ospf.h"
 
 #include "ip.h"
@@ -51,12 +51,13 @@ 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 }
 };
 
 static struct tok ospf_authtype_values[] = {
        { OSPF_AUTH_NONE,       "none" },
-       { OSPF_AUTH_NONE,       "simple" },
+       { OSPF_AUTH_SIMPLE,     "simple" },
        { OSPF_AUTH_MD5,        "MD5" },
        { 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 }
 };
 
@@ -126,11 +128,24 @@ static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = {
        { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" },
        { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR,    "Interface Switching Capability" },
        { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP,    "Shared Risk Link Group" },
+       { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS,       "Bandwidth Constraints" },
        { 0,                    NULL }
 };
 
-#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP        1  /* rfc3630 */
-#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA         2  /* rfc3630 */
+static struct tok lsa_opaque_grace_tlv_values[] = {
+       { LS_OPAQUE_GRACE_TLV_PERIOD,             "Grace Period" },
+       { LS_OPAQUE_GRACE_TLV_REASON,             "Graceful restart Reason" },
+       { LS_OPAQUE_GRACE_TLV_INT_ADDRESS,        "IPv4 interface address" },
+       { 0,                    NULL }
+};
+
+static struct tok lsa_opaque_grace_tlv_reason_values[] = {
+       { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN,     "Unknown" },
+       { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART,  "Software Restart" },
+       { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE,  "Software Reload/Upgrade" },
+       { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH,   "Control Processor Switch" },
+       { 0,                    NULL }
+};
 
 static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
        { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" },
@@ -138,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
@@ -219,7 +253,7 @@ ospf_print_lsa(register const struct lsa *lsap)
        register const struct aslametric *almp;
        register const struct mcla *mcp;
        register const u_int32_t *lp;
-       register int j, k, tlv_type, tlv_length, subtlv_type, subtlv_length, priority_level;
+       register int j, k, tlv_type, tlv_length, subtlv_type, subtlv_length, priority_level, te_class;
        register int ls_length;
        const u_int8_t *tptr;
        int count_srlg;
@@ -348,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));
@@ -412,13 +447,122 @@ 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_TE:
-               if (!TTEST2(*tptr, 4))
-                   goto trunc;
+            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) {
+                    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_grace_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_GRACE_TLV_PERIOD:
+                        if (tlv_length != 4) {
+                            printf("\n\t    Bogus length %u != 4", tlv_length);
+                            return(ls_end);
+                        }
+                        printf("%us",EXTRACT_32BITS(tptr));
+                        break;
+                    case LS_OPAQUE_GRACE_TLV_REASON:
+                        if (tlv_length != 1) {
+                            printf("\n\t    Bogus length %u != 1", tlv_length);
+                            return(ls_end);
+                        }
+                        printf("%s (%u)",
+                               tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr),
+                               *tptr);
+                        break;
+                    case LS_OPAQUE_GRACE_TLV_INT_ADDRESS:
+                        if (tlv_length != 4) {
+                            printf("\n\t    Bogus length %u != 4", tlv_length);
+                            return(ls_end);
+                        }
+                        printf("%s", ipaddr_string(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_TE:
                tptr = (u_int8_t *)(&lsap->lsa_un.un_te_lsa_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);
@@ -447,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;
@@ -459,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));
@@ -485,10 +627,22 @@ ospf_print_lsa(register const struct lsa *lsap)
                                 printf(", %.3f Mbps", bw.f*8/1000000 );
                                 break;
                             case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
-                                for (priority_level = 0; priority_level < 8; priority_level++) {
-                                    bw.i = EXTRACT_32BITS(tptr+priority_level*4);
-                                    printf("\n\t\tpriority level %d: %.3f Mbps",
-                                           priority_level,
+                                for (te_class = 0; te_class < 8; te_class++) {
+                                    bw.i = EXTRACT_32BITS(tptr+te_class*4);
+                                    printf("\n\t\tTE-Class %u: %.3f Mbps",
+                                           te_class,
+                                           bw.f*8/1000000 );
+                                }
+                                break;
+                            case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS:
+                                printf("\n\t\tBandwidth Constraints Model ID: %s (%u)",
+                                       tok2str(diffserv_te_bc_values, "unknown", *tptr),
+                                       *tptr);
+                                /* decode BCs until the subTLV ends */
+                                for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) {
+                                    bw.i = EXTRACT_32BITS(tptr+4+te_class*4);
+                                    printf("\n\t\t  Bandwidth constraint CT%u: %.3f Mbps",
+                                           te_class,
                                            bw.f*8/1000000 );
                                 }
                                 break;
@@ -550,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;
                         
@@ -714,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);
@@ -735,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;
@@ -776,9 +932,8 @@ ospf_print(register const u_char *bp, register u_int length,
                        break;
 
                case OSPF_AUTH_SIMPLE:
-                       (void)fn_printn(op->ospf_authdata,
-                           sizeof(op->ospf_authdata), NULL);
-                       printf("\"");
+                        printf("\n\tSimple text password: ");
+                        safeputs(op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN);
                        break;
 
                case OSPF_AUTH_MD5: