xref: /netbsd-src/external/bsd/tcpdump/dist/print-lspping.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
10f74e101Schristos /*
20f74e101Schristos  * Redistribution and use in source and binary forms, with or without
30f74e101Schristos  * modification, are permitted provided that: (1) source code
40f74e101Schristos  * distributions retain the above copyright notice and this paragraph
50f74e101Schristos  * in its entirety, and (2) distributions including binary code include
60f74e101Schristos  * the above copyright notice and this paragraph in its entirety in
70f74e101Schristos  * the documentation or other materials provided with the distribution.
80f74e101Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
90f74e101Schristos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
100f74e101Schristos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
110f74e101Schristos  * FOR A PARTICULAR PURPOSE.
120f74e101Schristos  *
1372c96ff3Schristos  * Original code by Hannes Gredler (hannes@gredler.at)
140f74e101Schristos  */
150f74e101Schristos 
1611b3aaa1Schristos #include <sys/cdefs.h>
170f74e101Schristos #ifndef lint
18*26ba0b50Schristos __RCSID("$NetBSD: print-lspping.c,v 1.11 2024/09/02 16:15:32 christos Exp $");
190f74e101Schristos #endif
200f74e101Schristos 
21dc860a36Sspz /* \summary: MPLS LSP PING printer */
22dc860a36Sspz 
23c74ad251Schristos /* specification: RFC 4379 */
24c74ad251Schristos 
25c74ad251Schristos #include <config.h>
260f74e101Schristos 
27c74ad251Schristos #include "netdissect-stdinc.h"
280f74e101Schristos 
29c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK
30fdccd7e4Schristos #include "netdissect.h"
310f74e101Schristos #include "extract.h"
320f74e101Schristos #include "addrtoname.h"
33c74ad251Schristos #include "ntp.h"
340f74e101Schristos 
350f74e101Schristos #include "l2vpn.h"
360f74e101Schristos #include "oui.h"
370f74e101Schristos 
38dc860a36Sspz 
390f74e101Schristos /*
400f74e101Schristos  * LSPPING common header
410f74e101Schristos  *
420f74e101Schristos  *  0                   1                   2                   3
430f74e101Schristos  *  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
440f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
450f74e101Schristos  * |         Version Number        |         Must Be Zero          |
460f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
470f74e101Schristos  * |  Message Type |   Reply mode  |  Return Code  | Return Subcode|
480f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
490f74e101Schristos  * |                        Sender's Handle                        |
500f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
510f74e101Schristos  * |                        Sequence Number                        |
520f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
530f74e101Schristos  * |                    TimeStamp Sent (seconds)                   |
540f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
550f74e101Schristos  * |                  TimeStamp Sent (microseconds)                |
560f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
570f74e101Schristos  * |                  TimeStamp Received (seconds)                 |
580f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
590f74e101Schristos  * |                TimeStamp Received (microseconds)              |
600f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
610f74e101Schristos  * |                            TLVs ...                           |
620f74e101Schristos  * .                                                               .
630f74e101Schristos  * .                                                               .
640f74e101Schristos  * .                                                               .
650f74e101Schristos  */
660f74e101Schristos 
670f74e101Schristos struct lspping_common_header {
68c74ad251Schristos     nd_uint16_t version;
69c74ad251Schristos     nd_uint16_t global_flags;
70c74ad251Schristos     nd_uint8_t  msg_type;
71c74ad251Schristos     nd_uint8_t  reply_mode;
72c74ad251Schristos     nd_uint8_t  return_code;
73c74ad251Schristos     nd_uint8_t  return_subcode;
74c74ad251Schristos     nd_uint32_t sender_handle;
75c74ad251Schristos     nd_uint32_t seq_number;
76c74ad251Schristos     struct l_fixedpt ts_sent;
77c74ad251Schristos     struct l_fixedpt ts_rcvd;
780f74e101Schristos };
790f74e101Schristos 
800f74e101Schristos #define LSPPING_VERSION            1
810f74e101Schristos 
820f74e101Schristos static const struct tok lspping_msg_type_values[] = {
830f74e101Schristos     { 1, "MPLS Echo Request"},
840f74e101Schristos     { 2, "MPLS Echo Reply"},
850f74e101Schristos     { 0, NULL}
860f74e101Schristos };
870f74e101Schristos 
880f74e101Schristos static const struct tok lspping_reply_mode_values[] = {
890f74e101Schristos     { 1, "Do not reply"},
900f74e101Schristos     { 2, "Reply via an IPv4/IPv6 UDP packet"},
910f74e101Schristos     { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
920f74e101Schristos     { 4, "Reply via application level control channel"},
930f74e101Schristos     { 0, NULL}
940f74e101Schristos };
950f74e101Schristos 
960f74e101Schristos static const struct tok lspping_return_code_values[] = {
970f74e101Schristos     {  0, "No return code or return code contained in the Error Code TLV"},
980f74e101Schristos     {  1, "Malformed echo request received"},
990f74e101Schristos     {  2, "One or more of the TLVs was not understood"},
1000f74e101Schristos     {  3, "Replying router is an egress for the FEC at stack depth"},
1010f74e101Schristos     {  4, "Replying router has no mapping for the FEC at stack depth"},
1020f74e101Schristos     {  5, "Reserved"},
1030f74e101Schristos     {  6, "Reserved"},
1040f74e101Schristos     {  7, "Reserved"},
1050f74e101Schristos     {  8, "Label switched at stack-depth"},
1060f74e101Schristos     {  9, "Label switched but no MPLS forwarding at stack-depth"},
1070f74e101Schristos     { 10, "Mapping for this FEC is not the given label at stack depth"},
1080f74e101Schristos     { 11, "No label entry at stack-depth"},
1090f74e101Schristos     { 12, "Protocol not associated with interface at FEC stack depth"},
110dc860a36Sspz     { 13, "Premature termination of ping due to label stack shrinking to a single label"},
11172c96ff3Schristos     { 0,  NULL},
1120f74e101Schristos };
1130f74e101Schristos 
1140f74e101Schristos 
1150f74e101Schristos /*
1160f74e101Schristos  * LSPPING TLV header
1170f74e101Schristos  *  0                   1                   2                   3
1180f74e101Schristos  *  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
1190f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1200f74e101Schristos  * |             Type              |            Length             |
1210f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1220f74e101Schristos  * |                             Value                             |
1230f74e101Schristos  * .                                                               .
1240f74e101Schristos  * .                                                               .
1250f74e101Schristos  * .                                                               .
1260f74e101Schristos  * |                                                               |
1270f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1280f74e101Schristos  */
1290f74e101Schristos 
1300f74e101Schristos struct lspping_tlv_header {
131c74ad251Schristos     nd_uint16_t type;
132c74ad251Schristos     nd_uint16_t length;
1330f74e101Schristos };
1340f74e101Schristos 
1350f74e101Schristos #define	LSPPING_TLV_TARGET_FEC_STACK      1
1360f74e101Schristos #define	LSPPING_TLV_DOWNSTREAM_MAPPING    2
1370f74e101Schristos #define	LSPPING_TLV_PAD                   3
138dc860a36Sspz /* not assigned                           4 */
1390f74e101Schristos #define LSPPING_TLV_VENDOR_ENTERPRISE     5
1400f74e101Schristos #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
141dc860a36Sspz /* not assigned                           6 */
1420f74e101Schristos #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
143dc860a36Sspz /* not assigned                           8 */
1440f74e101Schristos #define	LSPPING_TLV_ERROR_CODE            9
1450f74e101Schristos #define LSPPING_TLV_REPLY_TOS_BYTE        10
1460f74e101Schristos #define	LSPPING_TLV_BFD_DISCRIMINATOR     15 /* draft-ietf-bfd-mpls-02 */
1470f74e101Schristos #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
1480f74e101Schristos #define	LSPPING_TLV_VENDOR_PRIVATE        0xfc00
1490f74e101Schristos 
1500f74e101Schristos static const struct tok lspping_tlv_values[] = {
1510f74e101Schristos     { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
1520f74e101Schristos     { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
1530f74e101Schristos     { LSPPING_TLV_PAD, "Pad" },
1540f74e101Schristos     { LSPPING_TLV_ERROR_CODE, "Error Code" },
1550f74e101Schristos     { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
1560f74e101Schristos     { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
1570f74e101Schristos     { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
1580f74e101Schristos     { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
1590f74e101Schristos     { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
1600f74e101Schristos     { 0, NULL}
1610f74e101Schristos };
1620f74e101Schristos 
1630f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4       1
1640f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6       2
1650f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4      3
1660f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6      4
167dc860a36Sspz /* not assigned                                     5 */
1680f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4     6
1690f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6     7
1700f74e101Schristos #define	LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT    8
171dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9
172dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW     10
173dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW     11
174dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4       12
175dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6       13
176dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4   14
177dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6   15
178dc860a36Sspz #define	LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC        16
1790f74e101Schristos 
1800f74e101Schristos static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
1810f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
1820f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
1830f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
1840f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
1850f74e101Schristos     { 5, "Reserved"},
1860f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
1870f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
1880f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
189dc860a36Sspz     { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"},
190dc860a36Sspz     { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"},
1910f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
1920f74e101Schristos     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
1930f74e101Schristos     { 0, NULL}
1940f74e101Schristos };
1950f74e101Schristos 
1960f74e101Schristos /*
1970f74e101Schristos  *  0                   1                   2                   3
1980f74e101Schristos  *  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
1990f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2000f74e101Schristos  * |                          IPv4 prefix                          |
2010f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2020f74e101Schristos  * | Prefix Length |         Must Be Zero                          |
2030f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2040f74e101Schristos  */
2050f74e101Schristos struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
206c74ad251Schristos     nd_ipv4    prefix;
207c74ad251Schristos     nd_uint8_t prefix_len;
2080f74e101Schristos };
2090f74e101Schristos 
2100f74e101Schristos /*
2110f74e101Schristos  *  0                   1                   2                   3
2120f74e101Schristos  *  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
2130f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2140f74e101Schristos  * |                          IPv6 prefix                          |
2150f74e101Schristos  * |                          (16 octets)                          |
2160f74e101Schristos  * |                                                               |
2170f74e101Schristos  * |                                                               |
2180f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2190f74e101Schristos  * | Prefix Length |         Must Be Zero                          |
2200f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2210f74e101Schristos  */
2220f74e101Schristos struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
223c74ad251Schristos     nd_ipv6    prefix;
224c74ad251Schristos     nd_uint8_t prefix_len;
2250f74e101Schristos };
2260f74e101Schristos 
2270f74e101Schristos /*
2280f74e101Schristos  *  0                   1                   2                   3
2290f74e101Schristos  *  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
2300f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2310f74e101Schristos  * |                 IPv4 tunnel end point address                 |
2320f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2330f74e101Schristos  * |          Must Be Zero         |     Tunnel ID                 |
2340f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2350f74e101Schristos  * |                       Extended Tunnel ID                      |
2360f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2370f74e101Schristos  * |                   IPv4 tunnel sender address                  |
2380f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2390f74e101Schristos  * |          Must Be Zero         |            LSP ID             |
2400f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2410f74e101Schristos  */
2420f74e101Schristos struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
243c74ad251Schristos     nd_ipv4     tunnel_endpoint;
244c74ad251Schristos     nd_byte     res[2];
245c74ad251Schristos     nd_uint16_t tunnel_id;
246c74ad251Schristos     nd_ipv4     extended_tunnel_id;
247c74ad251Schristos     nd_ipv4     tunnel_sender;
248c74ad251Schristos     nd_byte     res2[2];
249c74ad251Schristos     nd_uint16_t lsp_id;
2500f74e101Schristos };
2510f74e101Schristos 
2520f74e101Schristos /*
2530f74e101Schristos  *  0                   1                   2                   3
2540f74e101Schristos  *  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
2550f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2560f74e101Schristos  * |                 IPv6 tunnel end point address                 |
2570f74e101Schristos  * |                                                               |
2580f74e101Schristos  * |                                                               |
2590f74e101Schristos  * |                                                               |
2600f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2610f74e101Schristos  * |          Must Be Zero         |          Tunnel ID            |
2620f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2630f74e101Schristos  * |                       Extended Tunnel ID                      |
2640f74e101Schristos  * |                                                               |
2650f74e101Schristos  * |                                                               |
2660f74e101Schristos  * |                                                               |
2670f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2680f74e101Schristos  * |                   IPv6 tunnel sender address                  |
2690f74e101Schristos  * |                                                               |
2700f74e101Schristos  * |                                                               |
2710f74e101Schristos  * |                                                               |
2720f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2730f74e101Schristos  * |          Must Be Zero         |            LSP ID             |
2740f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2750f74e101Schristos  */
2760f74e101Schristos struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
277c74ad251Schristos     nd_ipv6     tunnel_endpoint;
278c74ad251Schristos     nd_byte     res[2];
279c74ad251Schristos     nd_uint16_t tunnel_id;
280c74ad251Schristos     nd_ipv6     extended_tunnel_id;
281c74ad251Schristos     nd_ipv6     tunnel_sender;
282c74ad251Schristos     nd_byte     res2[2];
283c74ad251Schristos     nd_uint16_t lsp_id;
2840f74e101Schristos };
2850f74e101Schristos 
2860f74e101Schristos /*
2870f74e101Schristos  *  0                   1                   2                   3
2880f74e101Schristos  *  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
2890f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2900f74e101Schristos  * |                      Route Distinguisher                      |
2910f74e101Schristos  * |                          (8 octets)                           |
2920f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2930f74e101Schristos  * |                         IPv4 prefix                           |
2940f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2950f74e101Schristos  * | Prefix Length |                 Must Be Zero                  |
2960f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2970f74e101Schristos  */
2980f74e101Schristos struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
299c74ad251Schristos     nd_byte    rd[8];
300c74ad251Schristos     nd_ipv4    prefix;
301c74ad251Schristos     nd_uint8_t prefix_len;
3020f74e101Schristos };
3030f74e101Schristos 
3040f74e101Schristos /*
3050f74e101Schristos  *  0                   1                   2                   3
3060f74e101Schristos  *  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
3070f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3080f74e101Schristos  * |                      Route Distinguisher                      |
3090f74e101Schristos  * |                          (8 octets)                           |
3100f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3110f74e101Schristos  * |                          IPv6 prefix                          |
3120f74e101Schristos  * |                          (16 octets)                          |
3130f74e101Schristos  * |                                                               |
3140f74e101Schristos  * |                                                               |
3150f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3160f74e101Schristos  * | Prefix Length |                 Must Be Zero                  |
3170f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3180f74e101Schristos  */
3190f74e101Schristos struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
320c74ad251Schristos     nd_byte    rd[8];
321c74ad251Schristos     nd_ipv6    prefix;
322c74ad251Schristos     nd_uint8_t prefix_len;
3230f74e101Schristos };
3240f74e101Schristos 
3250f74e101Schristos /*
3260f74e101Schristos  *  0                   1                   2                   3
3270f74e101Schristos  *  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
3280f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3290f74e101Schristos  * |                      Route Distinguisher                      |
3300f74e101Schristos  * |                          (8 octets)                           |
3310f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
332dc860a36Sspz  * |         Sender's VE ID        |       Receiver's VE ID        |
3330f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3340f74e101Schristos  * |      Encapsulation Type       |         Must Be Zero          |
3350f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3360f74e101Schristos  *  0                   1                   2                   3
3370f74e101Schristos  */
3380f74e101Schristos struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
339c74ad251Schristos     nd_byte     rd[8];
340c74ad251Schristos     nd_uint16_t sender_ve_id;
341c74ad251Schristos     nd_uint16_t receiver_ve_id;
342c74ad251Schristos     nd_uint16_t encapsulation;
3430f74e101Schristos };
3440f74e101Schristos 
3450f74e101Schristos /*
3460f74e101Schristos  *  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
3470f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3480f74e101Schristos  * |                      Remote PE Address                        |
3490f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
350dc860a36Sspz  * |                             PW ID                             |
3510f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
352dc860a36Sspz  * |            PW Type            |          Must Be Zero         |
3530f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3540f74e101Schristos  */
355dc860a36Sspz struct lspping_tlv_targetfec_subtlv_fec_128_pw_old {
356c74ad251Schristos     nd_ipv4     remote_pe_address;
357c74ad251Schristos     nd_uint32_t pw_id;
358c74ad251Schristos     nd_uint16_t pw_type;
3590f74e101Schristos };
3600f74e101Schristos 
3610f74e101Schristos /*
3620f74e101Schristos  *  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
3630f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3640f74e101Schristos  * |                     Sender's PE Address                       |
3650f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3660f74e101Schristos  * |                      Remote PE Address                        |
3670f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
368dc860a36Sspz  * |                             PW ID                             |
3690f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
370dc860a36Sspz  * |            PW Type            |          Must Be Zero         |
3710f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3720f74e101Schristos  */
373dc860a36Sspz struct lspping_tlv_targetfec_subtlv_fec_128_pw {
374c74ad251Schristos     nd_ipv4     sender_pe_address;
375c74ad251Schristos     nd_ipv4     remote_pe_address;
376c74ad251Schristos     nd_uint32_t pw_id;
377c74ad251Schristos     nd_uint16_t pw_type;
378dc860a36Sspz };
379dc860a36Sspz 
380dc860a36Sspz /*
381dc860a36Sspz  * 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
382dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
383dc860a36Sspz  * |                         IPv4 prefix                           |
384dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
385dc860a36Sspz  * | Prefix Length |                 Must Be Zero                  |
386dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
387dc860a36Sspz  */
388dc860a36Sspz struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
389c74ad251Schristos     nd_ipv4    prefix;
390c74ad251Schristos     nd_uint8_t prefix_len;
391dc860a36Sspz };
392dc860a36Sspz 
393dc860a36Sspz /*
394dc860a36Sspz  * 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
395dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
396dc860a36Sspz  * |                          IPv6 prefix                          |
397dc860a36Sspz  * |                          (16 octets)                          |
398dc860a36Sspz  * |                                                               |
399dc860a36Sspz  * |                                                               |
400dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
401dc860a36Sspz  * | Prefix Length |                 Must Be Zero                  |
402dc860a36Sspz  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
403dc860a36Sspz  */
404dc860a36Sspz struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
405c74ad251Schristos     nd_ipv6    prefix;
406c74ad251Schristos     nd_uint8_t prefix_len;
4070f74e101Schristos };
4080f74e101Schristos 
4090f74e101Schristos /*
4100f74e101Schristos  *  0                   1                   2                   3
4110f74e101Schristos  *  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
4120f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4130f74e101Schristos  * |               MTU             | Address Type  |  Resvd (SBZ)  |
4140f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4150f74e101Schristos  * |             Downstream IP Address (4 or 16 octets)            |
4160f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4170f74e101Schristos  * |         Downstream Interface Address (4 or 16 octets)         |
4180f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
419dc860a36Sspz  * | Multipath Type| Depth Limit   |        Multipath Length       |
4200f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4210f74e101Schristos  * .                                                               .
4220f74e101Schristos  * .                     (Multipath Information)                   .
4230f74e101Schristos  * .                                                               .
4240f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4250f74e101Schristos  * |               Downstream Label                |    Protocol   |
4260f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4270f74e101Schristos  * .                                                               .
4280f74e101Schristos  * .                                                               .
4290f74e101Schristos  * .                                                               .
4300f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4310f74e101Schristos  * |               Downstream Label                |    Protocol   |
4320f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4330f74e101Schristos  */
434dc860a36Sspz /* Enough to get the address type */
435dc860a36Sspz struct lspping_tlv_downstream_map_t {
436c74ad251Schristos     nd_uint16_t mtu;
437c74ad251Schristos     nd_uint8_t  address_type;
438c74ad251Schristos     nd_uint8_t  ds_flags;
439dc860a36Sspz };
440dc860a36Sspz 
4410f74e101Schristos struct lspping_tlv_downstream_map_ipv4_t {
442c74ad251Schristos     nd_uint16_t mtu;
443c74ad251Schristos     nd_uint8_t  address_type;
444c74ad251Schristos     nd_uint8_t  ds_flags;
445c74ad251Schristos     nd_ipv4     downstream_ip;
446c74ad251Schristos     nd_ipv4     downstream_interface;
447dc860a36Sspz };
448dc860a36Sspz 
449dc860a36Sspz struct lspping_tlv_downstream_map_ipv4_unmb_t {
450c74ad251Schristos     nd_uint16_t mtu;
451c74ad251Schristos     nd_uint8_t  address_type;
452c74ad251Schristos     nd_uint8_t  ds_flags;
453c74ad251Schristos     nd_ipv4     downstream_ip;
454c74ad251Schristos     nd_uint32_t downstream_interface;
4550f74e101Schristos };
4560f74e101Schristos 
4570f74e101Schristos struct lspping_tlv_downstream_map_ipv6_t {
458c74ad251Schristos     nd_uint16_t mtu;
459c74ad251Schristos     nd_uint8_t  address_type;
460c74ad251Schristos     nd_uint8_t  ds_flags;
461c74ad251Schristos     nd_ipv6     downstream_ip;
462c74ad251Schristos     nd_ipv6     downstream_interface;
4630f74e101Schristos };
4640f74e101Schristos 
465dc860a36Sspz struct lspping_tlv_downstream_map_ipv6_unmb_t {
466c74ad251Schristos     nd_uint16_t mtu;
467c74ad251Schristos     nd_uint8_t  address_type;
468c74ad251Schristos     nd_uint8_t  ds_flags;
469c74ad251Schristos     nd_ipv6     downstream_ip;
470c74ad251Schristos     nd_uint32_t downstream_interface;
471dc860a36Sspz };
472dc860a36Sspz 
4730f74e101Schristos struct lspping_tlv_downstream_map_info_t {
474c74ad251Schristos     nd_uint8_t  multipath_type;
475c74ad251Schristos     nd_uint8_t  depth_limit;
476c74ad251Schristos     nd_uint16_t multipath_length;
4770f74e101Schristos };
4780f74e101Schristos 
4790f74e101Schristos #define LSPPING_AFI_IPV4      1
480dc860a36Sspz #define LSPPING_AFI_IPV4_UNMB 2
4810f74e101Schristos #define LSPPING_AFI_IPV6      3
482dc860a36Sspz #define LSPPING_AFI_IPV6_UNMB 4
4830f74e101Schristos 
4840f74e101Schristos static const struct tok lspping_tlv_downstream_addr_values[] = {
4850f74e101Schristos     { LSPPING_AFI_IPV4,      "IPv4"},
486dc860a36Sspz     { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"},
4870f74e101Schristos     { LSPPING_AFI_IPV6,      "IPv6"},
488dc860a36Sspz     { LSPPING_AFI_IPV6_UNMB, "IPv6"},
4890f74e101Schristos     { 0, NULL}
4900f74e101Schristos };
4910f74e101Schristos 
4920f74e101Schristos void
493b3a00663Schristos lspping_print(netdissect_options *ndo,
494c74ad251Schristos               const u_char *pptr, u_int len)
495ba2ff121Schristos {
4960f74e101Schristos     const struct lspping_common_header *lspping_com_header;
4970f74e101Schristos     const struct lspping_tlv_header *lspping_tlv_header;
4980f74e101Schristos     const struct lspping_tlv_header *lspping_subtlv_header;
4990f74e101Schristos     const u_char *tptr,*tlv_tptr,*subtlv_tptr;
500c74ad251Schristos     u_int return_code, return_subcode;
501dc860a36Sspz     u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
5020f74e101Schristos     int tlv_hexdump,subtlv_hexdump;
503dc860a36Sspz     u_int lspping_subtlv_len,lspping_subtlv_type;
504c74ad251Schristos     uint32_t int_part, fraction;
505c74ad251Schristos     u_int address_type;
5060f74e101Schristos 
5070f74e101Schristos     union {
508dc860a36Sspz         const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map;
5090f74e101Schristos         const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
510dc860a36Sspz         const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb;
5110f74e101Schristos         const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
512dc860a36Sspz         const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb;
5130f74e101Schristos         const struct lspping_tlv_downstream_map_info_t  *lspping_tlv_downstream_map_info;
5140f74e101Schristos     } tlv_ptr;
5150f74e101Schristos 
5160f74e101Schristos     union {
5170f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
5180f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
5190f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
5200f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
5210f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
5220f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
5230f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
524dc860a36Sspz         const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
525dc860a36Sspz         const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
5260f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
5270f74e101Schristos         const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
5280f74e101Schristos     } subtlv_ptr;
5290f74e101Schristos 
530c74ad251Schristos     ndo->ndo_protocol = "lspping";
5310f74e101Schristos     tptr=pptr;
5320f74e101Schristos     lspping_com_header = (const struct lspping_common_header *)pptr;
533c74ad251Schristos     if (len < sizeof(struct lspping_common_header))
534dc860a36Sspz         goto tooshort;
535c74ad251Schristos     ND_TCHECK_SIZE(lspping_com_header);
5360f74e101Schristos 
5370f74e101Schristos     /*
5380f74e101Schristos      * Sanity checking of the header.
5390f74e101Schristos      */
540c74ad251Schristos     if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) {
541c74ad251Schristos 	ND_PRINT("LSP-PING version %u packet not supported",
542c74ad251Schristos                GET_BE_U_2(lspping_com_header->version));
5430f74e101Schristos 	return;
5440f74e101Schristos     }
5450f74e101Schristos 
5460f74e101Schristos     /* in non-verbose mode just lets print the basic Message Type*/
547b3a00663Schristos     if (ndo->ndo_vflag < 1) {
548c74ad251Schristos         ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u",
549c74ad251Schristos                GET_BE_U_2(lspping_com_header->version),
550c74ad251Schristos                tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)),
551c74ad251Schristos                GET_BE_U_4(lspping_com_header->seq_number),
552c74ad251Schristos                len);
5530f74e101Schristos         return;
5540f74e101Schristos     }
5550f74e101Schristos 
5560f74e101Schristos     /* ok they seem to want to know everything - lets fully decode it */
5570f74e101Schristos 
5580f74e101Schristos     tlen=len;
5590f74e101Schristos 
560c74ad251Schristos     ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t  reply-mode: %s (%u)",
561c74ad251Schristos            GET_BE_U_2(lspping_com_header->version),
562c74ad251Schristos            tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)),
563c74ad251Schristos            GET_U_1(lspping_com_header->msg_type),
5640f74e101Schristos            len,
565c74ad251Schristos            tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)),
566c74ad251Schristos            GET_U_1(lspping_com_header->reply_mode));
5670f74e101Schristos 
5680f74e101Schristos     /*
5690f74e101Schristos      *  the following return codes require that the subcode is attached
5700f74e101Schristos      *  at the end of the translated token output
5710f74e101Schristos      */
572c74ad251Schristos     return_code = GET_U_1(lspping_com_header->return_code);
573c74ad251Schristos     return_subcode = GET_U_1(lspping_com_header->return_subcode);
574c74ad251Schristos     if (return_code == 3 ||
575c74ad251Schristos         return_code == 4 ||
576c74ad251Schristos         return_code == 8 ||
577c74ad251Schristos         return_code == 10 ||
578c74ad251Schristos         return_code == 11 ||
579c74ad251Schristos         return_code == 12 )
580c74ad251Schristos         ND_PRINT("\n\t  Return Code: %s %u (%u)\n\t  Return Subcode: (%u)",
581c74ad251Schristos                tok2str(lspping_return_code_values, "unknown",return_code),
582c74ad251Schristos                return_subcode,
583c74ad251Schristos                return_code,
584c74ad251Schristos                return_subcode);
5850f74e101Schristos     else
586c74ad251Schristos         ND_PRINT("\n\t  Return Code: %s (%u)\n\t  Return Subcode: (%u)",
587c74ad251Schristos                tok2str(lspping_return_code_values, "unknown",return_code),
588c74ad251Schristos                return_code,
589c74ad251Schristos                return_subcode);
5900f74e101Schristos 
591c74ad251Schristos     ND_PRINT("\n\t  Sender Handle: 0x%08x, Sequence: %u",
592c74ad251Schristos            GET_BE_U_4(lspping_com_header->sender_handle),
593c74ad251Schristos            GET_BE_U_4(lspping_com_header->seq_number));
5940f74e101Schristos 
595c74ad251Schristos     ND_PRINT("\n\t  Sender Timestamp: ");
596c74ad251Schristos     p_ntp_time(ndo, &lspping_com_header->ts_sent);
597c74ad251Schristos     ND_PRINT(" ");
5980f74e101Schristos 
599c74ad251Schristos     int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part);
600c74ad251Schristos     fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction);
601c74ad251Schristos     ND_PRINT("Receiver Timestamp: ");
602c74ad251Schristos     if (! (int_part == 0 && fraction == 0))
603c74ad251Schristos         p_ntp_time(ndo, &lspping_com_header->ts_rcvd);
6040f74e101Schristos     else
605c74ad251Schristos         ND_PRINT("no timestamp");
6060f74e101Schristos 
607c74ad251Schristos     tptr+=sizeof(struct lspping_common_header);
608c74ad251Schristos     tlen-=sizeof(struct lspping_common_header);
6090f74e101Schristos 
610dc860a36Sspz     while (tlen != 0) {
611dc860a36Sspz         /* Does the TLV go past the end of the packet? */
612dc860a36Sspz         if (tlen < sizeof(struct lspping_tlv_header))
613dc860a36Sspz             goto tooshort;
6140f74e101Schristos 
6150f74e101Schristos         lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
616c74ad251Schristos         lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type);
617c74ad251Schristos         lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length);
6180f74e101Schristos 
619c74ad251Schristos         ND_PRINT("\n\t  %s TLV (%u), length: %u",
6200f74e101Schristos                tok2str(lspping_tlv_values,
6210f74e101Schristos                        "Unknown",
6220f74e101Schristos                        lspping_tlv_type),
6230f74e101Schristos                lspping_tlv_type,
624c74ad251Schristos                lspping_tlv_len);
6250f74e101Schristos 
626dc860a36Sspz         /* some little sanity checking */
627dc860a36Sspz         if (lspping_tlv_len == 0) {
628dc860a36Sspz             tptr+=sizeof(struct lspping_tlv_header);
629dc860a36Sspz             tlen-=sizeof(struct lspping_tlv_header);
630dc860a36Sspz             continue;    /* no value to dissect */
631dc860a36Sspz         }
632dc860a36Sspz 
6330f74e101Schristos         tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
6340f74e101Schristos         tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
6350f74e101Schristos 
636dc860a36Sspz         /* Does the TLV go past the end of the packet? */
637dc860a36Sspz         if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
638dc860a36Sspz             goto tooshort;
6390f74e101Schristos         /* did we capture enough for fully decoding the tlv ? */
640c74ad251Schristos         ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len);
6410f74e101Schristos         tlv_hexdump=FALSE;
6420f74e101Schristos 
6430f74e101Schristos         switch(lspping_tlv_type) {
6440f74e101Schristos         case LSPPING_TLV_TARGET_FEC_STACK:
645dc860a36Sspz             while (tlv_tlen != 0) {
646dc860a36Sspz                 /* Does the subTLV header go past the end of the TLV? */
647dc860a36Sspz                 if (tlv_tlen < sizeof(struct lspping_tlv_header)) {
648c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
649dc860a36Sspz                     tlv_hexdump = TRUE;
650dc860a36Sspz                     goto tlv_tooshort;
651dc860a36Sspz                 }
6520f74e101Schristos                 subtlv_hexdump=FALSE;
6530f74e101Schristos 
6540f74e101Schristos                 lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
655c74ad251Schristos                 lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type);
656c74ad251Schristos                 lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length);
6570f74e101Schristos                 subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
6580f74e101Schristos 
659dc860a36Sspz                 /* Does the subTLV go past the end of the TLV? */
660dc860a36Sspz                 if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
661c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
662dc860a36Sspz                     tlv_hexdump = TRUE;
663dc860a36Sspz                     goto tlv_tooshort;
664dc860a36Sspz                 }
665dc860a36Sspz 
666dc860a36Sspz                 /* Did we capture enough for fully decoding the subTLV? */
667c74ad251Schristos                 ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len);
6680f74e101Schristos 
669c74ad251Schristos                 ND_PRINT("\n\t    %s subTLV (%u), length: %u",
6700f74e101Schristos                        tok2str(lspping_tlvtargetfec_subtlv_values,
6710f74e101Schristos                                "Unknown",
6720f74e101Schristos                                lspping_subtlv_type),
6730f74e101Schristos                        lspping_subtlv_type,
674c74ad251Schristos                        lspping_subtlv_len);
6750f74e101Schristos 
6760f74e101Schristos                 switch(lspping_subtlv_type) {
6770f74e101Schristos 
6780f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
679dc860a36Sspz                     /* Is the subTLV length correct? */
680dc860a36Sspz                     if (lspping_subtlv_len != 5) {
681c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 5");
682dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
683dc860a36Sspz                     } else {
684c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 =
6850f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
686c74ad251Schristos                         ND_PRINT("\n\t      %s/%u",
687c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
688c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len));
689dc860a36Sspz                     }
6900f74e101Schristos                     break;
6910f74e101Schristos 
6920f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
693dc860a36Sspz                     /* Is the subTLV length correct? */
694dc860a36Sspz                     if (lspping_subtlv_len != 17) {
695c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 17");
696dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
697dc860a36Sspz                     } else {
698c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 =
6990f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
700c74ad251Schristos                         ND_PRINT("\n\t      %s/%u",
701c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
702c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
703dc860a36Sspz                     }
7040f74e101Schristos                     break;
7050f74e101Schristos 
7060f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
707dc860a36Sspz                     /* Is the subTLV length correct? */
708dc860a36Sspz                     if (lspping_subtlv_len != 5) {
709c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 5");
710dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
711dc860a36Sspz                     } else {
712c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 =
7130f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
714c74ad251Schristos                         ND_PRINT("\n\t      %s/%u",
715c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
716c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len));
717dc860a36Sspz                     }
7180f74e101Schristos                     break;
7190f74e101Schristos 
7200f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
721dc860a36Sspz                     /* Is the subTLV length correct? */
722dc860a36Sspz                     if (lspping_subtlv_len != 17) {
723c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 17");
724dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
725dc860a36Sspz                     } else {
726c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 =
7270f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
728c74ad251Schristos                         ND_PRINT("\n\t      %s/%u",
729c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
730c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len));
731dc860a36Sspz                     }
7320f74e101Schristos                     break;
7330f74e101Schristos 
7340f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
735dc860a36Sspz                     /* Is the subTLV length correct? */
736dc860a36Sspz                     if (lspping_subtlv_len != 20) {
737c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 20");
738dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
739dc860a36Sspz                     } else {
740c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 =
7410f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
742c74ad251Schristos                         ND_PRINT("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
7430f74e101Schristos                                "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
744c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
745c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
746c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
747c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
748c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
749dc860a36Sspz                     }
7500f74e101Schristos                     break;
7510f74e101Schristos 
7520f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
753dc860a36Sspz                     /* Is the subTLV length correct? */
754dc860a36Sspz                     if (lspping_subtlv_len != 56) {
755c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 56");
756dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
757dc860a36Sspz                     } else {
758c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 =
7590f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
760c74ad251Schristos                         ND_PRINT("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
7610f74e101Schristos                                "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
762c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
763c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
764c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
765c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
766c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
767dc860a36Sspz                     }
7680f74e101Schristos                     break;
7690f74e101Schristos 
7700f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
771dc860a36Sspz                     /* Is the subTLV length correct? */
772dc860a36Sspz                     if (lspping_subtlv_len != 13) {
773c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 13");
774dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
775dc860a36Sspz                     } else {
776c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 =
7770f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
778c74ad251Schristos                         ND_PRINT("\n\t      RD: %s, %s/%u",
779b3a00663Schristos                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
780c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
781c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
782dc860a36Sspz                     }
7830f74e101Schristos                     break;
7840f74e101Schristos 
7850f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
786dc860a36Sspz                     /* Is the subTLV length correct? */
787dc860a36Sspz                     if (lspping_subtlv_len != 25) {
788c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 25");
789dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
790dc860a36Sspz                     } else {
791c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 =
7920f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
793c74ad251Schristos                         ND_PRINT("\n\t      RD: %s, %s/%u",
794b3a00663Schristos                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
795c74ad251Schristos                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
796c74ad251Schristos                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
797dc860a36Sspz                     }
7980f74e101Schristos                     break;
7990f74e101Schristos 
8000f74e101Schristos                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
801dc860a36Sspz                     /* Is the subTLV length correct? */
802dc860a36Sspz                     if (lspping_subtlv_len != 14) {
803c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 14");
804dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
805dc860a36Sspz                     } else {
806c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt =
8070f74e101Schristos                             (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
808c74ad251Schristos                         ND_PRINT("\n\t      RD: %s, Sender VE ID: %u, Receiver VE ID: %u"
8090f74e101Schristos                                "\n\t      Encapsulation Type: %s (%u)",
810b3a00663Schristos                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
811c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id),
812c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id),
813dc860a36Sspz                                tok2str(mpls_pw_types_values,
8140f74e101Schristos                                        "unknown",
815c74ad251Schristos                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
816c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
817dc860a36Sspz                     }
8180f74e101Schristos                     break;
8190f74e101Schristos 
8200f74e101Schristos                     /* the old L2VPN VCID subTLV does not have support for the sender field */
821dc860a36Sspz                 case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD:
822dc860a36Sspz                     /* Is the subTLV length correct? */
823dc860a36Sspz                     if (lspping_subtlv_len != 10) {
824c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 10");
825dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
826dc860a36Sspz                     } else {
827c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old =
828dc860a36Sspz                             (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr;
829c74ad251Schristos                         ND_PRINT("\n\t      Remote PE: %s"
830dc860a36Sspz                                "\n\t      PW ID: 0x%08x, PW Type: %s (%u)",
831c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
832c74ad251Schristos                                GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id),
833dc860a36Sspz                                tok2str(mpls_pw_types_values,
8340f74e101Schristos                                        "unknown",
835c74ad251Schristos                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)),
836c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type));
837dc860a36Sspz                     }
8380f74e101Schristos                     break;
8390f74e101Schristos 
840dc860a36Sspz                 case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW:
841dc860a36Sspz                     /* Is the subTLV length correct? */
842dc860a36Sspz                     if (lspping_subtlv_len != 14) {
843c74ad251Schristos                         ND_PRINT("\n\t      invalid subTLV length, should be 14");
844dc860a36Sspz                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
845dc860a36Sspz                     } else {
846c74ad251Schristos                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid =
847dc860a36Sspz                             (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr;
848c74ad251Schristos                         ND_PRINT("\n\t      Sender PE: %s, Remote PE: %s"
849dc860a36Sspz                                "\n\t      PW ID: 0x%08x, PW Type: %s (%u)",
850c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
851c74ad251Schristos                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
852c74ad251Schristos                                GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id),
853dc860a36Sspz                                tok2str(mpls_pw_types_values,
8540f74e101Schristos                                        "unknown",
855c74ad251Schristos                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)),
856c74ad251Schristos                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type));
857dc860a36Sspz                     }
8580f74e101Schristos                     break;
8590f74e101Schristos 
8600f74e101Schristos                 default:
8610f74e101Schristos                     subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
8620f74e101Schristos                     break;
8630f74e101Schristos                 }
8640f74e101Schristos                 /* do we want to see an additionally subtlv hexdump ? */
865b3a00663Schristos                 if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
866c74ad251Schristos                     print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header),
8670f74e101Schristos                                        "\n\t      ",
8680f74e101Schristos                                        lspping_subtlv_len);
8690f74e101Schristos 
870dc860a36Sspz                 /* All subTLVs are aligned to four octet boundary */
871dc860a36Sspz                 if (lspping_subtlv_len % 4) {
872dc860a36Sspz                     lspping_subtlv_len += 4 - (lspping_subtlv_len % 4);
873dc860a36Sspz                     /* Does the subTLV, including padding, go past the end of the TLV? */
874dc860a36Sspz                     if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
875c74ad251Schristos                         ND_PRINT("\n\t\t TLV is too short");
876dc860a36Sspz                         return;
877dc860a36Sspz                     }
878dc860a36Sspz                 }
8790f74e101Schristos                 tlv_tptr+=lspping_subtlv_len;
8800f74e101Schristos                 tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
8810f74e101Schristos             }
8820f74e101Schristos             break;
8830f74e101Schristos 
8840f74e101Schristos         case LSPPING_TLV_DOWNSTREAM_MAPPING:
885dc860a36Sspz             /* Does the header go past the end of the TLV? */
886dc860a36Sspz             if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
887c74ad251Schristos                 ND_PRINT("\n\t      TLV is too short");
888dc860a36Sspz                 tlv_hexdump = TRUE;
889dc860a36Sspz                 goto tlv_tooshort;
890dc860a36Sspz             }
891dc860a36Sspz             /* Did we capture enough to get the address family? */
892c74ad251Schristos             ND_TCHECK_LEN(tlv_tptr,
893c74ad251Schristos                           sizeof(struct lspping_tlv_downstream_map_t));
894dc860a36Sspz 
895c74ad251Schristos             tlv_ptr.lspping_tlv_downstream_map=
896dc860a36Sspz                 (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
897dc860a36Sspz 
8980f74e101Schristos             /* that strange thing with the downstream map TLV is that until now
899dc860a36Sspz              * we do not know if its IPv4 or IPv6 or is unnumbered; after
900dc860a36Sspz              * we find the address-type, we recast the tlv_tptr and move on. */
901dc860a36Sspz 
902c74ad251Schristos             address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type);
903c74ad251Schristos             ND_PRINT("\n\t    MTU: %u, Address-Type: %s (%u)",
904c74ad251Schristos                    GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu),
905dc860a36Sspz                    tok2str(lspping_tlv_downstream_addr_values,
906dc860a36Sspz                            "unknown",
907c74ad251Schristos                            address_type),
908c74ad251Schristos                    address_type);
909dc860a36Sspz 
910c74ad251Schristos             switch(address_type) {
911dc860a36Sspz 
912dc860a36Sspz             case LSPPING_AFI_IPV4:
913dc860a36Sspz                 /* Does the data go past the end of the TLV? */
914dc860a36Sspz                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
915c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
916dc860a36Sspz                     tlv_hexdump = TRUE;
917dc860a36Sspz                     goto tlv_tooshort;
918dc860a36Sspz                 }
919dc860a36Sspz                 /* Did we capture enough for this part of the TLV? */
920c74ad251Schristos                 ND_TCHECK_LEN(tlv_tptr,
921c74ad251Schristos                               sizeof(struct lspping_tlv_downstream_map_ipv4_t));
9220f74e101Schristos 
923c74ad251Schristos                 tlv_ptr.lspping_tlv_downstream_map_ipv4=
9240f74e101Schristos                     (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
925c74ad251Schristos                 ND_PRINT("\n\t    Downstream IP: %s"
9260f74e101Schristos                        "\n\t    Downstream Interface IP: %s",
927c74ad251Schristos                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
928c74ad251Schristos                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
9290f74e101Schristos                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
9300f74e101Schristos                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
9310f74e101Schristos                 break;
932dc860a36Sspz             case LSPPING_AFI_IPV4_UNMB:
933dc860a36Sspz                 /* Does the data go past the end of the TLV? */
934dc860a36Sspz                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
935c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
936dc860a36Sspz                     tlv_hexdump = TRUE;
937dc860a36Sspz                     goto tlv_tooshort;
938dc860a36Sspz                 }
939dc860a36Sspz                 /* Did we capture enough for this part of the TLV? */
940c74ad251Schristos                 ND_TCHECK_LEN(tlv_tptr,
941c74ad251Schristos                               sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
942dc860a36Sspz 
943c74ad251Schristos                 tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb=
944dc860a36Sspz                     (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
945c74ad251Schristos                 ND_PRINT("\n\t    Downstream IP: %s"
946dc860a36Sspz                        "\n\t    Downstream Interface Index: 0x%08x",
947c74ad251Schristos                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
948c74ad251Schristos                        GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface));
949dc860a36Sspz                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
950dc860a36Sspz                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
951dc860a36Sspz                 break;
9520f74e101Schristos             case LSPPING_AFI_IPV6:
953dc860a36Sspz                 /* Does the data go past the end of the TLV? */
954dc860a36Sspz                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
955c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
956dc860a36Sspz                     tlv_hexdump = TRUE;
957dc860a36Sspz                     goto tlv_tooshort;
958dc860a36Sspz                 }
959dc860a36Sspz                 /* Did we capture enough for this part of the TLV? */
960c74ad251Schristos                 ND_TCHECK_LEN(tlv_tptr,
961c74ad251Schristos                               sizeof(struct lspping_tlv_downstream_map_ipv6_t));
962dc860a36Sspz 
963c74ad251Schristos                 tlv_ptr.lspping_tlv_downstream_map_ipv6=
964dc860a36Sspz                     (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
965c74ad251Schristos                 ND_PRINT("\n\t    Downstream IP: %s"
9660f74e101Schristos                        "\n\t    Downstream Interface IP: %s",
967c74ad251Schristos                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
968c74ad251Schristos                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
9690f74e101Schristos                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
9700f74e101Schristos                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
9710f74e101Schristos                 break;
972dc860a36Sspz              case LSPPING_AFI_IPV6_UNMB:
973dc860a36Sspz                 /* Does the data go past the end of the TLV? */
974dc860a36Sspz                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
975c74ad251Schristos                     ND_PRINT("\n\t      TLV is too short");
976dc860a36Sspz                     tlv_hexdump = TRUE;
977dc860a36Sspz                     goto tlv_tooshort;
978dc860a36Sspz                 }
979dc860a36Sspz                 /* Did we capture enough for this part of the TLV? */
980c74ad251Schristos                 ND_TCHECK_LEN(tlv_tptr,
981c74ad251Schristos                               sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
982dc860a36Sspz 
983c74ad251Schristos                 tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb=
984dc860a36Sspz                    (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
985c74ad251Schristos                 ND_PRINT("\n\t    Downstream IP: %s"
9860f74e101Schristos                        "\n\t    Downstream Interface Index: 0x%08x",
987c74ad251Schristos                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
988c74ad251Schristos                        GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface));
989dc860a36Sspz                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
990dc860a36Sspz                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
9910f74e101Schristos                 break;
9920f74e101Schristos 
9930f74e101Schristos             default:
9940f74e101Schristos                 /* should not happen ! - no error message - tok2str() has barked already */
9950f74e101Schristos                 break;
9960f74e101Schristos             }
9970f74e101Schristos 
998dc860a36Sspz             /* Does the data go past the end of the TLV? */
999dc860a36Sspz             if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
1000c74ad251Schristos                 ND_PRINT("\n\t      TLV is too short");
1001dc860a36Sspz                 tlv_hexdump = TRUE;
1002dc860a36Sspz                 goto tlv_tooshort;
1003dc860a36Sspz             }
1004dc860a36Sspz             /* Did we capture enough for this part of the TLV? */
1005c74ad251Schristos             ND_TCHECK_LEN(tlv_tptr,
1006c74ad251Schristos                           sizeof(struct lspping_tlv_downstream_map_info_t));
1007dc860a36Sspz 
1008c74ad251Schristos             tlv_ptr.lspping_tlv_downstream_map_info=
10090f74e101Schristos                 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
10100f74e101Schristos 
10110f74e101Schristos             /* FIXME add hash-key type, depth limit, multipath processing */
10120f74e101Schristos 
10130f74e101Schristos             /* FIXME print downstream labels */
10140f74e101Schristos 
10150f74e101Schristos             tlv_hexdump=TRUE; /* dump the TLV until code complete */
10160f74e101Schristos 
10170f74e101Schristos             break;
10180f74e101Schristos 
10190f74e101Schristos         case LSPPING_TLV_BFD_DISCRIMINATOR:
1020dc860a36Sspz             if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
1021c74ad251Schristos                 ND_PRINT("\n\t      TLV is too short");
1022dc860a36Sspz                 tlv_hexdump = TRUE;
1023dc860a36Sspz                 goto tlv_tooshort;
1024dc860a36Sspz             } else {
1025c74ad251Schristos                 ND_PRINT("\n\t    BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr));
1026dc860a36Sspz             }
10270f74e101Schristos             break;
10280f74e101Schristos 
10290f74e101Schristos         case  LSPPING_TLV_VENDOR_ENTERPRISE:
10300f74e101Schristos         {
1031b3a00663Schristos             uint32_t vendor_id;
10320f74e101Schristos 
1033dc860a36Sspz             if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
1034c74ad251Schristos                 ND_PRINT("\n\t      TLV is too short");
1035dc860a36Sspz                 tlv_hexdump = TRUE;
1036dc860a36Sspz                 goto tlv_tooshort;
1037dc860a36Sspz             } else {
1038c74ad251Schristos                 vendor_id = GET_BE_U_4(tlv_tptr);
1039c74ad251Schristos                 ND_PRINT("\n\t    Vendor: %s (0x%04x)",
10400f74e101Schristos                        tok2str(smi_values, "Unknown", vendor_id),
1041c74ad251Schristos                        vendor_id);
10420f74e101Schristos             }
1043dc860a36Sspz         }
10440f74e101Schristos             break;
10450f74e101Schristos 
10460f74e101Schristos             /*
10470f74e101Schristos              *  FIXME those are the defined TLVs that lack a decoder
10480f74e101Schristos              *  you are welcome to contribute code ;-)
10490f74e101Schristos              */
10500f74e101Schristos         case LSPPING_TLV_PAD:
10510f74e101Schristos         case LSPPING_TLV_ERROR_CODE:
10520f74e101Schristos         case LSPPING_TLV_VENDOR_PRIVATE:
10530f74e101Schristos 
10540f74e101Schristos         default:
1055b3a00663Schristos             if (ndo->ndo_vflag <= 1)
1056b3a00663Schristos                 print_unknown_data(ndo, tlv_tptr, "\n\t    ", tlv_tlen);
10570f74e101Schristos             break;
10580f74e101Schristos         }
10590f74e101Schristos         /* do we want to see an additionally tlv hexdump ? */
1060dc860a36Sspz     tlv_tooshort:
1061b3a00663Schristos         if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
1062b3a00663Schristos             print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t    ",
10630f74e101Schristos                                lspping_tlv_len);
10640f74e101Schristos 
10650f74e101Schristos 
10660f74e101Schristos         /* All TLVs are aligned to four octet boundary */
10670f74e101Schristos         if (lspping_tlv_len % 4) {
10680f74e101Schristos             lspping_tlv_len += (4 - lspping_tlv_len % 4);
1069dc860a36Sspz             /* Does the TLV, including padding, go past the end of the packet? */
1070dc860a36Sspz             if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
1071dc860a36Sspz                 goto tooshort;
10720f74e101Schristos         }
10730f74e101Schristos 
10740f74e101Schristos         tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
10750f74e101Schristos         tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
10760f74e101Schristos     }
10770f74e101Schristos     return;
1078dc860a36Sspz tooshort:
1079c74ad251Schristos     ND_PRINT("\n\t\t packet is too short");
10800f74e101Schristos }
1081