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 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