]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-lspping.c
IP packet information printing from NFLOG packet
[tcpdump] / print-lspping.c
index 50e28f2b8ca0468d1391cad76f8ffb0a71db3bce..2ca57fb05cf9dd48bfb243ae9a144b61f4bfa81c 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.7 2004-06-15 08:17:19 hannes Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -31,7 +31,10 @@ static const char rcsid[] _U_ =
 #include "interface.h"
 #include "extract.h"
 #include "addrtoname.h"
+
 #include "bgp.h"
+#include "l2vpn.h"
+#include "oui.h"
 
 /*
  * LSPPING common header
@@ -77,8 +80,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"},
@@ -134,15 +135,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}
 };
 
@@ -153,9 +164,10 @@ static const struct tok lspping_tlv_values[] = {
 #define        LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4    6
 #define        LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6    7
 #define        LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT   8
-#define        LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID    9
-#define        LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4     10
-#define        LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6     11
+#define        LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9
+#define        LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID   10
+#define        LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4     11
+#define        LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6     12
 
 static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
@@ -166,6 +178,7 @@ static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
+    { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"},
     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"},
     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
@@ -359,6 +372,22 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
     u_int8_t encapsulation[2];
 };
 
+/*
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      Remote PE Address                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                             VC ID                             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Encapsulation Type       |         Must Be Zero          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t {
+    u_int8_t remote_pe_address [4];
+    u_int8_t vc_id [4];
+    u_int8_t encapsulation[2];
+};
+
 /*
  *  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
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -378,6 +407,64 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t {
     u_int8_t encapsulation[2];
 };
 
+/*
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               MTU             | Address Type  |  Resvd (SBZ)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Downstream IP Address (4 or 16 octets)            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         Downstream Interface Address (4 or 16 octets)         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Hash Key Type | Depth Limit   |        Multipath Length       |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * .                                                               .
+ * .                     (Multipath Information)                   .
+ * .                                                               .
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               Downstream Label                |    Protocol   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * .                                                               .
+ * .                                                               .
+ * .                                                               .
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |               Downstream Label                |    Protocol   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_downstream_map_ipv4_t {
+    u_int8_t mtu [2];
+    u_int8_t address_type;
+    u_int8_t res;
+    u_int8_t downstream_ip[4];
+    u_int8_t downstream_interface[4];
+};
+
+struct lspping_tlv_downstream_map_ipv6_t {
+    u_int8_t mtu [2];
+    u_int8_t address_type;
+    u_int8_t res;
+    u_int8_t downstream_ip[16];
+    u_int8_t downstream_interface[16];
+};
+
+struct lspping_tlv_downstream_map_info_t {
+    u_int8_t hash_key_type;
+    u_int8_t depth_limit;
+    u_int8_t multipath_length [2];
+};
+
+#define LSPPING_AFI_IPV4 1
+#define LSPPING_AFI_UNMB 2
+#define LSPPING_AFI_IPV6 3
+
+static const struct tok lspping_tlv_downstream_addr_values[] = {
+    { LSPPING_AFI_IPV4, "IPv4"},
+    { LSPPING_AFI_IPV6, "IPv6"},
+    { LSPPING_AFI_UNMB, "Unnumbered"},
+    { 0, NULL}
+};
+
 void
 lspping_print(register const u_char *pptr, register u_int len) {
 
@@ -388,6 +475,13 @@ 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; 
+
+    union {
+        const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
+        const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
+        const struct lspping_tlv_downstream_map_info_t  *lspping_tlv_downstream_map_info;
+    } tlv_ptr;
 
     union {
         const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
@@ -397,6 +491,7 @@ lspping_print(register const u_char *pptr, register u_int len) {
         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
         const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
+        const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
         const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
         const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
         const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
@@ -429,10 +524,11 @@ lspping_print(register const u_char *pptr, register u_int len) {
 
     tlen=len;
 
-    printf("\n\tLSP-PINGv%u, msg-type: %s (%u), reply-mode: %s (%u)",
+    printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t  reply-mode: %s (%u)",
            EXTRACT_16BITS(&lspping_com_header->version[0]),
            tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type),
            lspping_com_header->msg_type,
+           len,
            tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode),
            lspping_com_header->reply_mode);
 
@@ -446,30 +542,39 @@ lspping_print(register const u_char *pptr, register u_int len) {
         lspping_com_header->return_code == 10 ||
         lspping_com_header->return_code == 11 ||
         lspping_com_header->return_code == 12 )
-        printf("\n\t  Return Code: %s %u (%u), Return Subcode: (%u)",
+        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_code,
                lspping_com_header->return_subcode);
     else
-        printf("\n\t  Return Code: %s (%u), Return Subcode: (%u)",
+        printf("\n\t  Return Code: %s (%u)\n\t  Return Subcode: (%u)",
                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" \
-           "\n\t  Sender Timestamp %u.%us, Receiver Timestamp %u.%us",
+    printf("\n\t  Sender Handle: 0x%08x, Sequence: %u",
            EXTRACT_32BITS(lspping_com_header->sender_handle),
-           EXTRACT_32BITS(lspping_com_header->seq_number),
-           EXTRACT_32BITS(lspping_com_header->ts_sent_sec), /* FIXME: replace with ts_print() */
-           EXTRACT_32BITS(lspping_com_header->ts_sent_usec),
-           EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec), /* FIXME: replace with ts_print() */
-           EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec));
+           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);     
+    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); 
+    printf("Receiver Timestamp: ");
+    if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0))
+        ts_print(&timestamp);
+    else
+        printf("no timestamp");
 
     tptr+=sizeof(const struct lspping_common_header);
     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;
