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 201de50e9fSSam Leffler #ifdef HAVE_CONFIG_H 21*ee67461eSJoseph Mingrone #include <config.h> 221de50e9fSSam Leffler #endif 231de50e9fSSam Leffler 24*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 251de50e9fSSam Leffler 26*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK 273340d773SGleb Smirnoff #include "netdissect.h" 281de50e9fSSam Leffler #include "extract.h" 291de50e9fSSam Leffler #include "addrtoname.h" 30*ee67461eSJoseph Mingrone #include "ntp.h" 311de50e9fSSam Leffler 321de50e9fSSam Leffler #include "l2vpn.h" 3327df3f5dSRui Paulo #include "oui.h" 341de50e9fSSam Leffler 353340d773SGleb Smirnoff 361de50e9fSSam Leffler /* 371de50e9fSSam Leffler * LSPPING common header 381de50e9fSSam Leffler * 391de50e9fSSam Leffler * 0 1 2 3 401de50e9fSSam 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 411de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421de50e9fSSam Leffler * | Version Number | Must Be Zero | 431de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 441de50e9fSSam Leffler * | Message Type | Reply mode | Return Code | Return Subcode| 451de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 461de50e9fSSam Leffler * | Sender's Handle | 471de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 481de50e9fSSam Leffler * | Sequence Number | 491de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 501de50e9fSSam Leffler * | TimeStamp Sent (seconds) | 511de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 521de50e9fSSam Leffler * | TimeStamp Sent (microseconds) | 531de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541de50e9fSSam Leffler * | TimeStamp Received (seconds) | 551de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 561de50e9fSSam Leffler * | TimeStamp Received (microseconds) | 571de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 581de50e9fSSam Leffler * | TLVs ... | 591de50e9fSSam Leffler * . . 601de50e9fSSam Leffler * . . 611de50e9fSSam Leffler * . . 621de50e9fSSam Leffler */ 631de50e9fSSam Leffler 641de50e9fSSam Leffler struct lspping_common_header { 65*ee67461eSJoseph Mingrone nd_uint16_t version; 66*ee67461eSJoseph Mingrone nd_uint16_t global_flags; 67*ee67461eSJoseph Mingrone nd_uint8_t msg_type; 68*ee67461eSJoseph Mingrone nd_uint8_t reply_mode; 69*ee67461eSJoseph Mingrone nd_uint8_t return_code; 70*ee67461eSJoseph Mingrone nd_uint8_t return_subcode; 71*ee67461eSJoseph Mingrone nd_uint32_t sender_handle; 72*ee67461eSJoseph Mingrone nd_uint32_t seq_number; 73*ee67461eSJoseph Mingrone struct l_fixedpt ts_sent; 74*ee67461eSJoseph Mingrone struct l_fixedpt ts_rcvd; 751de50e9fSSam Leffler }; 761de50e9fSSam Leffler 771de50e9fSSam Leffler #define LSPPING_VERSION 1 781de50e9fSSam Leffler 791de50e9fSSam Leffler static const struct tok lspping_msg_type_values[] = { 801de50e9fSSam Leffler { 1, "MPLS Echo Request"}, 811de50e9fSSam Leffler { 2, "MPLS Echo Reply"}, 821de50e9fSSam Leffler { 0, NULL} 831de50e9fSSam Leffler }; 841de50e9fSSam Leffler 851de50e9fSSam Leffler static const struct tok lspping_reply_mode_values[] = { 861de50e9fSSam Leffler { 1, "Do not reply"}, 871de50e9fSSam Leffler { 2, "Reply via an IPv4/IPv6 UDP packet"}, 881de50e9fSSam Leffler { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"}, 891de50e9fSSam Leffler { 4, "Reply via application level control channel"}, 901de50e9fSSam Leffler { 0, NULL} 911de50e9fSSam Leffler }; 921de50e9fSSam Leffler 931de50e9fSSam Leffler static const struct tok lspping_return_code_values[] = { 941de50e9fSSam Leffler { 0, "No return code or return code contained in the Error Code TLV"}, 951de50e9fSSam Leffler { 1, "Malformed echo request received"}, 961de50e9fSSam Leffler { 2, "One or more of the TLVs was not understood"}, 971de50e9fSSam Leffler { 3, "Replying router is an egress for the FEC at stack depth"}, 981de50e9fSSam Leffler { 4, "Replying router has no mapping for the FEC at stack depth"}, 991de50e9fSSam Leffler { 5, "Reserved"}, 1001de50e9fSSam Leffler { 6, "Reserved"}, 1011de50e9fSSam Leffler { 7, "Reserved"}, 1021de50e9fSSam Leffler { 8, "Label switched at stack-depth"}, 1031de50e9fSSam Leffler { 9, "Label switched but no MPLS forwarding at stack-depth"}, 1041de50e9fSSam Leffler { 10, "Mapping for this FEC is not the given label at stack depth"}, 1051de50e9fSSam Leffler { 11, "No label entry at stack-depth"}, 1061de50e9fSSam Leffler { 12, "Protocol not associated with interface at FEC stack depth"}, 1073340d773SGleb Smirnoff { 13, "Premature termination of ping due to label stack shrinking to a single label"}, 1080bff6a5aSEd Maste { 0, NULL}, 1091de50e9fSSam Leffler }; 1101de50e9fSSam Leffler 1111de50e9fSSam Leffler 1121de50e9fSSam Leffler /* 1131de50e9fSSam Leffler * LSPPING TLV header 1141de50e9fSSam Leffler * 0 1 2 3 1151de50e9fSSam 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 1161de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1171de50e9fSSam Leffler * | Type | Length | 1181de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1191de50e9fSSam Leffler * | Value | 1201de50e9fSSam Leffler * . . 1211de50e9fSSam Leffler * . . 1221de50e9fSSam Leffler * . . 1231de50e9fSSam Leffler * | | 1241de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1251de50e9fSSam Leffler */ 1261de50e9fSSam Leffler 1271de50e9fSSam Leffler struct lspping_tlv_header { 128*ee67461eSJoseph Mingrone nd_uint16_t type; 129*ee67461eSJoseph Mingrone nd_uint16_t length; 1301de50e9fSSam Leffler }; 1311de50e9fSSam Leffler 1321de50e9fSSam Leffler #define LSPPING_TLV_TARGET_FEC_STACK 1 1331de50e9fSSam Leffler #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 1341de50e9fSSam Leffler #define LSPPING_TLV_PAD 3 1353340d773SGleb Smirnoff /* not assigned 4 */ 13627df3f5dSRui Paulo #define LSPPING_TLV_VENDOR_ENTERPRISE 5 13727df3f5dSRui Paulo #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 1383340d773SGleb Smirnoff /* not assigned 6 */ 13927df3f5dSRui Paulo #define LSPPING_TLV_INTERFACE_LABEL_STACK 7 1403340d773SGleb Smirnoff /* not assigned 8 */ 14127df3f5dSRui Paulo #define LSPPING_TLV_ERROR_CODE 9 14227df3f5dSRui Paulo #define LSPPING_TLV_REPLY_TOS_BYTE 10 143b5bfcb5dSMax Laier #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ 144b5bfcb5dSMax Laier #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 145f4d0c64aSSam Leffler #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 1461de50e9fSSam Leffler 1471de50e9fSSam Leffler static const struct tok lspping_tlv_values[] = { 1481de50e9fSSam Leffler { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, 1491de50e9fSSam Leffler { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, 1501de50e9fSSam Leffler { LSPPING_TLV_PAD, "Pad" }, 1511de50e9fSSam Leffler { LSPPING_TLV_ERROR_CODE, "Error Code" }, 15227df3f5dSRui Paulo { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, 15327df3f5dSRui Paulo { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, 15427df3f5dSRui Paulo { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, 155b5bfcb5dSMax Laier { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, 15627df3f5dSRui Paulo { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, 1571de50e9fSSam Leffler { 0, NULL} 1581de50e9fSSam Leffler }; 1591de50e9fSSam Leffler 1601de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 1611de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 1621de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 1631de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 1643340d773SGleb Smirnoff /* not assigned 5 */ 1651de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 1661de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 1671de50e9fSSam Leffler #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 1683340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9 1693340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10 1703340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11 1713340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12 1723340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13 1733340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14 1743340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15 1753340d773SGleb Smirnoff #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16 1761de50e9fSSam Leffler 1771de50e9fSSam Leffler static const struct tok lspping_tlvtargetfec_subtlv_values[] = { 1781de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, 1791de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"}, 1801de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"}, 1811de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"}, 1821de50e9fSSam Leffler { 5, "Reserved"}, 1831de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, 1841de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, 1851de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, 1863340d773SGleb Smirnoff { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"}, 1873340d773SGleb Smirnoff { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"}, 1881de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, 1891de50e9fSSam Leffler { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, 1901de50e9fSSam Leffler { 0, NULL} 1911de50e9fSSam Leffler }; 1921de50e9fSSam Leffler 1931de50e9fSSam Leffler /* 1941de50e9fSSam Leffler * 0 1 2 3 1951de50e9fSSam 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 1961de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1971de50e9fSSam Leffler * | IPv4 prefix | 1981de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1991de50e9fSSam Leffler * | Prefix Length | Must Be Zero | 2001de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2011de50e9fSSam Leffler */ 2021de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { 203*ee67461eSJoseph Mingrone nd_ipv4 prefix; 204*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 2051de50e9fSSam Leffler }; 2061de50e9fSSam Leffler 2071de50e9fSSam Leffler /* 2081de50e9fSSam Leffler * 0 1 2 3 2091de50e9fSSam 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 2101de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2111de50e9fSSam Leffler * | IPv6 prefix | 2121de50e9fSSam Leffler * | (16 octets) | 2131de50e9fSSam Leffler * | | 2141de50e9fSSam Leffler * | | 2151de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2161de50e9fSSam Leffler * | Prefix Length | Must Be Zero | 2171de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2181de50e9fSSam Leffler */ 2191de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { 220*ee67461eSJoseph Mingrone nd_ipv6 prefix; 221*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 2221de50e9fSSam Leffler }; 2231de50e9fSSam Leffler 2241de50e9fSSam Leffler /* 2251de50e9fSSam Leffler * 0 1 2 3 2261de50e9fSSam 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 2271de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2281de50e9fSSam Leffler * | IPv4 tunnel end point address | 2291de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2301de50e9fSSam Leffler * | Must Be Zero | Tunnel ID | 2311de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2321de50e9fSSam Leffler * | Extended Tunnel ID | 2331de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2341de50e9fSSam Leffler * | IPv4 tunnel sender address | 2351de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2361de50e9fSSam Leffler * | Must Be Zero | LSP ID | 2371de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2381de50e9fSSam Leffler */ 2391de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { 240*ee67461eSJoseph Mingrone nd_ipv4 tunnel_endpoint; 241*ee67461eSJoseph Mingrone nd_byte res[2]; 242*ee67461eSJoseph Mingrone nd_uint16_t tunnel_id; 243*ee67461eSJoseph Mingrone nd_ipv4 extended_tunnel_id; 244*ee67461eSJoseph Mingrone nd_ipv4 tunnel_sender; 245*ee67461eSJoseph Mingrone nd_byte res2[2]; 246*ee67461eSJoseph Mingrone nd_uint16_t lsp_id; 2471de50e9fSSam Leffler }; 2481de50e9fSSam Leffler 2491de50e9fSSam Leffler /* 2501de50e9fSSam Leffler * 0 1 2 3 2511de50e9fSSam 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 2521de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2531de50e9fSSam Leffler * | IPv6 tunnel end point address | 2541de50e9fSSam Leffler * | | 2551de50e9fSSam Leffler * | | 2561de50e9fSSam Leffler * | | 2571de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2581de50e9fSSam Leffler * | Must Be Zero | Tunnel ID | 2591de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2601de50e9fSSam Leffler * | Extended Tunnel ID | 2611de50e9fSSam Leffler * | | 2621de50e9fSSam Leffler * | | 2631de50e9fSSam Leffler * | | 2641de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2651de50e9fSSam Leffler * | IPv6 tunnel sender address | 2661de50e9fSSam Leffler * | | 2671de50e9fSSam Leffler * | | 2681de50e9fSSam Leffler * | | 2691de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2701de50e9fSSam Leffler * | Must Be Zero | LSP ID | 2711de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2721de50e9fSSam Leffler */ 2731de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { 274*ee67461eSJoseph Mingrone nd_ipv6 tunnel_endpoint; 275*ee67461eSJoseph Mingrone nd_byte res[2]; 276*ee67461eSJoseph Mingrone nd_uint16_t tunnel_id; 277*ee67461eSJoseph Mingrone nd_ipv6 extended_tunnel_id; 278*ee67461eSJoseph Mingrone nd_ipv6 tunnel_sender; 279*ee67461eSJoseph Mingrone nd_byte res2[2]; 280*ee67461eSJoseph Mingrone nd_uint16_t lsp_id; 2811de50e9fSSam Leffler }; 2821de50e9fSSam Leffler 2831de50e9fSSam Leffler /* 2841de50e9fSSam Leffler * 0 1 2 3 2851de50e9fSSam 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 2861de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2871de50e9fSSam Leffler * | Route Distinguisher | 2881de50e9fSSam Leffler * | (8 octets) | 2891de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2901de50e9fSSam Leffler * | IPv4 prefix | 2911de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2921de50e9fSSam Leffler * | Prefix Length | Must Be Zero | 2931de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2941de50e9fSSam Leffler */ 2951de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { 296*ee67461eSJoseph Mingrone nd_byte rd[8]; 297*ee67461eSJoseph Mingrone nd_ipv4 prefix; 298*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 2991de50e9fSSam Leffler }; 3001de50e9fSSam Leffler 3011de50e9fSSam Leffler /* 3021de50e9fSSam Leffler * 0 1 2 3 3031de50e9fSSam 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 3041de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3051de50e9fSSam Leffler * | Route Distinguisher | 3061de50e9fSSam Leffler * | (8 octets) | 3071de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3081de50e9fSSam Leffler * | IPv6 prefix | 3091de50e9fSSam Leffler * | (16 octets) | 3101de50e9fSSam Leffler * | | 3111de50e9fSSam Leffler * | | 3121de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3131de50e9fSSam Leffler * | Prefix Length | Must Be Zero | 3141de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3151de50e9fSSam Leffler */ 3161de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { 317*ee67461eSJoseph Mingrone nd_byte rd[8]; 318*ee67461eSJoseph Mingrone nd_ipv6 prefix; 319*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 3201de50e9fSSam Leffler }; 3211de50e9fSSam Leffler 3221de50e9fSSam Leffler /* 3231de50e9fSSam Leffler * 0 1 2 3 3241de50e9fSSam 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 3251de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3261de50e9fSSam Leffler * | Route Distinguisher | 3271de50e9fSSam Leffler * | (8 octets) | 3281de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3293340d773SGleb Smirnoff * | Sender's VE ID | Receiver's VE ID | 3301de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3311de50e9fSSam Leffler * | Encapsulation Type | Must Be Zero | 3321de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3331de50e9fSSam Leffler * 0 1 2 3 3341de50e9fSSam Leffler */ 3351de50e9fSSam Leffler struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { 336*ee67461eSJoseph Mingrone nd_byte rd[8]; 337*ee67461eSJoseph Mingrone nd_uint16_t sender_ve_id; 338*ee67461eSJoseph Mingrone nd_uint16_t receiver_ve_id; 339*ee67461eSJoseph Mingrone nd_uint16_t encapsulation; 3401de50e9fSSam Leffler }; 3411de50e9fSSam Leffler 3421de50e9fSSam Leffler /* 3431de50e9fSSam 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 3441de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3451de50e9fSSam Leffler * | Remote PE Address | 3461de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3473340d773SGleb Smirnoff * | PW ID | 3481de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3493340d773SGleb Smirnoff * | PW Type | Must Be Zero | 3501de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3511de50e9fSSam Leffler */ 3523340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_fec_128_pw_old { 353*ee67461eSJoseph Mingrone nd_ipv4 remote_pe_address; 354*ee67461eSJoseph Mingrone nd_uint32_t pw_id; 355*ee67461eSJoseph Mingrone nd_uint16_t pw_type; 3561de50e9fSSam Leffler }; 3571de50e9fSSam Leffler 3581de50e9fSSam Leffler /* 3591de50e9fSSam 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 3601de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3611de50e9fSSam Leffler * | Sender's PE Address | 3621de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3631de50e9fSSam Leffler * | Remote PE Address | 3641de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3653340d773SGleb Smirnoff * | PW ID | 3661de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3673340d773SGleb Smirnoff * | PW Type | Must Be Zero | 3681de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3691de50e9fSSam Leffler */ 3703340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_fec_128_pw { 371*ee67461eSJoseph Mingrone nd_ipv4 sender_pe_address; 372*ee67461eSJoseph Mingrone nd_ipv4 remote_pe_address; 373*ee67461eSJoseph Mingrone nd_uint32_t pw_id; 374*ee67461eSJoseph Mingrone nd_uint16_t pw_type; 3753340d773SGleb Smirnoff }; 3763340d773SGleb Smirnoff 3773340d773SGleb Smirnoff /* 3783340d773SGleb 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 3793340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3803340d773SGleb Smirnoff * | IPv4 prefix | 3813340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3823340d773SGleb Smirnoff * | Prefix Length | Must Be Zero | 3833340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3843340d773SGleb Smirnoff */ 3853340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { 386*ee67461eSJoseph Mingrone nd_ipv4 prefix; 387*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 3883340d773SGleb Smirnoff }; 3893340d773SGleb Smirnoff 3903340d773SGleb Smirnoff /* 3913340d773SGleb 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 3923340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3933340d773SGleb Smirnoff * | IPv6 prefix | 3943340d773SGleb Smirnoff * | (16 octets) | 3953340d773SGleb Smirnoff * | | 3963340d773SGleb Smirnoff * | | 3973340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3983340d773SGleb Smirnoff * | Prefix Length | Must Be Zero | 3993340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4003340d773SGleb Smirnoff */ 4013340d773SGleb Smirnoff struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { 402*ee67461eSJoseph Mingrone nd_ipv6 prefix; 403*ee67461eSJoseph Mingrone nd_uint8_t prefix_len; 4041de50e9fSSam Leffler }; 4051de50e9fSSam Leffler 4061de50e9fSSam Leffler /* 4071de50e9fSSam Leffler * 0 1 2 3 4081de50e9fSSam 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 4091de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4101de50e9fSSam Leffler * | MTU | Address Type | Resvd (SBZ) | 4111de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4121de50e9fSSam Leffler * | Downstream IP Address (4 or 16 octets) | 4131de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4141de50e9fSSam Leffler * | Downstream Interface Address (4 or 16 octets) | 4151de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4163340d773SGleb Smirnoff * | Multipath Type| Depth Limit | Multipath Length | 4171de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4181de50e9fSSam Leffler * . . 4191de50e9fSSam Leffler * . (Multipath Information) . 4201de50e9fSSam Leffler * . . 4211de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4221de50e9fSSam Leffler * | Downstream Label | Protocol | 4231de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4241de50e9fSSam Leffler * . . 4251de50e9fSSam Leffler * . . 4261de50e9fSSam Leffler * . . 4271de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4281de50e9fSSam Leffler * | Downstream Label | Protocol | 4291de50e9fSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4301de50e9fSSam Leffler */ 4313340d773SGleb Smirnoff /* Enough to get the address type */ 4323340d773SGleb Smirnoff struct lspping_tlv_downstream_map_t { 433*ee67461eSJoseph Mingrone nd_uint16_t mtu; 434*ee67461eSJoseph Mingrone nd_uint8_t address_type; 435*ee67461eSJoseph Mingrone nd_uint8_t ds_flags; 4363340d773SGleb Smirnoff }; 4373340d773SGleb Smirnoff 4381de50e9fSSam Leffler struct lspping_tlv_downstream_map_ipv4_t { 439*ee67461eSJoseph Mingrone nd_uint16_t mtu; 440*ee67461eSJoseph Mingrone nd_uint8_t address_type; 441*ee67461eSJoseph Mingrone nd_uint8_t ds_flags; 442*ee67461eSJoseph Mingrone nd_ipv4 downstream_ip; 443*ee67461eSJoseph Mingrone nd_ipv4 downstream_interface; 4443340d773SGleb Smirnoff }; 4453340d773SGleb Smirnoff 4463340d773SGleb Smirnoff struct lspping_tlv_downstream_map_ipv4_unmb_t { 447*ee67461eSJoseph Mingrone nd_uint16_t mtu; 448*ee67461eSJoseph Mingrone nd_uint8_t address_type; 449*ee67461eSJoseph Mingrone nd_uint8_t ds_flags; 450*ee67461eSJoseph Mingrone nd_ipv4 downstream_ip; 451*ee67461eSJoseph Mingrone nd_uint32_t downstream_interface; 4521de50e9fSSam Leffler }; 4531de50e9fSSam Leffler 4541de50e9fSSam Leffler struct lspping_tlv_downstream_map_ipv6_t { 455*ee67461eSJoseph Mingrone nd_uint16_t mtu; 456*ee67461eSJoseph Mingrone nd_uint8_t address_type; 457*ee67461eSJoseph Mingrone nd_uint8_t ds_flags; 458*ee67461eSJoseph Mingrone nd_ipv6 downstream_ip; 459*ee67461eSJoseph Mingrone nd_ipv6 downstream_interface; 4601de50e9fSSam Leffler }; 4611de50e9fSSam Leffler 4623340d773SGleb Smirnoff struct lspping_tlv_downstream_map_ipv6_unmb_t { 463*ee67461eSJoseph Mingrone nd_uint16_t mtu; 464*ee67461eSJoseph Mingrone nd_uint8_t address_type; 465*ee67461eSJoseph Mingrone nd_uint8_t ds_flags; 466*ee67461eSJoseph Mingrone nd_ipv6 downstream_ip; 467*ee67461eSJoseph Mingrone nd_uint32_t downstream_interface; 4683340d773SGleb Smirnoff }; 4693340d773SGleb Smirnoff 4701de50e9fSSam Leffler struct lspping_tlv_downstream_map_info_t { 471*ee67461eSJoseph Mingrone nd_uint8_t multipath_type; 472*ee67461eSJoseph Mingrone nd_uint8_t depth_limit; 473*ee67461eSJoseph Mingrone nd_uint16_t multipath_length; 4741de50e9fSSam Leffler }; 4751de50e9fSSam Leffler 4761de50e9fSSam Leffler #define LSPPING_AFI_IPV4 1 4773340d773SGleb Smirnoff #define LSPPING_AFI_IPV4_UNMB 2 4781de50e9fSSam Leffler #define LSPPING_AFI_IPV6 3 4793340d773SGleb Smirnoff #define LSPPING_AFI_IPV6_UNMB 4 4801de50e9fSSam Leffler 4811de50e9fSSam Leffler static const struct tok lspping_tlv_downstream_addr_values[] = { 4821de50e9fSSam Leffler { LSPPING_AFI_IPV4, "IPv4"}, 4833340d773SGleb Smirnoff { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"}, 4841de50e9fSSam Leffler { LSPPING_AFI_IPV6, "IPv6"}, 4853340d773SGleb Smirnoff { LSPPING_AFI_IPV6_UNMB, "IPv6"}, 4861de50e9fSSam Leffler { 0, NULL} 4871de50e9fSSam Leffler }; 4881de50e9fSSam Leffler 4891de50e9fSSam Leffler void 4903c602fabSXin LI lspping_print(netdissect_options *ndo, 491*ee67461eSJoseph Mingrone const u_char *pptr, u_int len) 4928bdc5a62SPatrick Kelsey { 4931de50e9fSSam Leffler const struct lspping_common_header *lspping_com_header; 4941de50e9fSSam Leffler const struct lspping_tlv_header *lspping_tlv_header; 4951de50e9fSSam Leffler const struct lspping_tlv_header *lspping_subtlv_header; 4961de50e9fSSam Leffler const u_char *tptr,*tlv_tptr,*subtlv_tptr; 497*ee67461eSJoseph Mingrone u_int return_code, return_subcode; 4983340d773SGleb Smirnoff u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; 4991de50e9fSSam Leffler int tlv_hexdump,subtlv_hexdump; 5003340d773SGleb Smirnoff u_int lspping_subtlv_len,lspping_subtlv_type; 501*ee67461eSJoseph Mingrone uint32_t int_part, fraction; 502*ee67461eSJoseph Mingrone u_int address_type; 5031de50e9fSSam Leffler 5041de50e9fSSam Leffler union { 5053340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map; 5061de50e9fSSam Leffler const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; 5073340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb; 5081de50e9fSSam Leffler const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; 5093340d773SGleb Smirnoff const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb; 5101de50e9fSSam Leffler const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; 5111de50e9fSSam Leffler } tlv_ptr; 5121de50e9fSSam Leffler 5131de50e9fSSam Leffler union { 5141de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; 5151de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6; 5161de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4; 5171de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6; 5181de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; 5191de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; 5201de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; 5213340d773SGleb Smirnoff const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; 5223340d773SGleb Smirnoff const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid; 5231de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; 5241de50e9fSSam Leffler const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; 5251de50e9fSSam Leffler } subtlv_ptr; 5261de50e9fSSam Leffler 527*ee67461eSJoseph Mingrone ndo->ndo_protocol = "lspping"; 5281de50e9fSSam Leffler tptr=pptr; 5291de50e9fSSam Leffler lspping_com_header = (const struct lspping_common_header *)pptr; 530*ee67461eSJoseph Mingrone if (len < sizeof(struct lspping_common_header)) 5313340d773SGleb Smirnoff goto tooshort; 532*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(lspping_com_header); 5331de50e9fSSam Leffler 5341de50e9fSSam Leffler /* 5351de50e9fSSam Leffler * Sanity checking of the header. 5361de50e9fSSam Leffler */ 537*ee67461eSJoseph Mingrone if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) { 538*ee67461eSJoseph Mingrone ND_PRINT("LSP-PING version %u packet not supported", 539*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version)); 5401de50e9fSSam Leffler return; 5411de50e9fSSam Leffler } 5421de50e9fSSam Leffler 5431de50e9fSSam Leffler /* in non-verbose mode just lets print the basic Message Type*/ 5443c602fabSXin LI if (ndo->ndo_vflag < 1) { 545*ee67461eSJoseph Mingrone ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u", 546*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version), 547*ee67461eSJoseph Mingrone tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)), 548*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->seq_number), 549*ee67461eSJoseph Mingrone len); 5501de50e9fSSam Leffler return; 5511de50e9fSSam Leffler } 5521de50e9fSSam Leffler 5531de50e9fSSam Leffler /* ok they seem to want to know everything - lets fully decode it */ 5541de50e9fSSam Leffler 5551de50e9fSSam Leffler tlen=len; 5561de50e9fSSam Leffler 557*ee67461eSJoseph Mingrone ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", 558*ee67461eSJoseph Mingrone GET_BE_U_2(lspping_com_header->version), 559*ee67461eSJoseph Mingrone tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)), 560*ee67461eSJoseph Mingrone GET_U_1(lspping_com_header->msg_type), 561f4d0c64aSSam Leffler len, 562*ee67461eSJoseph Mingrone tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)), 563*ee67461eSJoseph Mingrone GET_U_1(lspping_com_header->reply_mode)); 5641de50e9fSSam Leffler 5651de50e9fSSam Leffler /* 5661de50e9fSSam Leffler * the following return codes require that the subcode is attached 5671de50e9fSSam Leffler * at the end of the translated token output 5681de50e9fSSam Leffler */ 569*ee67461eSJoseph Mingrone return_code = GET_U_1(lspping_com_header->return_code); 570*ee67461eSJoseph Mingrone return_subcode = GET_U_1(lspping_com_header->return_subcode); 571*ee67461eSJoseph Mingrone if (return_code == 3 || 572*ee67461eSJoseph Mingrone return_code == 4 || 573*ee67461eSJoseph Mingrone return_code == 8 || 574*ee67461eSJoseph Mingrone return_code == 10 || 575*ee67461eSJoseph Mingrone return_code == 11 || 576*ee67461eSJoseph Mingrone return_code == 12 ) 577*ee67461eSJoseph Mingrone ND_PRINT("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", 578*ee67461eSJoseph Mingrone tok2str(lspping_return_code_values, "unknown",return_code), 579*ee67461eSJoseph Mingrone return_subcode, 580*ee67461eSJoseph Mingrone return_code, 581*ee67461eSJoseph Mingrone return_subcode); 5821de50e9fSSam Leffler else 583*ee67461eSJoseph Mingrone ND_PRINT("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", 584*ee67461eSJoseph Mingrone tok2str(lspping_return_code_values, "unknown",return_code), 585*ee67461eSJoseph Mingrone return_code, 586*ee67461eSJoseph Mingrone return_subcode); 5871de50e9fSSam Leffler 588*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender Handle: 0x%08x, Sequence: %u", 589*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->sender_handle), 590*ee67461eSJoseph Mingrone GET_BE_U_4(lspping_com_header->seq_number)); 5911de50e9fSSam Leffler 592*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender Timestamp: "); 593*ee67461eSJoseph Mingrone p_ntp_time(ndo, &lspping_com_header->ts_sent); 594*ee67461eSJoseph Mingrone ND_PRINT(" "); 5951de50e9fSSam Leffler 596*ee67461eSJoseph Mingrone int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part); 597*ee67461eSJoseph Mingrone fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction); 598*ee67461eSJoseph Mingrone ND_PRINT("Receiver Timestamp: "); 599*ee67461eSJoseph Mingrone if (! (int_part == 0 && fraction == 0)) 600*ee67461eSJoseph Mingrone p_ntp_time(ndo, &lspping_com_header->ts_rcvd); 6011de50e9fSSam Leffler else 602*ee67461eSJoseph Mingrone ND_PRINT("no timestamp"); 6031de50e9fSSam Leffler 604*ee67461eSJoseph Mingrone tptr+=sizeof(struct lspping_common_header); 605*ee67461eSJoseph Mingrone tlen-=sizeof(struct lspping_common_header); 6061de50e9fSSam Leffler 6073340d773SGleb Smirnoff while (tlen != 0) { 6083340d773SGleb Smirnoff /* Does the TLV go past the end of the packet? */ 6093340d773SGleb Smirnoff if (tlen < sizeof(struct lspping_tlv_header)) 6103340d773SGleb Smirnoff goto tooshort; 61127df3f5dSRui Paulo 6121de50e9fSSam Leffler lspping_tlv_header = (const struct lspping_tlv_header *)tptr; 613*ee67461eSJoseph Mingrone lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type); 614*ee67461eSJoseph Mingrone lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length); 6151de50e9fSSam Leffler 616*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s TLV (%u), length: %u", 6171de50e9fSSam Leffler tok2str(lspping_tlv_values, 6181de50e9fSSam Leffler "Unknown", 6191de50e9fSSam Leffler lspping_tlv_type), 6201de50e9fSSam Leffler lspping_tlv_type, 621*ee67461eSJoseph Mingrone lspping_tlv_len); 6221de50e9fSSam Leffler 6233340d773SGleb Smirnoff /* some little sanity checking */ 6243340d773SGleb Smirnoff if (lspping_tlv_len == 0) { 6253340d773SGleb Smirnoff tptr+=sizeof(struct lspping_tlv_header); 6263340d773SGleb Smirnoff tlen-=sizeof(struct lspping_tlv_header); 6273340d773SGleb Smirnoff continue; /* no value to dissect */ 6283340d773SGleb Smirnoff } 6293340d773SGleb Smirnoff 6301de50e9fSSam Leffler tlv_tptr=tptr+sizeof(struct lspping_tlv_header); 6311de50e9fSSam Leffler tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ 6321de50e9fSSam Leffler 6333340d773SGleb Smirnoff /* Does the TLV go past the end of the packet? */ 6343340d773SGleb Smirnoff if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 6353340d773SGleb Smirnoff goto tooshort; 6361de50e9fSSam Leffler /* did we capture enough for fully decoding the tlv ? */ 637*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len); 6381de50e9fSSam Leffler tlv_hexdump=FALSE; 6391de50e9fSSam Leffler 6401de50e9fSSam Leffler switch(lspping_tlv_type) { 6411de50e9fSSam Leffler case LSPPING_TLV_TARGET_FEC_STACK: 6423340d773SGleb Smirnoff while (tlv_tlen != 0) { 6433340d773SGleb Smirnoff /* Does the subTLV header go past the end of the TLV? */ 6443340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_header)) { 645*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 6463340d773SGleb Smirnoff tlv_hexdump = TRUE; 6473340d773SGleb Smirnoff goto tlv_tooshort; 6483340d773SGleb Smirnoff } 6491de50e9fSSam Leffler subtlv_hexdump=FALSE; 6501de50e9fSSam Leffler 6511de50e9fSSam Leffler lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; 652*ee67461eSJoseph Mingrone lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type); 653*ee67461eSJoseph Mingrone lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length); 6541de50e9fSSam Leffler subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); 6551de50e9fSSam Leffler 6563340d773SGleb Smirnoff /* Does the subTLV go past the end of the TLV? */ 6573340d773SGleb Smirnoff if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { 658*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 6593340d773SGleb Smirnoff tlv_hexdump = TRUE; 6603340d773SGleb Smirnoff goto tlv_tooshort; 6613340d773SGleb Smirnoff } 6623340d773SGleb Smirnoff 6633340d773SGleb Smirnoff /* Did we capture enough for fully decoding the subTLV? */ 664*ee67461eSJoseph Mingrone ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len); 6651de50e9fSSam Leffler 666*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s subTLV (%u), length: %u", 6671de50e9fSSam Leffler tok2str(lspping_tlvtargetfec_subtlv_values, 6681de50e9fSSam Leffler "Unknown", 6691de50e9fSSam Leffler lspping_subtlv_type), 6701de50e9fSSam Leffler lspping_subtlv_type, 671*ee67461eSJoseph Mingrone lspping_subtlv_len); 6721de50e9fSSam Leffler 6731de50e9fSSam Leffler switch(lspping_subtlv_type) { 6741de50e9fSSam Leffler 6751de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4: 6763340d773SGleb Smirnoff /* Is the subTLV length correct? */ 6773340d773SGleb Smirnoff if (lspping_subtlv_len != 5) { 678*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 5"); 6793340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 6803340d773SGleb Smirnoff } else { 681*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = 6821de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr; 683*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u", 684*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), 685*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len)); 6863340d773SGleb Smirnoff } 6871de50e9fSSam Leffler break; 6881de50e9fSSam Leffler 6891de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6: 6903340d773SGleb Smirnoff /* Is the subTLV length correct? */ 6913340d773SGleb Smirnoff if (lspping_subtlv_len != 17) { 692*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 17"); 6933340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 6943340d773SGleb Smirnoff } else { 695*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = 6961de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr; 697*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u", 698*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), 699*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len)); 7003340d773SGleb Smirnoff } 7011de50e9fSSam Leffler break; 7021de50e9fSSam Leffler 7031de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4: 7043340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7053340d773SGleb Smirnoff if (lspping_subtlv_len != 5) { 706*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 5"); 7073340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7083340d773SGleb Smirnoff } else { 709*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = 7101de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr; 711*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u", 712*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), 713*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len)); 7143340d773SGleb Smirnoff } 7151de50e9fSSam Leffler break; 7161de50e9fSSam Leffler 7171de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6: 7183340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7193340d773SGleb Smirnoff if (lspping_subtlv_len != 17) { 720*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 17"); 7213340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7223340d773SGleb Smirnoff } else { 723*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = 7241de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr; 725*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s/%u", 726*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), 727*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len)); 7283340d773SGleb Smirnoff } 7291de50e9fSSam Leffler break; 7301de50e9fSSam Leffler 7311de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4: 7323340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7333340d773SGleb Smirnoff if (lspping_subtlv_len != 20) { 734*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 20"); 7353340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7363340d773SGleb Smirnoff } else { 737*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = 7381de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr; 739*ee67461eSJoseph Mingrone ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" 7401de50e9fSSam Leffler "\n\t tunnel-id 0x%04x, extended tunnel-id %s", 741*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), 742*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), 743*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), 744*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), 745*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)); 7463340d773SGleb Smirnoff } 7471de50e9fSSam Leffler break; 7481de50e9fSSam Leffler 7491de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6: 7503340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7513340d773SGleb Smirnoff if (lspping_subtlv_len != 56) { 752*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 56"); 7533340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7543340d773SGleb Smirnoff } else { 755*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = 7561de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr; 757*ee67461eSJoseph Mingrone ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" 7581de50e9fSSam Leffler "\n\t tunnel-id 0x%04x, extended tunnel-id %s", 759*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), 760*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), 761*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), 762*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), 763*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)); 7643340d773SGleb Smirnoff } 7651de50e9fSSam Leffler break; 7661de50e9fSSam Leffler 7671de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4: 7683340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7693340d773SGleb Smirnoff if (lspping_subtlv_len != 13) { 770*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 13"); 7713340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7723340d773SGleb Smirnoff } else { 773*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = 7741de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; 775*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, %s/%u", 7763c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), 777*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), 778*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len)); 7793340d773SGleb Smirnoff } 7801de50e9fSSam Leffler break; 7811de50e9fSSam Leffler 7821de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6: 7833340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7843340d773SGleb Smirnoff if (lspping_subtlv_len != 25) { 785*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 25"); 7863340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 7873340d773SGleb Smirnoff } else { 788*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = 7891de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; 790*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, %s/%u", 7913c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), 792*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), 793*ee67461eSJoseph Mingrone GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len)); 7943340d773SGleb Smirnoff } 7951de50e9fSSam Leffler break; 7961de50e9fSSam Leffler 7971de50e9fSSam Leffler case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT: 7983340d773SGleb Smirnoff /* Is the subTLV length correct? */ 7993340d773SGleb Smirnoff if (lspping_subtlv_len != 14) { 800*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 14"); 8013340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 8023340d773SGleb Smirnoff } else { 803*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = 8041de50e9fSSam Leffler (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr; 805*ee67461eSJoseph Mingrone ND_PRINT("\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u" 8061de50e9fSSam Leffler "\n\t Encapsulation Type: %s (%u)", 8073c602fabSXin LI bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd), 808*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id), 809*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id), 8103340d773SGleb Smirnoff tok2str(mpls_pw_types_values, 8111de50e9fSSam Leffler "unknown", 812*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), 813*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)); 8143340d773SGleb Smirnoff } 8151de50e9fSSam Leffler break; 8161de50e9fSSam Leffler 8171de50e9fSSam Leffler /* the old L2VPN VCID subTLV does not have support for the sender field */ 8183340d773SGleb Smirnoff case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD: 8193340d773SGleb Smirnoff /* Is the subTLV length correct? */ 8203340d773SGleb Smirnoff if (lspping_subtlv_len != 10) { 821*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 10"); 8223340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 8233340d773SGleb Smirnoff } else { 824*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = 8253340d773SGleb Smirnoff (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr; 826*ee67461eSJoseph Mingrone ND_PRINT("\n\t Remote PE: %s" 8273340d773SGleb Smirnoff "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 828*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), 829*ee67461eSJoseph Mingrone GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id), 8303340d773SGleb Smirnoff tok2str(mpls_pw_types_values, 8311de50e9fSSam Leffler "unknown", 832*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)), 833*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)); 8343340d773SGleb Smirnoff } 8351de50e9fSSam Leffler break; 8361de50e9fSSam Leffler 8373340d773SGleb Smirnoff case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW: 8383340d773SGleb Smirnoff /* Is the subTLV length correct? */ 8393340d773SGleb Smirnoff if (lspping_subtlv_len != 14) { 840*ee67461eSJoseph Mingrone ND_PRINT("\n\t invalid subTLV length, should be 14"); 8413340d773SGleb Smirnoff subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 8423340d773SGleb Smirnoff } else { 843*ee67461eSJoseph Mingrone subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = 8443340d773SGleb Smirnoff (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr; 845*ee67461eSJoseph Mingrone ND_PRINT("\n\t Sender PE: %s, Remote PE: %s" 8463340d773SGleb Smirnoff "\n\t PW ID: 0x%08x, PW Type: %s (%u)", 847*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), 848*ee67461eSJoseph Mingrone GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), 849*ee67461eSJoseph Mingrone GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id), 8503340d773SGleb Smirnoff tok2str(mpls_pw_types_values, 8511de50e9fSSam Leffler "unknown", 852*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)), 853*ee67461eSJoseph Mingrone GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)); 8543340d773SGleb Smirnoff } 8551de50e9fSSam Leffler break; 8561de50e9fSSam Leffler 8571de50e9fSSam Leffler default: 8581de50e9fSSam Leffler subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ 8591de50e9fSSam Leffler break; 8601de50e9fSSam Leffler } 8611de50e9fSSam Leffler /* do we want to see an additionally subtlv hexdump ? */ 8623c602fabSXin LI if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE) 863*ee67461eSJoseph Mingrone print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), 8641de50e9fSSam Leffler "\n\t ", 8651de50e9fSSam Leffler lspping_subtlv_len); 8661de50e9fSSam Leffler 8673340d773SGleb Smirnoff /* All subTLVs are aligned to four octet boundary */ 8683340d773SGleb Smirnoff if (lspping_subtlv_len % 4) { 8693340d773SGleb Smirnoff lspping_subtlv_len += 4 - (lspping_subtlv_len % 4); 8703340d773SGleb Smirnoff /* Does the subTLV, including padding, go past the end of the TLV? */ 8713340d773SGleb Smirnoff if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) { 872*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t TLV is too short"); 8733340d773SGleb Smirnoff return; 8743340d773SGleb Smirnoff } 8753340d773SGleb Smirnoff } 8761de50e9fSSam Leffler tlv_tptr+=lspping_subtlv_len; 8771de50e9fSSam Leffler tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header); 8781de50e9fSSam Leffler } 8791de50e9fSSam Leffler break; 8801de50e9fSSam Leffler 8811de50e9fSSam Leffler case LSPPING_TLV_DOWNSTREAM_MAPPING: 8823340d773SGleb Smirnoff /* Does the header go past the end of the TLV? */ 8833340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) { 884*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 8853340d773SGleb Smirnoff tlv_hexdump = TRUE; 8863340d773SGleb Smirnoff goto tlv_tooshort; 8873340d773SGleb Smirnoff } 8883340d773SGleb Smirnoff /* Did we capture enough to get the address family? */ 889*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 890*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_t)); 8913340d773SGleb Smirnoff 892*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map= 8933340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_t *)tlv_tptr; 8943340d773SGleb Smirnoff 8951de50e9fSSam Leffler /* that strange thing with the downstream map TLV is that until now 8963340d773SGleb Smirnoff * we do not know if its IPv4 or IPv6 or is unnumbered; after 8973340d773SGleb Smirnoff * we find the address-type, we recast the tlv_tptr and move on. */ 8983340d773SGleb Smirnoff 899*ee67461eSJoseph Mingrone address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type); 900*ee67461eSJoseph Mingrone ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)", 901*ee67461eSJoseph Mingrone GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu), 9023340d773SGleb Smirnoff tok2str(lspping_tlv_downstream_addr_values, 9033340d773SGleb Smirnoff "unknown", 904*ee67461eSJoseph Mingrone address_type), 905*ee67461eSJoseph Mingrone address_type); 9063340d773SGleb Smirnoff 907*ee67461eSJoseph Mingrone switch(address_type) { 9083340d773SGleb Smirnoff 9093340d773SGleb Smirnoff case LSPPING_AFI_IPV4: 9103340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */ 9113340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) { 912*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 9133340d773SGleb Smirnoff tlv_hexdump = TRUE; 9143340d773SGleb Smirnoff goto tlv_tooshort; 9153340d773SGleb Smirnoff } 9163340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */ 917*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 918*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv4_t)); 9191de50e9fSSam Leffler 920*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv4= 9211de50e9fSSam Leffler (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; 922*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s" 9231de50e9fSSam Leffler "\n\t Downstream Interface IP: %s", 924*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), 925*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); 9261de50e9fSSam Leffler tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 9271de50e9fSSam Leffler tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); 9281de50e9fSSam Leffler break; 9293340d773SGleb Smirnoff case LSPPING_AFI_IPV4_UNMB: 9303340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */ 9313340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) { 932*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 9333340d773SGleb Smirnoff tlv_hexdump = TRUE; 9343340d773SGleb Smirnoff goto tlv_tooshort; 9353340d773SGleb Smirnoff } 9363340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */ 937*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 938*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)); 9393340d773SGleb Smirnoff 940*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= 9413340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr; 942*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s" 9433340d773SGleb Smirnoff "\n\t Downstream Interface Index: 0x%08x", 944*ee67461eSJoseph Mingrone GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip), 945*ee67461eSJoseph Mingrone GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface)); 9463340d773SGleb Smirnoff tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 9473340d773SGleb Smirnoff tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t); 9483340d773SGleb Smirnoff break; 9491de50e9fSSam Leffler case LSPPING_AFI_IPV6: 9503340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */ 9513340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) { 952*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 9533340d773SGleb Smirnoff tlv_hexdump = TRUE; 9543340d773SGleb Smirnoff goto tlv_tooshort; 9553340d773SGleb Smirnoff } 9563340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */ 957*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 958*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv6_t)); 9593340d773SGleb Smirnoff 960*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv6= 9613340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; 962*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s" 9631de50e9fSSam Leffler "\n\t Downstream Interface IP: %s", 964*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), 965*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); 9661de50e9fSSam Leffler tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 9671de50e9fSSam Leffler tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); 9681de50e9fSSam Leffler break; 9693340d773SGleb Smirnoff case LSPPING_AFI_IPV6_UNMB: 9703340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */ 9713340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) { 972*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 9733340d773SGleb Smirnoff tlv_hexdump = TRUE; 9743340d773SGleb Smirnoff goto tlv_tooshort; 9753340d773SGleb Smirnoff } 9763340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */ 977*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 978*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)); 9793340d773SGleb Smirnoff 980*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= 9813340d773SGleb Smirnoff (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr; 982*ee67461eSJoseph Mingrone ND_PRINT("\n\t Downstream IP: %s" 9831de50e9fSSam Leffler "\n\t Downstream Interface Index: 0x%08x", 984*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip), 985*ee67461eSJoseph Mingrone GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface)); 9863340d773SGleb Smirnoff tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 9873340d773SGleb Smirnoff tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t); 9881de50e9fSSam Leffler break; 9891de50e9fSSam Leffler 9901de50e9fSSam Leffler default: 9911de50e9fSSam Leffler /* should not happen ! - no error message - tok2str() has barked already */ 9921de50e9fSSam Leffler break; 9931de50e9fSSam Leffler } 9941de50e9fSSam Leffler 9953340d773SGleb Smirnoff /* Does the data go past the end of the TLV? */ 9963340d773SGleb Smirnoff if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) { 997*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 9983340d773SGleb Smirnoff tlv_hexdump = TRUE; 9993340d773SGleb Smirnoff goto tlv_tooshort; 10003340d773SGleb Smirnoff } 10013340d773SGleb Smirnoff /* Did we capture enough for this part of the TLV? */ 1002*ee67461eSJoseph Mingrone ND_TCHECK_LEN(tlv_tptr, 1003*ee67461eSJoseph Mingrone sizeof(struct lspping_tlv_downstream_map_info_t)); 10043340d773SGleb Smirnoff 1005*ee67461eSJoseph Mingrone tlv_ptr.lspping_tlv_downstream_map_info= 10061de50e9fSSam Leffler (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; 10071de50e9fSSam Leffler 10081de50e9fSSam Leffler /* FIXME add hash-key type, depth limit, multipath processing */ 10091de50e9fSSam Leffler 10101de50e9fSSam Leffler /* FIXME print downstream labels */ 10111de50e9fSSam Leffler 10121de50e9fSSam Leffler tlv_hexdump=TRUE; /* dump the TLV until code complete */ 10131de50e9fSSam Leffler 10141de50e9fSSam Leffler break; 10151de50e9fSSam Leffler 1016b5bfcb5dSMax Laier case LSPPING_TLV_BFD_DISCRIMINATOR: 10173340d773SGleb Smirnoff if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) { 1018*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 10193340d773SGleb Smirnoff tlv_hexdump = TRUE; 10203340d773SGleb Smirnoff goto tlv_tooshort; 10213340d773SGleb Smirnoff } else { 1022*ee67461eSJoseph Mingrone ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr)); 10233340d773SGleb Smirnoff } 1024b5bfcb5dSMax Laier break; 102527df3f5dSRui Paulo 102627df3f5dSRui Paulo case LSPPING_TLV_VENDOR_ENTERPRISE: 102727df3f5dSRui Paulo { 10283c602fabSXin LI uint32_t vendor_id; 102927df3f5dSRui Paulo 10303340d773SGleb Smirnoff if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) { 1031*ee67461eSJoseph Mingrone ND_PRINT("\n\t TLV is too short"); 10323340d773SGleb Smirnoff tlv_hexdump = TRUE; 10333340d773SGleb Smirnoff goto tlv_tooshort; 10343340d773SGleb Smirnoff } else { 1035*ee67461eSJoseph Mingrone vendor_id = GET_BE_U_4(tlv_tptr); 1036*ee67461eSJoseph Mingrone ND_PRINT("\n\t Vendor: %s (0x%04x)", 103727df3f5dSRui Paulo tok2str(smi_values, "Unknown", vendor_id), 1038*ee67461eSJoseph Mingrone vendor_id); 103927df3f5dSRui Paulo } 10403340d773SGleb Smirnoff } 104127df3f5dSRui Paulo break; 104227df3f5dSRui Paulo 10431de50e9fSSam Leffler /* 10441de50e9fSSam Leffler * FIXME those are the defined TLVs that lack a decoder 10451de50e9fSSam Leffler * you are welcome to contribute code ;-) 10461de50e9fSSam Leffler */ 10471de50e9fSSam Leffler case LSPPING_TLV_PAD: 10481de50e9fSSam Leffler case LSPPING_TLV_ERROR_CODE: 10491de50e9fSSam Leffler case LSPPING_TLV_VENDOR_PRIVATE: 10501de50e9fSSam Leffler 10511de50e9fSSam Leffler default: 10523c602fabSXin LI if (ndo->ndo_vflag <= 1) 10533c602fabSXin LI print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen); 10541de50e9fSSam Leffler break; 10551de50e9fSSam Leffler } 10561de50e9fSSam Leffler /* do we want to see an additionally tlv hexdump ? */ 10573340d773SGleb Smirnoff tlv_tooshort: 10583c602fabSXin LI if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE) 10593c602fabSXin LI print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ", 10601de50e9fSSam Leffler lspping_tlv_len); 10611de50e9fSSam Leffler 1062a5779b6eSRui Paulo 1063a5779b6eSRui Paulo /* All TLVs are aligned to four octet boundary */ 1064a5779b6eSRui Paulo if (lspping_tlv_len % 4) { 1065a5779b6eSRui Paulo lspping_tlv_len += (4 - lspping_tlv_len % 4); 10663340d773SGleb Smirnoff /* Does the TLV, including padding, go past the end of the packet? */ 10673340d773SGleb Smirnoff if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header)) 10683340d773SGleb Smirnoff goto tooshort; 1069a5779b6eSRui Paulo } 1070a5779b6eSRui Paulo 1071f4d0c64aSSam Leffler tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); 10721de50e9fSSam Leffler tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); 10731de50e9fSSam Leffler } 10741de50e9fSSam Leffler return; 10753340d773SGleb Smirnoff tooshort: 1076*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t packet is too short"); 10771de50e9fSSam Leffler } 1078