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