]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-lspping.c
NDOize OpenFlow, IEEE slow and telnet decoders
[tcpdump] / print-lspping.c
index 76bd14c2da4260a6462c15e2a780660e90c9ce6b..b920ae77d211065ae9899b8cfcdca55339f6dad0 100644 (file)
  * Original code by Hannes Gredler ([email protected])
  */
 
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.14 2005-04-19 12:44:05 hannes Exp $";
-#endif
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -34,6 +29,7 @@ static const char rcsid[] _U_ =
 
 #include "bgp.h"
 #include "l2vpn.h"
+#include "oui.h"
 
 /*
  * LSPPING common header
@@ -67,9 +63,9 @@ struct lspping_common_header {
     u_int8_t version[2];
     u_int8_t reserved[2];
     u_int8_t msg_type;
-    u_int8_t reply_mode;   
-    u_int8_t return_code;   
-    u_int8_t return_subcode;   
+    u_int8_t reply_mode;
+    u_int8_t return_code;
+    u_int8_t return_subcode;
     u_int8_t sender_handle[4];
     u_int8_t seq_number[4];
     u_int8_t ts_sent_sec[4];
@@ -79,8 +75,6 @@ struct lspping_common_header {
 };
 
 #define LSPPING_VERSION            1
-#define FALSE 0
-#define TRUE  1
 
 static const struct tok lspping_msg_type_values[] = {
     { 1, "MPLS Echo Request"},
@@ -113,7 +107,7 @@ static const struct tok lspping_return_code_values[] = {
 };
 
 
-/* 
+/*
  * LSPPING TLV header
  *  0                   1                   2                   3
  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -136,15 +130,25 @@ struct lspping_tlv_header {
 #define        LSPPING_TLV_TARGET_FEC_STACK      1
 #define        LSPPING_TLV_DOWNSTREAM_MAPPING    2
 #define        LSPPING_TLV_PAD                   3
-#define        LSPPING_TLV_ERROR_CODE            4
-#define        LSPPING_TLV_VENDOR_PRIVATE        5 
+#define LSPPING_TLV_VENDOR_ENTERPRISE     5
+#define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
+#define LSPPING_TLV_INTERFACE_LABEL_STACK 7
+#define        LSPPING_TLV_ERROR_CODE            9
+#define LSPPING_TLV_REPLY_TOS_BYTE        10
+#define        LSPPING_TLV_BFD_DISCRIMINATOR     15 /* draft-ietf-bfd-mpls-02 */
+#define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
+#define        LSPPING_TLV_VENDOR_PRIVATE        0xfc00
 
 static const struct tok lspping_tlv_values[] = {
     { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
     { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
     { LSPPING_TLV_PAD, "Pad" },
     { LSPPING_TLV_ERROR_CODE, "Error Code" },
-    { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Enterprise Code" },
+    { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
+    { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
+    { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
+    { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
+    { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
     { 0, NULL}
 };
 
@@ -466,7 +470,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
     int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
     int tlv_hexdump,subtlv_hexdump;
     int lspping_subtlv_len,lspping_subtlv_type;
-    struct timeval timestamp; 
+    struct timeval timestamp;
 
     union {
         const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
@@ -535,26 +539,26 @@ lspping_print(register const u_char *pptr, register u_int len) {
         lspping_com_header->return_code == 12 )
         printf("\n\t  Return Code: %s %u (%u)\n\t  Return Subcode: (%u)",
                tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
-               lspping_com_header->return_subcode,    
+               lspping_com_header->return_subcode,
                lspping_com_header->return_code,
                lspping_com_header->return_subcode);
     else
         printf("\n\t  Return Code: %s (%u)\n\t  Return Subcode: (%u)",
-               tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),   
+               tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
                lspping_com_header->return_code,
                lspping_com_header->return_subcode);
+
     printf("\n\t  Sender Handle: 0x%08x, Sequence: %u",
            EXTRACT_32BITS(lspping_com_header->sender_handle),
            EXTRACT_32BITS(lspping_com_header->seq_number));
 
     timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec);
-    timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec);     
+    timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec);
     printf("\n\t  Sender Timestamp: ");
     ts_print(&timestamp);
 
     timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec);
-    timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); 
+    timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec);
     printf("Receiver Timestamp: ");
     if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0))
         ts_print(&timestamp);
