11de50e9fSSam Leffler /*
21de50e9fSSam Leffler * Redistribution and use in source and binary forms, with or without
31de50e9fSSam Leffler * modification, are permitted provided that: (1) source code
41de50e9fSSam Leffler * distributions retain the above copyright notice and this paragraph
51de50e9fSSam Leffler * in its entirety, and (2) distributions including binary code include
61de50e9fSSam Leffler * the above copyright notice and this paragraph in its entirety in
71de50e9fSSam Leffler * the documentation or other materials provided with the distribution.
81de50e9fSSam Leffler * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
91de50e9fSSam Leffler * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
101de50e9fSSam Leffler * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
111de50e9fSSam Leffler * FOR A PARTICULAR PURPOSE.
121de50e9fSSam Leffler *
130bff6a5aSEd Maste * Original code by Hannes Gredler (hannes@gredler.at)
141de50e9fSSam Leffler */
151de50e9fSSam Leffler
163340d773SGleb Smirnoff /* \summary: MPLS LSP PING printer */
173340d773SGleb Smirnoff
18*ee67461eSJoseph Mingrone /* specification: RFC 4379 */
19*ee67461eSJoseph Mingrone
20*ee67461eSJoseph Mingrone #include <config.h>
211de50e9fSSam Leffler
22*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
231de50e9fSSam Leffler
24*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK
253340d773SGleb Smirnoff #include "netdissect.h"
261de50e9fSSam Leffler #include "extract.h"
271de50e9fSSam Leffler #include "addrtoname.h"
28*ee67461eSJoseph Mingrone #include "ntp.h"
291de50e9fSSam Leffler
301de50e9fSSam Leffler #include "l2vpn.h"
3127df3f5dSRui Paulo #include "oui.h"
321de50e9fSSam Leffler
333340d773SGleb Smirnoff
341de50e9fSSam Leffler /*
351de50e9fSSam Leffler * LSPPING common header
361de50e9fSSam Leffler *
371de50e9fSSam Leffler * 0 1 2 3
381de50e9fSSam Leffler * 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
391de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
401de50e9fSSam Leffler * | Version Number | Must Be Zero |
411de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
421de50e9fSSam Leffler * | Message Type | Reply mode | Return Code | Return Subcode|
431de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
441de50e9fSSam Leffler * | Sender's Handle |
451de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
461de50e9fSSam Leffler * | Sequence Number |
471de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
481de50e9fSSam Leffler * | TimeStamp Sent (seconds) |
491de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
501de50e9fSSam Leffler * | TimeStamp Sent (microseconds) |
511de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
521de50e9fSSam Leffler * | TimeStamp Received (seconds) |
531de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
541de50e9fSSam Leffler * | TimeStamp Received (microseconds) |
551de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
561de50e9fSSam Leffler * | TLVs ... |
571de50e9fSSam Leffler * . .
581de50e9fSSam Leffler * . .
591de50e9fSSam Leffler * . .
601de50e9fSSam Leffler */
611de50e9fSSam Leffler
621de50e9fSSam Leffler struct lspping_common_header {
63*ee67461eSJoseph Mingrone nd_uint16_t version;
64*ee67461eSJoseph Mingrone nd_uint16_t global_flags;
65*ee67461eSJoseph Mingrone nd_uint8_t msg_type;
66*ee67461eSJoseph Mingrone nd_uint8_t reply_mode;
67*ee67461eSJoseph Mingrone nd_uint8_t return_code;
68*ee67461eSJoseph Mingrone nd_uint8_t return_subcode;
69*ee67461eSJoseph Mingrone nd_uint32_t sender_handle;
70*ee67461eSJoseph Mingrone nd_uint32_t seq_number;
71*ee67461eSJoseph Mingrone struct l_fixedpt ts_sent;
72*ee67461eSJoseph Mingrone struct l_fixedpt ts_rcvd;
731de50e9fSSam Leffler };
741de50e9fSSam Leffler
751de50e9fSSam Leffler #define LSPPING_VERSION 1
761de50e9fSSam Leffler
771de50e9fSSam Leffler static const struct tok lspping_msg_type_values[] = {
781de50e9fSSam Leffler { 1, "MPLS Echo Request"},
791de50e9fSSam Leffler { 2, "MPLS Echo Reply"},
801de50e9fSSam Leffler { 0, NULL}
811de50e9fSSam Leffler };
821de50e9fSSam Leffler
831de50e9fSSam Leffler static const struct tok lspping_reply_mode_values[] = {
841de50e9fSSam Leffler { 1, "Do not reply"},
851de50e9fSSam Leffler { 2, "Reply via an IPv4/IPv6 UDP packet"},
861de50e9fSSam Leffler { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
871de50e9fSSam Leffler { 4, "Reply via application level control channel"},
881de50e9fSSam Leffler { 0, NULL}
891de50e9fSSam Leffler };
901de50e9fSSam Leffler
911de50e9fSSam Leffler static const struct tok lspping_return_code_values[] = {
921de50e9fSSam Leffler { 0, "No return code or return code contained in the Error Code TLV"},
931de50e9fSSam Leffler { 1, "Malformed echo request received"},
941de50e9fSSam Leffler { 2, "One or more of the TLVs was not understood"},
951de50e9fSSam Leffler { 3, "Replying router is an egress for the FEC at stack depth"},
961de50e9fSSam Leffler { 4, "Replying router has no mapping for the FEC at stack depth"},
971de50e9fSSam Leffler { 5, "Reserved"},
981de50e9fSSam Leffler { 6, "Reserved"},
991de50e9fSSam Leffler { 7, "Reserved"},
1001de50e9fSSam Leffler { 8, "Label switched at stack-depth"},
1011de50e9fSSam Leffler { 9, "Label switched but no MPLS forwarding at stack-depth"},
1021de50e9fSSam Leffler { 10, "Mapping for this FEC is not the given label at stack depth"},
1031de50e9fSSam Leffler { 11, "No label entry at stack-depth"},
1041de50e9fSSam Leffler { 12, "Protocol not associated with interface at FEC stack depth"},
1053340d773SGleb Smirnoff { 13, "Premature termination of ping due to label stack shrinking to a single label"},
1060bff6a5aSEd Maste { 0, NULL},
1071de50e9fSSam Leffler };
1081de50e9fSSam Leffler
1091de50e9fSSam Leffler
1101de50e9fSSam Leffler /*
1111de50e9fSSam Leffler * LSPPING TLV header
1121de50e9fSSam Leffler * 0 1 2 3
1131de50e9fSSam Leffler * 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
1141de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1151de50e9fSSam Leffler * | Type | Length |
1161de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1171de50e9fSSam Leffler * | Value |
1181de50e9fSSam Leffler * . .
1191de50e9fSSam Leffler * . .
1201de50e9fSSam Leffler * . .
1211de50e9fSSam Leffler * | |
1221de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1231de50e9fSSam Leffler */
1241de50e9fSSam Leffler
1251de50e9fSSam Leffler struct lspping_tlv_header {
126*ee67461eSJoseph Mingrone nd_uint16_t type;
127*ee67461eSJoseph Mingrone nd_uint16_t length;
1281de50e9fSSam Leffler };
1291de50e9fSSam Leffler
1301de50e9fSSam Leffler #define LSPPING_TLV_TARGET_FEC_STACK 1
1311de50e9fSSam Leffler #define LSPPING_TLV_DOWNSTREAM_MAPPING 2
1321de50e9fSSam Leffler #define LSPPING_TLV_PAD 3
1333340d773SGleb Smirnoff /* not assigned 4 */
13427df3f5dSRui Paulo #define LSPPING_TLV_VENDOR_ENTERPRISE 5
13527df3f5dSRui Paulo #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
1363340d773SGleb Smirnoff /* not assigned 6 */
13727df3f5dSRui Paulo #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
1383340d773SGleb Smirnoff /* not assigned 8 */
13927df3f5dSRui Paulo #define LSPPING_TLV_ERROR_CODE 9
14027df3f5dSRui Paulo #define LSPPING_TLV_REPLY_TOS_BYTE 10
141b5bfcb5dSMax Laier #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */
142b5bfcb5dSMax Laier #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
143f4d0c64aSSam Leffler #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00
1441de50e9fSSam Leffler
1451de50e9fSSam Leffler static const struct tok lspping_tlv_values[] = {
1461de50e9fSSam Leffler { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
1471de50e9fSSam Leffler { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
1481de50e9fSSam Leffler { LSPPING_TLV_PAD, "Pad" },
1491de50e9fSSam Leffler { LSPPING_TLV_ERROR_CODE, "Error Code" },
15027df3f5dSRui Paulo { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
15127df3f5dSRui Paulo { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
15227df3f5dSRui Paulo { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
153b5bfcb5dSMax Laier { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
15427df3f5dSRui Paulo { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
1551de50e9fSSam Leffler { 0, NULL}
1561de50e9fSSam Leffler };
1571de50e9fSSam Leffler
1581de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1
1591de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2
1601de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3
1611de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4
1623340d773SGleb Smirnoff /* not assigned 5 */
1631de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6
1641de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7
1651de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8
1663340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9
1673340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10
1683340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11
1693340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12
1703340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13
1713340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14
1723340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15
1733340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16
1741de50e9fSSam Leffler
1751de50e9fSSam Leffler static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
1761de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
1771de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
1781de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
1791de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
1801de50e9fSSam Leffler { 5, "Reserved"},
1811de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
1821de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
1831de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
1843340d773SGleb Smirnoff { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"},
1853340d773SGleb Smirnoff { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"},
1861de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
1871de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
1881de50e9fSSam Leffler { 0, NULL}
1891de50e9fSSam Leffler };
1901de50e9fSSam Leffler
1911de50e9fSSam Leffler /*
1921de50e9fSSam Leffler * 0 1 2 3
1931de50e9fSSam Leffler * 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
1941de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1951de50e9fSSam Leffler * | IPv4 prefix |
1961de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1971de50e9fSSam Leffler * | Prefix Length | Must Be Zero |
1981de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1991de50e9fSSam Leffler */
2001de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
201*ee67461eSJoseph Mingrone nd_ipv4 prefix;
202*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
2031de50e9fSSam Leffler };
2041de50e9fSSam Leffler
2051de50e9fSSam Leffler /*
2061de50e9fSSam Leffler * 0 1 2 3
2071de50e9fSSam Leffler * 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
2081de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2091de50e9fSSam Leffler * | IPv6 prefix |
2101de50e9fSSam Leffler * | (16 octets) |
2111de50e9fSSam Leffler * | |
2121de50e9fSSam Leffler * | |
2131de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2141de50e9fSSam Leffler * | Prefix Length | Must Be Zero |
2151de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2161de50e9fSSam Leffler */
2171de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
218*ee67461eSJoseph Mingrone nd_ipv6 prefix;
219*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
2201de50e9fSSam Leffler };
2211de50e9fSSam Leffler
2221de50e9fSSam Leffler /*
2231de50e9fSSam Leffler * 0 1 2 3
2241de50e9fSSam Leffler * 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
2251de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2261de50e9fSSam Leffler * | IPv4 tunnel end point address |
2271de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2281de50e9fSSam Leffler * | Must Be Zero | Tunnel ID |
2291de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2301de50e9fSSam Leffler * | Extended Tunnel ID |
2311de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2321de50e9fSSam Leffler * | IPv4 tunnel sender address |
2331de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2341de50e9fSSam Leffler * | Must Be Zero | LSP ID |
2351de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2361de50e9fSSam Leffler */
2371de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
238*ee67461eSJoseph Mingrone nd_ipv4 tunnel_endpoint;
239*ee67461eSJoseph Mingrone nd_byte res[2];
240*ee67461eSJoseph Mingrone nd_uint16_t tunnel_id;
241*ee67461eSJoseph Mingrone nd_ipv4 extended_tunnel_id;
242*ee67461eSJoseph Mingrone nd_ipv4 tunnel_sender;
243*ee67461eSJoseph Mingrone nd_byte res2[2];
244*ee67461eSJoseph Mingrone nd_uint16_t lsp_id;
2451de50e9fSSam Leffler };
2461de50e9fSSam Leffler
2471de50e9fSSam Leffler /*
2481de50e9fSSam Leffler * 0 1 2 3
2491de50e9fSSam Leffler * 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
2501de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2511de50e9fSSam Leffler * | IPv6 tunnel end point address |
2521de50e9fSSam Leffler * | |
2531de50e9fSSam Leffler * | |
2541de50e9fSSam Leffler * | |
2551de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2561de50e9fSSam Leffler * | Must Be Zero | Tunnel ID |
2571de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2581de50e9fSSam Leffler * | Extended Tunnel ID |
2591de50e9fSSam Leffler * | |
2601de50e9fSSam Leffler * | |
2611de50e9fSSam Leffler * | |
2621de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2631de50e9fSSam Leffler * | IPv6 tunnel sender address |
2641de50e9fSSam Leffler * | |
2651de50e9fSSam Leffler * | |
2661de50e9fSSam Leffler * | |
2671de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2681de50e9fSSam Leffler * | Must Be Zero | LSP ID |
2691de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2701de50e9fSSam Leffler */
2711de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
272*ee67461eSJoseph Mingrone nd_ipv6 tunnel_endpoint;
273*ee67461eSJoseph Mingrone nd_byte res[2];
274*ee67461eSJoseph Mingrone nd_uint16_t tunnel_id;
275*ee67461eSJoseph Mingrone nd_ipv6 extended_tunnel_id;
276*ee67461eSJoseph Mingrone nd_ipv6 tunnel_sender;
277*ee67461eSJoseph Mingrone nd_byte res2[2];
278*ee67461eSJoseph Mingrone nd_uint16_t lsp_id;
2791de50e9fSSam Leffler };
2801de50e9fSSam Leffler
2811de50e9fSSam Leffler /*
2821de50e9fSSam Leffler * 0 1 2 3
2831de50e9fSSam Leffler * 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
2841de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2851de50e9fSSam Leffler * | Route Distinguisher |
2861de50e9fSSam Leffler * | (8 octets) |
2871de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2881de50e9fSSam Leffler * | IPv4 prefix |
2891de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2901de50e9fSSam Leffler * | Prefix Length | Must Be Zero |
2911de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2921de50e9fSSam Leffler */
2931de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
294*ee67461eSJoseph Mingrone nd_byte rd[8];
295*ee67461eSJoseph Mingrone nd_ipv4 prefix;
296*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
2971de50e9fSSam Leffler };
2981de50e9fSSam Leffler
2991de50e9fSSam Leffler /*
3001de50e9fSSam Leffler * 0 1 2 3
3011de50e9fSSam Leffler * 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
3021de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3031de50e9fSSam Leffler * | Route Distinguisher |
3041de50e9fSSam Leffler * | (8 octets) |
3051de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3061de50e9fSSam Leffler * | IPv6 prefix |
3071de50e9fSSam Leffler * | (16 octets) |
3081de50e9fSSam Leffler * | |
3091de50e9fSSam Leffler * | |
3101de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3111de50e9fSSam Leffler * | Prefix Length | Must Be Zero |
3121de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3131de50e9fSSam Leffler */
3141de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
315*ee67461eSJoseph Mingrone nd_byte rd[8];
316*ee67461eSJoseph Mingrone nd_ipv6 prefix;
317*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
3181de50e9fSSam Leffler };
3191de50e9fSSam Leffler
3201de50e9fSSam Leffler /*
3211de50e9fSSam Leffler * 0 1 2 3
3221de50e9fSSam Leffler * 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
3231de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3241de50e9fSSam Leffler * | Route Distinguisher |
3251de50e9fSSam Leffler * | (8 octets) |
3261de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3273340d773SGleb Smirnoff * | Sender's VE ID | Receiver's VE ID |
3281de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3291de50e9fSSam Leffler * | Encapsulation Type | Must Be Zero |
3301de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3311de50e9fSSam Leffler * 0 1 2 3
3321de50e9fSSam Leffler */
3331de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
334*ee67461eSJoseph Mingrone nd_byte rd[8];
335*ee67461eSJoseph Mingrone nd_uint16_t sender_ve_id;
336*ee67461eSJoseph Mingrone nd_uint16_t receiver_ve_id;
337*ee67461eSJoseph Mingrone nd_uint16_t encapsulation;
3381de50e9fSSam Leffler };
3391de50e9fSSam Leffler
3401de50e9fSSam Leffler /*
3411de50e9fSSam Leffler * 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
3421de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3431de50e9fSSam Leffler * | Remote PE Address |
3441de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3453340d773SGleb Smirnoff * | PW ID |
3461de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3473340d773SGleb Smirnoff * | PW Type | Must Be Zero |
3481de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3491de50e9fSSam Leffler */
3503340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_fec_128_pw_old {
351*ee67461eSJoseph Mingrone nd_ipv4 remote_pe_address;
352*ee67461eSJoseph Mingrone nd_uint32_t pw_id;
353*ee67461eSJoseph Mingrone nd_uint16_t pw_type;
3541de50e9fSSam Leffler };
3551de50e9fSSam Leffler
3561de50e9fSSam Leffler /*
3571de50e9fSSam Leffler * 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
3581de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3591de50e9fSSam Leffler * | Sender's PE Address |
3601de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3611de50e9fSSam Leffler * | Remote PE Address |
3621de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3633340d773SGleb Smirnoff * | PW ID |
3641de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3653340d773SGleb Smirnoff * | PW Type | Must Be Zero |
3661de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3671de50e9fSSam Leffler */
3683340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_fec_128_pw {
369*ee67461eSJoseph Mingrone nd_ipv4 sender_pe_address;
370*ee67461eSJoseph Mingrone nd_ipv4 remote_pe_address;
371*ee67461eSJoseph Mingrone nd_uint32_t pw_id;
372*ee67461eSJoseph Mingrone nd_uint16_t pw_type;
3733340d773SGleb Smirnoff };
3743340d773SGleb Smirnoff
3753340d773SGleb Smirnoff /*
3763340d773SGleb Smirnoff * 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
3773340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3783340d773SGleb Smirnoff * | IPv4 prefix |
3793340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3803340d773SGleb Smirnoff * | Prefix Length | Must Be Zero |
3813340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3823340d773SGleb Smirnoff */
3833340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
384*ee67461eSJoseph Mingrone nd_ipv4 prefix;
385*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
3863340d773SGleb Smirnoff };
3873340d773SGleb Smirnoff
3883340d773SGleb Smirnoff /*
3893340d773SGleb Smirnoff * 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
3903340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3913340d773SGleb Smirnoff * | IPv6 prefix |
3923340d773SGleb Smirnoff * | (16 octets) |
3933340d773SGleb Smirnoff * | |
3943340d773SGleb Smirnoff * | |
3953340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3963340d773SGleb Smirnoff * | Prefix Length | Must Be Zero |
3973340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3983340d773SGleb Smirnoff */
3993340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
400*ee67461eSJoseph Mingrone nd_ipv6 prefix;
401*ee67461eSJoseph Mingrone nd_uint8_t prefix_len;
4021de50e9fSSam Leffler };
4031de50e9fSSam Leffler
4041de50e9fSSam Leffler /*
4051de50e9fSSam Leffler * 0 1 2 3
4061de50e9fSSam Leffler * 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
4071de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4081de50e9fSSam Leffler * | MTU | Address Type | Resvd (SBZ) |
4091de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4101de50e9fSSam Leffler * | Downstream IP Address (4 or 16 octets) |
4111de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4121de50e9fSSam Leffler * | Downstream Interface Address (4 or 16 octets) |
4131de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4143340d773SGleb Smirnoff * | Multipath Type| Depth Limit | Multipath Length |
4151de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4161de50e9fSSam Leffler * . .
4171de50e9fSSam Leffler * . (Multipath Information) .
4181de50e9fSSam Leffler * . .
4191de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4201de50e9fSSam Leffler * | Downstream Label | Protocol |
4211de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4221de50e9fSSam Leffler * . .
4231de50e9fSSam Leffler * . .
4241de50e9fSSam Leffler * . .
4251de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4261de50e9fSSam Leffler * | Downstream Label | Protocol |
4271de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4281de50e9fSSam Leffler */
4293340d773SGleb Smirnoff /* Enough to get the address type */
4303340d773SGleb Smirnoff struct lspping_tlv_downstream_map_t {
431*ee67461eSJoseph Mingrone nd_uint16_t mtu;
432*ee67461eSJoseph Mingrone nd_uint8_t address_type;
433*ee67461eSJoseph Mingrone nd_uint8_t ds_flags;
4343340d773SGleb Smirnoff };
4353340d773SGleb Smirnoff
4361de50e9fSSam Leffler struct lspping_tlv_downstream_map_ipv4_t {
437*ee67461eSJoseph Mingrone nd_uint16_t mtu;
438*ee67461eSJoseph Mingrone nd_uint8_t address_type;
439*ee67461eSJoseph Mingrone nd_uint8_t ds_flags;
440*ee67461eSJoseph Mingrone nd_ipv4 downstream_ip;
441*ee67461eSJoseph Mingrone nd_ipv4 downstream_interface;
4423340d773SGleb Smirnoff };
4433340d773SGleb Smirnoff
4443340d773SGleb Smirnoff struct lspping_tlv_downstream_map_ipv4_unmb_t {
445*ee67461eSJoseph Mingrone nd_uint16_t mtu;
446*ee67461eSJoseph Mingrone nd_uint8_t address_type;
447*ee67461eSJoseph Mingrone nd_uint8_t ds_flags;
448*ee67461eSJoseph Mingrone nd_ipv4 downstream_ip;
449*ee67461eSJoseph Mingrone nd_uint32_t downstream_interface;
4501de50e9fSSam Leffler };
4511de50e9fSSam Leffler
4521de50e9fSSam Leffler struct lspping_tlv_downstream_map_ipv6_t {
453*ee67461eSJoseph Mingrone nd_uint16_t mtu;
454*ee67461eSJoseph Mingrone nd_uint8_t address_type;
455*ee67461eSJoseph Mingrone nd_uint8_t ds_flags;
456*ee67461eSJoseph Mingrone nd_ipv6 downstream_ip;
457*ee67461eSJoseph Mingrone nd_ipv6 downstream_interface;
4581de50e9fSSam Leffler };
4591de50e9fSSam Leffler
4603340d773SGleb Smirnoff struct lspping_tlv_downstream_map_ipv6_unmb_t {
461*ee67461eSJoseph Mingrone nd_uint16_t mtu;
462*ee67461eSJoseph Mingrone nd_uint8_t address_type;
463*ee67461eSJoseph Mingrone nd_uint8_t ds_flags;
464*ee67461eSJoseph Mingrone nd_ipv6 downstream_ip;
465*ee67461eSJoseph Mingrone nd_uint32_t downstream_interface;
4663340d773SGleb Smirnoff };
4673340d773SGleb Smirnoff
4681de50e9fSSam Leffler struct lspping_tlv_downstream_map_info_t {
469*ee67461eSJoseph Mingrone nd_uint8_t multipath_type;
470*ee67461eSJoseph Mingrone nd_uint8_t depth_limit;
471*ee67461eSJoseph Mingrone nd_uint16_t multipath_length;
4721de50e9fSSam Leffler };
4731de50e9fSSam Leffler
4741de50e9fSSam Leffler #define LSPPING_AFI_IPV4 1
4753340d773SGleb Smirnoff #define LSPPING_AFI_IPV4_UNMB 2
4761de50e9fSSam Leffler #define LSPPING_AFI_IPV6 3
4773340d773SGleb Smirnoff #define LSPPING_AFI_IPV6_UNMB 4
4781de50e9fSSam Leffler
4791de50e9fSSam Leffler static const struct tok lspping_tlv_downstream_addr_values[] = {
4801de50e9fSSam Leffler { LSPPING_AFI_IPV4, "IPv4"},
4813340d773SGleb Smirnoff { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"},
4821de50e9fSSam Leffler { LSPPING_AFI_IPV6, "IPv6"},
4833340d773SGleb Smirnoff { LSPPING_AFI_IPV6_UNMB, "IPv6"},
4841de50e9fSSam Leffler { 0, NULL}
4851de50e9fSSam Leffler };
4861de50e9fSSam Leffler
4871de50e9fSSam Leffler void
lspping_print(netdissect_options * ndo,const u_char * pptr,u_int len)4883c602fabSXin LI lspping_print(netdissect_options *ndo,
489*ee67461eSJoseph Mingrone const u_char *pptr, u_int len)
4908bdc5a62SPatrick Kelsey {
4911de50e9fSSam Leffler const struct lspping_common_header *lspping_com_header;
4921de50e9fSSam Leffler const struct lspping_tlv_header *lspping_tlv_header;
4931de50e9fSSam Leffler const struct lspping_tlv_header *lspping_subtlv_header;
4941de50e9fSSam Leffler const u_char *tptr,*tlv_tptr,*subtlv_tptr;
495*ee67461eSJoseph Mingrone u_int return_code, return_subcode;
4963340d773SGleb Smirnoff u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
4971de50e9fSSam Leffler int tlv_hexdump,subtlv_hexdump;
4983340d773SGleb Smirnoff u_int lspping_subtlv_len,lspping_subtlv_type;
499*ee67461eSJoseph Mingrone uint32_t int_part, fraction;
500*ee67461eSJoseph Mingrone u_int address_type;
5011de50e9fSSam Leffler
5021de50e9fSSam Leffler union {
5033340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map;
5041de50e9fSSam Leffler const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
5053340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb;
5061de50e9fSSam Leffler const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
5073340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb;
5081de50e9fSSam Leffler const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info;
5091de50e9fSSam Leffler } tlv_ptr;
5101de50e9fSSam Leffler
5111de50e9fSSam Leffler union {
5121de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
5131de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
5141de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
5151de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
5161de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
5171de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
5181de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
5193340d773SGleb Smirnoff const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
5203340d773SGleb Smirnoff const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
5211de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
5221de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
5231de50e9fSSam Leffler } subtlv_ptr;
5241de50e9fSSam Leffler
525*ee67461eSJoseph Mingrone ndo->ndo_protocol = "lspping";
5261de50e9fSSam Leffler tptr=pptr;
5271de50e9fSSam Leffler lspping_com_header = (const struct lspping_common_header *)pptr;
528*ee67461eSJoseph Mingrone if (len < sizeof(struct lspping_common_header))
5293340d773SGleb Smirnoff goto tooshort;
530*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(lspping_com_header);
5311de50e9fSSam Leffler
5321de50e9fSSam Leffler /*
5331de50e9fSSam Leffler * Sanity checking of the header.
5341de50e9fSSam Leffler */
535*ee67461eSJoseph Mingrone if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) {
536*ee67461eSJoseph Mingrone ND_PRINT("LSP-PING version %u packet not supported",
537*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version));
5381de50e9fSSam Leffler return;
5391de50e9fSSam Leffler }
5401de50e9fSSam Leffler
5411de50e9fSSam Leffler /* in non-verbose mode just lets print the basic Message Type*/
5423c602fabSXin LI if (ndo->ndo_vflag < 1) {
543*ee67461eSJoseph Mingrone ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u",
544*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version),
545*ee67461eSJoseph Mingrone tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)),
546*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->seq_number),
547*ee67461eSJoseph Mingrone len);
5481de50e9fSSam Leffler return;
5491de50e9fSSam Leffler }
5501de50e9fSSam Leffler
5511de50e9fSSam Leffler /* ok they seem to want to know everything - lets fully decode it */
5521de50e9fSSam Leffler
5531de50e9fSSam Leffler tlen=len;
5541de50e9fSSam Leffler
555*ee67461eSJoseph Mingrone ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)",
556*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version),
557*ee67461eSJoseph Mingrone tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)),
558*ee67461eSJoseph Mingrone GET_U_1(lspping_com_header->msg_type),
559f4d0c64aSSam Leffler len,
560*ee67461eSJoseph Mingrone tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)),
561*ee67461eSJoseph Mingrone GET_U_1(lspping_com_header->reply_mode));
5621de50e9fSSam Leffler
5631de50e9fSSam Leffler /*
5641de50e9fSSam Leffler * the following return codes require that the subcode is attached
5651de50e9fSSam Leffler * at the end of the translated token output
5661de50e9fSSam Leffler */
567*ee67461eSJoseph Mingrone return_code = GET_U_1(lspping_com_header->return_code);
568*ee67461eSJoseph Mingrone return_subcode = GET_U_1(lspping_com_header->return_subcode);
569*ee67461eSJoseph Mingrone if (return_code == 3 ||
570*ee67461eSJoseph Mingrone return_code == 4 ||
571*ee67461eSJoseph Mingrone return_code == 8 ||
572*ee67461eSJoseph Mingrone return_code == 10 ||
573*ee67461eSJoseph Mingrone return_code == 11 ||
574*ee67461eSJoseph Mingrone return_code == 12 )
575*ee67461eSJoseph Mingrone ND_PRINT("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)",
576*ee67461eSJoseph Mingrone tok2str(lspping_return_code_values, "unknown",return_code),
577*ee67461eSJoseph Mingrone return_subcode,
578*ee67461eSJoseph Mingrone return_code,
579*ee67461eSJoseph Mingrone return_subcode);
5801de50e9fSSam Leffler else
581*ee67461eSJoseph Mingrone ND_PRINT("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)",
582*ee67461eSJoseph Mingrone tok2str(lspping_return_code_values, "unknown",return_code),
583*ee67461eSJoseph Mingrone return_code,
584*ee67461eSJoseph Mingrone return_subcode);
5851de50e9fSSam Leffler
586*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender Handle: 0x%08x, Sequence: %u",
587*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->sender_handle),
588*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->seq_number));
5891de50e9fSSam Leffler
590*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender Timestamp: ");
591*ee67461eSJoseph Mingrone p_ntp_time(ndo, &lspping_com_header->ts_sent);
592*ee67461eSJoseph Mingrone ND_PRINT(" ");
5931de50e9fSSam Leffler
594*ee67461eSJoseph Mingrone int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part);
595*ee67461eSJoseph Mingrone fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction);
596*ee67461eSJoseph Mingrone ND_PRINT("Receiver Timestamp: ");
597*ee67461eSJoseph Mingrone if (! (int_part == 0 && fraction == 0))
598*ee67461eSJoseph Mingrone p_ntp_time(ndo, &lspping_com_header->ts_rcvd);
5991de50e9fSSam Leffler else
600*ee67461eSJoseph Mingrone ND_PRINT("no timestamp");
6011de50e9fSSam Leffler
602*ee67461eSJoseph Mingrone tptr+=sizeof(struct lspping_common_header);
603*ee67461eSJoseph Mingrone tlen-=sizeof(struct lspping_common_header);
6041de50e9fSSam Leffler
6053340d773SGleb Smirnoff while (tlen != 0) {
6063340d773SGleb Smirnoff /* Does the TLV go past the end of the packet? */
6073340d773SGleb Smirnoff if (tlen < sizeof(struct lspping_tlv_header))
6083340d773SGleb Smirnoff goto tooshort;
60927df3f5dSRui Paulo
6101de50e9fSSam Leffler lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
611*ee67461eSJoseph Mingrone lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type);
612*ee67461eSJoseph Mingrone lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length);
6131de50e9fSSam Leffler
614*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s TLV (%u), length: %u",
6151de50e9fSSam Leffler tok2str(lspping_tlv_values,
6161de50e9fSSam Leffler "Unknown",
6171de50e9fSSam Leffler lspping_tlv_type),
6181de50e9fSSam Leffler lspping_tlv_type,
619*ee67461eSJoseph Mingrone lspping_tlv_len);
6201de50e9fSSam Leffler
6213340d773SGleb Smirnoff /* some little sanity checking */
6223340d773SGleb Smirnoff if (lspping_tlv_len == 0) {
6233340d773SGleb Smirnoff tptr+=sizeof(struct lspping_tlv_header);
6243340d773SGleb Smirnoff tlen-=sizeof(struct lspping_tlv_header);
6253340d773SGleb Smirnoff continue; /* no value to dissect */
6263340d773SGleb Smirnoff }
6273340d773SGleb Smirnoff
6281de50e9fSSam Leffler tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
6291de50e9fSSam Leffler tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
6301de50e9fSSam Leffler
6313340d773SGleb Smirnoff /* Does the TLV go past the end of the packet? */
6323340d773SGleb Smirnoff if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
6333340d773SGleb Smirnoff goto tooshort;
6341de50e9fSSam Leffler /* did we capture enough for fully decoding the tlv ? */
635*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len);
6361de50e9fSSam Leffler tlv_hexdump=FALSE;
6371de50e9fSSam Leffler
6381de50e9fSSam Leffler switch(lspping_tlv_type) {
6391de50e9fSSam Leffler case LSPPING_TLV_TARGET_FEC_STACK:
6403340d773SGleb Smirnoff while (tlv_tlen != 0) {
6413340d773SGleb Smirnoff /* Does the subTLV header go past the end of the TLV? */
6423340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_header)) {
643*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
6443340d773SGleb Smirnoff tlv_hexdump = TRUE;
6453340d773SGleb Smirnoff goto tlv_tooshort;
6463340d773SGleb Smirnoff }
6471de50e9fSSam Leffler subtlv_hexdump=FALSE;
6481de50e9fSSam Leffler
6491de50e9fSSam Leffler lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
650*ee67461eSJoseph Mingrone lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type);
651*ee67461eSJoseph Mingrone lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length);
6521de50e9fSSam Leffler subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
6531de50e9fSSam Leffler
6543340d773SGleb Smirnoff /* Does the subTLV go past the end of the TLV? */
6553340d773SGleb Smirnoff if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
656*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
6573340d773SGleb Smirnoff tlv_hexdump = TRUE;
6583340d773SGleb Smirnoff goto tlv_tooshort;
6593340d773SGleb Smirnoff }
6603340d773SGleb Smirnoff
6613340d773SGleb Smirnoff /* Did we capture enough for fully decoding the subTLV? */
662*ee67461eSJoseph Mingrone ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len);
6631de50e9fSSam Leffler
664*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s subTLV (%u), length: %u",
6651de50e9fSSam Leffler tok2str(lspping_tlvtargetfec_subtlv_values,
6661de50e9fSSam Leffler "Unknown",
6671de50e9fSSam Leffler lspping_subtlv_type),
6681de50e9fSSam Leffler lspping_subtlv_type,
669*ee67461eSJoseph Mingrone lspping_subtlv_len);
6701de50e9fSSam Leffler
6711de50e9fSSam Leffler switch(lspping_subtlv_type) {
6721de50e9fSSam Leffler
6731de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
6743340d773SGleb Smirnoff /* Is the subTLV length correct? */
6753340d773SGleb Smirnoff if (lspping_subtlv_len != 5) {
676*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 5");
6773340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
6783340d773SGleb Smirnoff } else {
679*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 =
6801de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
681*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u",
682*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
683*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len));
6843340d773SGleb Smirnoff }
6851de50e9fSSam Leffler break;
6861de50e9fSSam Leffler
6871de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
6883340d773SGleb Smirnoff /* Is the subTLV length correct? */
6893340d773SGleb Smirnoff if (lspping_subtlv_len != 17) {
690*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 17");
6913340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
6923340d773SGleb Smirnoff } else {
693*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 =
6941de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
695*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u",
696*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
697*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
6983340d773SGleb Smirnoff }
6991de50e9fSSam Leffler break;
7001de50e9fSSam Leffler
7011de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
7023340d773SGleb Smirnoff /* Is the subTLV length correct? */
7033340d773SGleb Smirnoff if (lspping_subtlv_len != 5) {
704*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 5");
7053340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7063340d773SGleb Smirnoff } else {
707*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 =
7081de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
709*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u",
710*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
711*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len));
7123340d773SGleb Smirnoff }
7131de50e9fSSam Leffler break;
7141de50e9fSSam Leffler
7151de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
7163340d773SGleb Smirnoff /* Is the subTLV length correct? */
7173340d773SGleb Smirnoff if (lspping_subtlv_len != 17) {
718*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 17");
7193340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7203340d773SGleb Smirnoff } else {
721*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 =
7221de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
723*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u",
724*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
725*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len));
7263340d773SGleb Smirnoff }
7271de50e9fSSam Leffler break;
7281de50e9fSSam Leffler
7291de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
7303340d773SGleb Smirnoff /* Is the subTLV length correct? */
7313340d773SGleb Smirnoff if (lspping_subtlv_len != 20) {
732*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 20");
7333340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7343340d773SGleb Smirnoff } else {
735*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 =
7361de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
737*ee67461eSJoseph Mingrone ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
7381de50e9fSSam Leffler "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
739*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
740*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
741*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
742*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
743*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
7443340d773SGleb Smirnoff }
7451de50e9fSSam Leffler break;
7461de50e9fSSam Leffler
7471de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
7483340d773SGleb Smirnoff /* Is the subTLV length correct? */
7493340d773SGleb Smirnoff if (lspping_subtlv_len != 56) {
750*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 56");
7513340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7523340d773SGleb Smirnoff } else {
753*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 =
7541de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
755*ee67461eSJoseph Mingrone ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
7561de50e9fSSam Leffler "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
757*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
758*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
759*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
760*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
761*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
7623340d773SGleb Smirnoff }
7631de50e9fSSam Leffler break;
7641de50e9fSSam Leffler
7651de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
7663340d773SGleb Smirnoff /* Is the subTLV length correct? */
7673340d773SGleb Smirnoff if (lspping_subtlv_len != 13) {
768*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 13");
7693340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7703340d773SGleb Smirnoff } else {
771*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 =
7721de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
773*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, %s/%u",
7743c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
775*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
776*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
7773340d773SGleb Smirnoff }
7781de50e9fSSam Leffler break;
7791de50e9fSSam Leffler
7801de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
7813340d773SGleb Smirnoff /* Is the subTLV length correct? */
7823340d773SGleb Smirnoff if (lspping_subtlv_len != 25) {
783*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 25");
7843340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
7853340d773SGleb Smirnoff } else {
786*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 =
7871de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
788*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, %s/%u",
7893c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
790*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
791*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
7923340d773SGleb Smirnoff }
7931de50e9fSSam Leffler break;
7941de50e9fSSam Leffler
7951de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
7963340d773SGleb Smirnoff /* Is the subTLV length correct? */
7973340d773SGleb Smirnoff if (lspping_subtlv_len != 14) {
798*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 14");
7993340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
8003340d773SGleb Smirnoff } else {
801*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt =
8021de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
803*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u"
8041de50e9fSSam Leffler "\n\t Encapsulation Type: %s (%u)",
8053c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
806*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id),
807*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id),
8083340d773SGleb Smirnoff tok2str(mpls_pw_types_values,
8091de50e9fSSam Leffler "unknown",
810*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
811*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
8123340d773SGleb Smirnoff }
8131de50e9fSSam Leffler break;
8141de50e9fSSam Leffler
8151de50e9fSSam Leffler /* the old L2VPN VCID subTLV does not have support for the sender field */
8163340d773SGleb Smirnoff case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD:
8173340d773SGleb Smirnoff /* Is the subTLV length correct? */
8183340d773SGleb Smirnoff if (lspping_subtlv_len != 10) {
819*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 10");
8203340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
8213340d773SGleb Smirnoff } else {
822*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old =
8233340d773SGleb Smirnoff (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr;
824*ee67461eSJoseph Mingrone ND_PRINT("\n\t Remote PE: %s"
8253340d773SGleb Smirnoff "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
826*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
827*ee67461eSJoseph Mingrone GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id),
8283340d773SGleb Smirnoff tok2str(mpls_pw_types_values,
8291de50e9fSSam Leffler "unknown",
830*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)),
831*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type));
8323340d773SGleb Smirnoff }
8331de50e9fSSam Leffler break;
8341de50e9fSSam Leffler
8353340d773SGleb Smirnoff case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW:
8363340d773SGleb Smirnoff /* Is the subTLV length correct? */
8373340d773SGleb Smirnoff if (lspping_subtlv_len != 14) {
838*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 14");
8393340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
8403340d773SGleb Smirnoff } else {
841*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid =
8423340d773SGleb Smirnoff (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr;
843*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender PE: %s, Remote PE: %s"
8443340d773SGleb Smirnoff "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
845*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
846*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
847*ee67461eSJoseph Mingrone GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id),
8483340d773SGleb Smirnoff tok2str(mpls_pw_types_values,
8491de50e9fSSam Leffler "unknown",
850*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)),
851*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type));
8523340d773SGleb Smirnoff }
8531de50e9fSSam Leffler break;
8541de50e9fSSam Leffler
8551de50e9fSSam Leffler default:
8561de50e9fSSam Leffler subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
8571de50e9fSSam Leffler break;
8581de50e9fSSam Leffler }
8591de50e9fSSam Leffler /* do we want to see an additionally subtlv hexdump ? */
8603c602fabSXin LI if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
861*ee67461eSJoseph Mingrone print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header),
8621de50e9fSSam Leffler "\n\t ",
8631de50e9fSSam Leffler lspping_subtlv_len);
8641de50e9fSSam Leffler
8653340d773SGleb Smirnoff /* All subTLVs are aligned to four octet boundary */
8663340d773SGleb Smirnoff if (lspping_subtlv_len % 4) {
8673340d773SGleb Smirnoff lspping_subtlv_len += 4 - (lspping_subtlv_len % 4);
8683340d773SGleb Smirnoff /* Does the subTLV, including padding, go past the end of the TLV? */
8693340d773SGleb Smirnoff if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
870*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t TLV is too short");
8713340d773SGleb Smirnoff return;
8723340d773SGleb Smirnoff }
8733340d773SGleb Smirnoff }
8741de50e9fSSam Leffler tlv_tptr+=lspping_subtlv_len;
8751de50e9fSSam Leffler tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
8761de50e9fSSam Leffler }
8771de50e9fSSam Leffler break;
8781de50e9fSSam Leffler
8791de50e9fSSam Leffler case LSPPING_TLV_DOWNSTREAM_MAPPING:
8803340d773SGleb Smirnoff /* Does the header go past the end of the TLV? */
8813340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
882*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
8833340d773SGleb Smirnoff tlv_hexdump = TRUE;
8843340d773SGleb Smirnoff goto tlv_tooshort;
8853340d773SGleb Smirnoff }
8863340d773SGleb Smirnoff /* Did we capture enough to get the address family? */
887*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
888*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_t));
8893340d773SGleb Smirnoff
890*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map=
8913340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
8923340d773SGleb Smirnoff
8931de50e9fSSam Leffler /* that strange thing with the downstream map TLV is that until now
8943340d773SGleb Smirnoff * we do not know if its IPv4 or IPv6 or is unnumbered; after
8953340d773SGleb Smirnoff * we find the address-type, we recast the tlv_tptr and move on. */
8963340d773SGleb Smirnoff
897*ee67461eSJoseph Mingrone address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type);
898*ee67461eSJoseph Mingrone ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)",
899*ee67461eSJoseph Mingrone GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu),
9003340d773SGleb Smirnoff tok2str(lspping_tlv_downstream_addr_values,
9013340d773SGleb Smirnoff "unknown",
902*ee67461eSJoseph Mingrone address_type),
903*ee67461eSJoseph Mingrone address_type);
9043340d773SGleb Smirnoff
905*ee67461eSJoseph Mingrone switch(address_type) {
9063340d773SGleb Smirnoff
9073340d773SGleb Smirnoff case LSPPING_AFI_IPV4:
9083340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */
9093340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
910*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
9113340d773SGleb Smirnoff tlv_hexdump = TRUE;
9123340d773SGleb Smirnoff goto tlv_tooshort;
9133340d773SGleb Smirnoff }
9143340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */
915*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
916*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv4_t));
9171de50e9fSSam Leffler
918*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv4=
9191de50e9fSSam Leffler (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
920*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s"
9211de50e9fSSam Leffler "\n\t Downstream Interface IP: %s",
922*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
923*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
9241de50e9fSSam Leffler tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
9251de50e9fSSam Leffler tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
9261de50e9fSSam Leffler break;
9273340d773SGleb Smirnoff case LSPPING_AFI_IPV4_UNMB:
9283340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */
9293340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
930*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
9313340d773SGleb Smirnoff tlv_hexdump = TRUE;
9323340d773SGleb Smirnoff goto tlv_tooshort;
9333340d773SGleb Smirnoff }
9343340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */
935*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
936*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
9373340d773SGleb Smirnoff
938*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb=
9393340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
940*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s"
9413340d773SGleb Smirnoff "\n\t Downstream Interface Index: 0x%08x",
942*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
943*ee67461eSJoseph Mingrone GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface));
9443340d773SGleb Smirnoff tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
9453340d773SGleb Smirnoff tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
9463340d773SGleb Smirnoff break;
9471de50e9fSSam Leffler case LSPPING_AFI_IPV6:
9483340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */
9493340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
950*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
9513340d773SGleb Smirnoff tlv_hexdump = TRUE;
9523340d773SGleb Smirnoff goto tlv_tooshort;
9533340d773SGleb Smirnoff }
9543340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */
955*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
956*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv6_t));
9573340d773SGleb Smirnoff
958*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv6=
9593340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
960*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s"
9611de50e9fSSam Leffler "\n\t Downstream Interface IP: %s",
962*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
963*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
9641de50e9fSSam Leffler tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
9651de50e9fSSam Leffler tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
9661de50e9fSSam Leffler break;
9673340d773SGleb Smirnoff case LSPPING_AFI_IPV6_UNMB:
9683340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */
9693340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
970*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
9713340d773SGleb Smirnoff tlv_hexdump = TRUE;
9723340d773SGleb Smirnoff goto tlv_tooshort;
9733340d773SGleb Smirnoff }
9743340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */
975*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
976*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
9773340d773SGleb Smirnoff
978*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb=
9793340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
980*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s"
9811de50e9fSSam Leffler "\n\t Downstream Interface Index: 0x%08x",
982*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
983*ee67461eSJoseph Mingrone GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface));
9843340d773SGleb Smirnoff tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
9853340d773SGleb Smirnoff tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
9861de50e9fSSam Leffler break;
9871de50e9fSSam Leffler
9881de50e9fSSam Leffler default:
9891de50e9fSSam Leffler /* should not happen ! - no error message - tok2str() has barked already */
9901de50e9fSSam Leffler break;
9911de50e9fSSam Leffler }
9921de50e9fSSam Leffler
9933340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */
9943340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
995*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
9963340d773SGleb Smirnoff tlv_hexdump = TRUE;
9973340d773SGleb Smirnoff goto tlv_tooshort;
9983340d773SGleb Smirnoff }
9993340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */
1000*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr,
1001*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_info_t));
10023340d773SGleb Smirnoff
1003*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_info=
10041de50e9fSSam Leffler (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
10051de50e9fSSam Leffler
10061de50e9fSSam Leffler /* FIXME add hash-key type, depth limit, multipath processing */
10071de50e9fSSam Leffler
10081de50e9fSSam Leffler /* FIXME print downstream labels */
10091de50e9fSSam Leffler
10101de50e9fSSam Leffler tlv_hexdump=TRUE; /* dump the TLV until code complete */
10111de50e9fSSam Leffler
10121de50e9fSSam Leffler break;
10131de50e9fSSam Leffler
1014b5bfcb5dSMax Laier case LSPPING_TLV_BFD_DISCRIMINATOR:
10153340d773SGleb Smirnoff if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
1016*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
10173340d773SGleb Smirnoff tlv_hexdump = TRUE;
10183340d773SGleb Smirnoff goto tlv_tooshort;
10193340d773SGleb Smirnoff } else {
1020*ee67461eSJoseph Mingrone ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr));
10213340d773SGleb Smirnoff }
1022b5bfcb5dSMax Laier break;
102327df3f5dSRui Paulo
102427df3f5dSRui Paulo case LSPPING_TLV_VENDOR_ENTERPRISE:
102527df3f5dSRui Paulo {
10263c602fabSXin LI uint32_t vendor_id;
102727df3f5dSRui Paulo
10283340d773SGleb Smirnoff if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
1029*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short");
10303340d773SGleb Smirnoff tlv_hexdump = TRUE;
10313340d773SGleb Smirnoff goto tlv_tooshort;
10323340d773SGleb Smirnoff } else {
1033*ee67461eSJoseph Mingrone vendor_id = GET_BE_U_4(tlv_tptr);
1034*ee67461eSJoseph Mingrone ND_PRINT("\n\t Vendor: %s (0x%04x)",
103527df3f5dSRui Paulo tok2str(smi_values, "Unknown", vendor_id),
1036*ee67461eSJoseph Mingrone vendor_id);
103727df3f5dSRui Paulo }
10383340d773SGleb Smirnoff }
103927df3f5dSRui Paulo break;
104027df3f5dSRui Paulo
10411de50e9fSSam Leffler /*
10421de50e9fSSam Leffler * FIXME those are the defined TLVs that lack a decoder
10431de50e9fSSam Leffler * you are welcome to contribute code ;-)
10441de50e9fSSam Leffler */
10451de50e9fSSam Leffler case LSPPING_TLV_PAD:
10461de50e9fSSam Leffler case LSPPING_TLV_ERROR_CODE:
10471de50e9fSSam Leffler case LSPPING_TLV_VENDOR_PRIVATE:
10481de50e9fSSam Leffler
10491de50e9fSSam Leffler default:
10503c602fabSXin LI if (ndo->ndo_vflag <= 1)
10513c602fabSXin LI print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen);
10521de50e9fSSam Leffler break;
10531de50e9fSSam Leffler }
10541de50e9fSSam Leffler /* do we want to see an additionally tlv hexdump ? */
10553340d773SGleb Smirnoff tlv_tooshort:
10563c602fabSXin LI if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
10573c602fabSXin LI print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ",
10581de50e9fSSam Leffler lspping_tlv_len);
10591de50e9fSSam Leffler
1060a5779b6eSRui Paulo
1061a5779b6eSRui Paulo /* All TLVs are aligned to four octet boundary */
1062a5779b6eSRui Paulo if (lspping_tlv_len % 4) {
1063a5779b6eSRui Paulo lspping_tlv_len += (4 - lspping_tlv_len % 4);
10643340d773SGleb Smirnoff /* Does the TLV, including padding, go past the end of the packet? */
10653340d773SGleb Smirnoff if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
10663340d773SGleb Smirnoff goto tooshort;
1067a5779b6eSRui Paulo }
1068a5779b6eSRui Paulo
1069f4d0c64aSSam Leffler tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
10701de50e9fSSam Leffler tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
10711de50e9fSSam Leffler }
10721de50e9fSSam Leffler return;
10733340d773SGleb Smirnoff tooshort:
1074*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t packet is too short");
10751de50e9fSSam Leffler }
1076