@@ -478,10 +583,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;
         }
@@ -619,13 +725,28 @@ lspping_print(register const u_char *pptr, register u_int len) {
                            bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id),
                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id),
-                           tok2str(bgp_l2vpn_encaps_values,
+                           tok2str(l2vpn_encaps_values,
                                    "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 */
+                case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD:
+                    subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \
+                        (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr;
+                    printf("\n\t      Remote PE: %s" \
+                           "\n\t      VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
+                           ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
+                           EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id),
+                           tok2str(l2vpn_encaps_values,
+                                   "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:
                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \
                         (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr;
@@ -634,10 +755,10 @@ lspping_print(register const u_char *pptr, register u_int len) {
                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
                            EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id),
-                           tok2str(bgp_l2vpn_encaps_values, /* FIXME are the L2 encaps codepoints of BGP == LDP ??? */
+                           tok2str(l2vpn_encaps_values,
                                    "unknown",
-                                   EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
-                           EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
+                                   EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
+                           EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation));
                     
                     break;
 
@@ -656,12 +777,96 @@ lspping_print(register const u_char *pptr, register u_int len) {
             }
             break;
 
+        case LSPPING_TLV_DOWNSTREAM_MAPPING:
+            /* that strange thing with the downstream map TLV is that until now
+             * we do not know if its IPv4 or IPv6 , after we found the adress-type
+             * lets recast the tlv_tptr and move on */
+
+            tlv_ptr.lspping_tlv_downstream_map_ipv4= \
+                (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
+            tlv_ptr.lspping_tlv_downstream_map_ipv6= \
+                (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
+            printf("\n\t    MTU: %u, Address-Type: %s (%u)",
+                   EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu),
+                   tok2str(lspping_tlv_downstream_addr_values,
+                           "unknown",
+                           tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type),
+                   tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type);
+
+            switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) {
+
+            case LSPPING_AFI_IPV4:
+                printf("\n\t    Downstream IP: %s" \
+                       "\n\t    Downstream Interface IP: %s",
+                       ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
+                       ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
+                tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+                tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+                break;
+#ifdef INET6
+             case LSPPING_AFI_IPV6:
+                printf("\n\t    Downstream IP: %s" \
+                       "\n\t    Downstream Interface IP: %s",
+                       ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
+                       ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
+                tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+                tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+                break;
+#endif
+            case LSPPING_AFI_UNMB:
+                printf("\n\t    Downstream IP: %s" \
+                       "\n\t    Downstream Interface Index: 0x%08x",
+                       ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
+                       EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
+                tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+                tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+                break;
+
+            default:
+                /* should not happen ! - no error message - tok2str() has barked already */
+                break;
+            }
+
+            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 */
+
+
+            tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t);
+            tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t);
+
+            /* FIXME print downstream labels */
+
+
+            tlv_hexdump=TRUE; /* dump the TLV until code complete */
+
+            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_DOWNSTREAM_MAPPING:
         case LSPPING_TLV_PAD:
         case LSPPING_TLV_ERROR_CODE:
         case LSPPING_TLV_VENDOR_PRIVATE:
@@ -673,10 +878,16 @@ lspping_print(register const u_char *pptr, register u_int len) {
         }
         /* 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(tptr+sizeof(struct lspping_tlv_header),"\n\t    ",
                                lspping_tlv_len);
 
-        tptr+=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);
     }
     return;