]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-isoclns.c
Protect code for particular Juniper DLT_ values with #ifdefs, so this
[tcpdump] / print-isoclns.c
index f57770f404118b264e227278b366e78169b3dc72..ac3269c68a8b44327ae185762810c38622be716d 100644 (file)
@@ -26,7 +26,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.133.2.4 2005-04-25 18:51:52 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.133.2.8 2005-05-25 22:06:41 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -201,12 +201,20 @@ static struct tok esis_option_values[] = {
 
 #define CLNP_OPTION_DISCARD_REASON   193
 #define CLNP_OPTION_QOS_MAINTENANCE  195 /* iso8473 */
+#define CLNP_OPTION_SECURITY         197 /* iso8473 */
+#define CLNP_OPTION_SOURCE_ROUTING   200 /* iso8473 */
+#define CLNP_OPTION_ROUTE_RECORDING  203 /* iso8473 */
+#define CLNP_OPTION_PADDING          204 /* iso8473 */
 #define CLNP_OPTION_PRIORITY         205 /* iso8473 */
 
 static struct tok clnp_option_values[] = {
     { CLNP_OPTION_DISCARD_REASON,  "Discard Reason"},
     { CLNP_OPTION_PRIORITY,        "Priority"},
     { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"},
+    { CLNP_OPTION_SECURITY, "Security"},
+    { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"},
+    { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"},
+    { CLNP_OPTION_PADDING, "Padding"},
     { 0, NULL }
 };
 
@@ -286,6 +294,40 @@ static struct tok *clnp_option_rfd_error_class[] = {
     NULL
 };
 
+#define CLNP_OPTION_OPTION_QOS_MASK 0x3f
+#define CLNP_OPTION_SCOPE_MASK      0xc0
+#define CLNP_OPTION_SCOPE_SA_SPEC   0x40
+#define CLNP_OPTION_SCOPE_DA_SPEC   0x80
+#define CLNP_OPTION_SCOPE_GLOBAL    0xc0
+
+static struct tok clnp_option_scope_values[] = {
+    { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"},
+    { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"},
+    { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"},
+    { 0, NULL }
+};
+
+static struct tok clnp_option_sr_rr_values[] = {
+    { 0x0, "partial"},
+    { 0x0, "complete"},
+    { 0, NULL }
+};
+
+static struct tok clnp_option_sr_rr_string_values[] = {
+    { CLNP_OPTION_SOURCE_ROUTING, "source routing"},
+    { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"},
+    { 0, NULL }
+};
+
+static struct tok clnp_option_qos_global_values[] = {
+    { 0x20, "reserved"},
+    { 0x10, "sequencing vs. delay"},
+    { 0x08, "congested"},
+    { 0x04, "delay vs. cost"},
+    { 0x02, "error vs. delay"},
+    { 0x01, "error vs. cost"},
+    { 0, NULL }
+};
 
 #define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP           3 /* draft-ietf-isis-traffic-05 */
 #define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID  4 /* draft-ietf-isis-gmpls-extensions */
@@ -586,7 +628,9 @@ void isoclns_print(const u_int8_t *p, u_int length, u_int caplen)
                break;
 
        case NLPID_NULLNS:
-               (void)printf(", length: %u", length);
+               (void)printf("%slength: %u",
+                            eflag ? "" : ", ",
+                             length);
                break;
 
         case NLPID_Q933:
@@ -610,7 +654,9 @@ void isoclns_print(const u_int8_t *p, u_int length, u_int caplen)
        default:
                 if (!eflag)
                     printf("OSI NLPID 0x%02x unknown",*p);
-               (void)printf(", length: %u", length);
+               (void)printf("%slength: %u",
+                            eflag ? "" : ", ",
+                             length);
                if (caplen > 1)
                         print_unknown_data(p,"\n\t",caplen);
                break;
@@ -656,7 +702,7 @@ struct clnp_segment_header_t {
 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, clnp_flags;
+        u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags;
        const struct clnp_header_t *clnp_header;
        const struct clnp_segment_header_t *clnp_segment_header;
         u_int8_t rfd_error_major,rfd_error_minor;
@@ -746,8 +792,7 @@ static int clnp_print (const u_int8_t *pptr, u_int length)
             u_int op, opli;
             const u_int8_t *tptr;
             
-            if (snapend - pptr < 2)
-                return (0);
+            TCHECK2(*pptr, 2);
             if (li < 2) {
                 printf(", bad opts/li");
                 return (0);
@@ -755,15 +800,14 @@ static int clnp_print (const u_int8_t *pptr, u_int length)
             op = *pptr++;
             opli = *pptr++;
             li -= 2;
+            TCHECK2(*pptr, opli);
             if (opli > li) {
                 printf(", opt (%d) too long", op);
                 return (0);
             }
             li -= opli;
             tptr = pptr;
-            
-            if (snapend < pptr)
-                return(0);
+            tlen = opli;
             
             printf("\n\t  %s Option #%u, length %u, value: ",
                    tok2str(clnp_option_values,"Unknown",op),
@@ -772,9 +816,61 @@ static int clnp_print (const u_int8_t *pptr, u_int length)
 
             switch (op) {
 
+
+            case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */
+            case CLNP_OPTION_SOURCE_ROUTING:  
+                    printf("%s %s",
+                           tok2str(clnp_option_sr_rr_values,"Unknown",*tptr),
+                           tok2str(clnp_option_sr_rr_string_values,"Unknown Option %u",op));
+                    nsap_offset=*(tptr+1);
+                    if (nsap_offset == 0) {
+                            printf(" Bad NSAP offset (0)");
+                            break;
+                    }
+                    nsap_offset-=1; /* offset to nsap list */
+                    if (nsap_offset > tlen) {
+                            printf(" Bad NSAP offset (past end of option)");
+                            break;
+                    }
+                    tptr+=nsap_offset;
+                    tlen-=nsap_offset;
+                    while (tlen > 0) {
+                            source_address_length=*tptr;
+                            if (tlen < source_address_length+1) {
+                                    printf("\n\t    NSAP address goes past end of option");
+                                    break;
+                           }
+                            if (source_address_length > 0) {
+                                    source_address=(tptr+1);
+                                    TCHECK2(*source_address, source_address_length);
+                                    printf("\n\t    NSAP address (length %u): %s",
+                                           source_address_length,
+                                           isonsap_string(source_address, source_address_length));
+                            }
+                            tlen-=source_address_length+1;
+                    }
+                    break;
+
             case CLNP_OPTION_PRIORITY:
-                printf("%u", *tptr);
-                break;
+                    printf("0x%1x", *tptr&0x0f);
+                    break;
+
+            case CLNP_OPTION_QOS_MAINTENANCE:
+                    printf("\n\t    Format Code: %s",
+                           tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK));
+
+                    if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL)
+                            printf("\n\t    QoS Flags [%s]",
+                                   bittok2str(clnp_option_qos_global_values,
+                                              "none",
+                                              *tptr&CLNP_OPTION_OPTION_QOS_MASK));
+                    break;
+
+            case CLNP_OPTION_SECURITY:
+                    printf("\n\t    Format Code: %s, Security-Level %u",
+                           tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK),
+                           *(tptr+1));
+                    break;
 
             case CLNP_OPTION_DISCARD_REASON:
                 rfd_error_major = (*tptr&0xf0) >> 4;
@@ -786,6 +882,10 @@ static int clnp_print (const u_int8_t *pptr, u_int length)
                        rfd_error_minor);
                 break;
 
+            case CLNP_OPTION_PADDING:
+                    printf("padding data");
+                break;
+
                 /*
                  * FIXME those are the defined Options that lack a decoder
                  * you are welcome to contribute code ;-)
@@ -804,6 +904,7 @@ static int clnp_print (const u_int8_t *pptr, u_int length)
 
         case    CLNP_PDU_ER: /* fall through */
         case   CLNP_PDU_ERP:
+            TCHECK(*pptr);
             if (*(pptr) == NLPID_CLNP) {
                 printf("\n\t-----original packet-----\n\t");
                 /* FIXME recursion protection */