@@ -565,6 +569,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
     tlen-=sizeof(const struct lspping_common_header);
 
     while(tlen>(int)sizeof(struct lspping_tlv_header)) {
+
         /* did we capture enough for fully decoding the tlv header ? */
         if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header)))
             goto trunc;
@@ -573,10 +578,11 @@ lspping_print(register const u_char *pptr, register u_int len) {
         lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type);
         lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length);
 
-        if (lspping_tlv_len == 0)
+        /* some little sanity checking */
+        if (lspping_tlv_type == 0 || lspping_tlv_len == 0)
             return;
 
-        if(lspping_tlv_len % 4 || lspping_tlv_len < 4) { /* aligned to four octet boundary */
+        if(lspping_tlv_len < 4) {
             printf("\n\t  ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len);
             return;
         }
@@ -609,7 +615,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
                 lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type);
                 lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length);
                 subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
-                
+
                 if (lspping_subtlv_len == 0)
                     break;
 
@@ -718,7 +724,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
                                    "unknown",
                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
-                    
+
                     break;
 
                     /* the old L2VPN VCID subTLV does not have support for the sender field */
@@ -733,7 +739,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
                                    "unknown",
                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)),
                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation));
-                    
+
                     break;
 
                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID:
@@ -748,7 +754,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
                                    "unknown",
                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation));
-                    
+
                     break;
 
                 default:
@@ -757,7 +763,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
                 }
                 /* do we want to see an additionally subtlv hexdump ? */
                 if (vflag > 1 || subtlv_hexdump==TRUE)
-                    print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \
+                    print_unknown_data(gndo,tlv_tptr+sizeof(struct lspping_tlv_header), \
                                        "\n\t      ",
                                        lspping_subtlv_len);
 
@@ -818,7 +824,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
 
             tlv_ptr.lspping_tlv_downstream_map_info= \
                 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
-            
+
             /* FIXME add hash-key type, depth limit, multipath processing */
 
 
@@ -832,25 +838,50 @@ lspping_print(register const u_char *pptr, register u_int len) {
 
             break;
 
+        case LSPPING_TLV_BFD_DISCRIMINATOR:
+            tptr += sizeof(struct lspping_tlv_header);
+            if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN))
+                goto trunc;
+            printf("\n\t    BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr));
+            break;
+
+        case  LSPPING_TLV_VENDOR_ENTERPRISE:
+        {
+            u_int32_t vendor_id;
+
+            if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN))
+                goto trunc;
+            vendor_id = EXTRACT_32BITS(tlv_tptr);
+            printf("\n\t    Vendor: %s (0x%04x)",
+                   tok2str(smi_values, "Unknown", vendor_id),
+                   vendor_id);
+        }
+            break;
+
             /*
              *  FIXME those are the defined TLVs that lack a decoder
              *  you are welcome to contribute code ;-)
              */
-
         case LSPPING_TLV_PAD:
         case LSPPING_TLV_ERROR_CODE:
         case LSPPING_TLV_VENDOR_PRIVATE:
-    
+
         default:
             if (vflag <= 1)
-                print_unknown_data(tlv_tptr,"\n\t    ",tlv_tlen);
+                print_unknown_data(gndo,tlv_tptr,"\n\t    ",tlv_tlen);
             break;
         }
         /* do we want to see an additionally tlv hexdump ? */
         if (vflag > 1 || tlv_hexdump==TRUE)
-            print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t    ",
+            print_unknown_data(gndo,tptr+sizeof(struct lspping_tlv_header),"\n\t    ",
                                lspping_tlv_len);
 
+
+        /* All TLVs are aligned to four octet boundary */
+        if (lspping_tlv_len % 4) {
+            lspping_tlv_len += (4 - lspping_tlv_len % 4);
+        }
+
         tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
         tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
     }
@@ -858,3 +889,9 @@ lspping_print(register const u_char *pptr, register u_int len) {
 trunc:
     printf("\n\t\t packet exceeded snapshot");
 }
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */