xref: /aosp_15_r20/external/tcpdump/print-lspping.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
3*05b00f60SXin Li  * modification, are permitted provided that: (1) source code
4*05b00f60SXin Li  * distributions retain the above copyright notice and this paragraph
5*05b00f60SXin Li  * in its entirety, and (2) distributions including binary code include
6*05b00f60SXin Li  * the above copyright notice and this paragraph in its entirety in
7*05b00f60SXin Li  * the documentation or other materials provided with the distribution.
8*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9*05b00f60SXin Li  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10*05b00f60SXin Li  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11*05b00f60SXin Li  * FOR A PARTICULAR PURPOSE.
12*05b00f60SXin Li  *
13*05b00f60SXin Li  * Original code by Hannes Gredler ([email protected])
14*05b00f60SXin Li  */
15*05b00f60SXin Li 
16*05b00f60SXin Li /* \summary: MPLS LSP PING printer */
17*05b00f60SXin Li 
18*05b00f60SXin Li /* specification: RFC 4379 */
19*05b00f60SXin Li 
20*05b00f60SXin Li #ifdef HAVE_CONFIG_H
21*05b00f60SXin Li #include <config.h>
22*05b00f60SXin Li #endif
23*05b00f60SXin Li 
24*05b00f60SXin Li #include "netdissect-stdinc.h"
25*05b00f60SXin Li 
26*05b00f60SXin Li #define ND_LONGJMP_FROM_TCHECK
27*05b00f60SXin Li #include "netdissect.h"
28*05b00f60SXin Li #include "extract.h"
29*05b00f60SXin Li #include "addrtoname.h"
30*05b00f60SXin Li #include "ntp.h"
31*05b00f60SXin Li 
32*05b00f60SXin Li #include "l2vpn.h"
33*05b00f60SXin Li #include "oui.h"
34*05b00f60SXin Li 
35*05b00f60SXin Li 
36*05b00f60SXin Li /*
37*05b00f60SXin Li  * LSPPING common header
38*05b00f60SXin Li  *
39*05b00f60SXin Li  *  0                   1                   2                   3
40*05b00f60SXin Li  *  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
41*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42*05b00f60SXin Li  * |         Version Number        |         Must Be Zero          |
43*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44*05b00f60SXin Li  * |  Message Type |   Reply mode  |  Return Code  | Return Subcode|
45*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46*05b00f60SXin Li  * |                        Sender's Handle                        |
47*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48*05b00f60SXin Li  * |                        Sequence Number                        |
49*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50*05b00f60SXin Li  * |                    TimeStamp Sent (seconds)                   |
51*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52*05b00f60SXin Li  * |                  TimeStamp Sent (microseconds)                |
53*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54*05b00f60SXin Li  * |                  TimeStamp Received (seconds)                 |
55*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56*05b00f60SXin Li  * |                TimeStamp Received (microseconds)              |
57*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58*05b00f60SXin Li  * |                            TLVs ...                           |
59*05b00f60SXin Li  * .                                                               .
60*05b00f60SXin Li  * .                                                               .
61*05b00f60SXin Li  * .                                                               .
62*05b00f60SXin Li  */
63*05b00f60SXin Li 
64*05b00f60SXin Li struct lspping_common_header {
65*05b00f60SXin Li     nd_uint16_t version;
66*05b00f60SXin Li     nd_uint16_t global_flags;
67*05b00f60SXin Li     nd_uint8_t  msg_type;
68*05b00f60SXin Li     nd_uint8_t  reply_mode;
69*05b00f60SXin Li     nd_uint8_t  return_code;
70*05b00f60SXin Li     nd_uint8_t  return_subcode;
71*05b00f60SXin Li     nd_uint32_t sender_handle;
72*05b00f60SXin Li     nd_uint32_t seq_number;
73*05b00f60SXin Li     struct l_fixedpt ts_sent;
74*05b00f60SXin Li     struct l_fixedpt ts_rcvd;
75*05b00f60SXin Li };
76*05b00f60SXin Li 
77*05b00f60SXin Li #define LSPPING_VERSION            1
78*05b00f60SXin Li 
79*05b00f60SXin Li static const struct tok lspping_msg_type_values[] = {
80*05b00f60SXin Li     { 1, "MPLS Echo Request"},
81*05b00f60SXin Li     { 2, "MPLS Echo Reply"},
82*05b00f60SXin Li     { 0, NULL}
83*05b00f60SXin Li };
84*05b00f60SXin Li 
85*05b00f60SXin Li static const struct tok lspping_reply_mode_values[] = {
86*05b00f60SXin Li     { 1, "Do not reply"},
87*05b00f60SXin Li     { 2, "Reply via an IPv4/IPv6 UDP packet"},
88*05b00f60SXin Li     { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
89*05b00f60SXin Li     { 4, "Reply via application level control channel"},
90*05b00f60SXin Li     { 0, NULL}
91*05b00f60SXin Li };
92*05b00f60SXin Li 
93*05b00f60SXin Li static const struct tok lspping_return_code_values[] = {
94*05b00f60SXin Li     {  0, "No return code or return code contained in the Error Code TLV"},
95*05b00f60SXin Li     {  1, "Malformed echo request received"},
96*05b00f60SXin Li     {  2, "One or more of the TLVs was not understood"},
97*05b00f60SXin Li     {  3, "Replying router is an egress for the FEC at stack depth"},
98*05b00f60SXin Li     {  4, "Replying router has no mapping for the FEC at stack depth"},
99*05b00f60SXin Li     {  5, "Reserved"},
100*05b00f60SXin Li     {  6, "Reserved"},
101*05b00f60SXin Li     {  7, "Reserved"},
102*05b00f60SXin Li     {  8, "Label switched at stack-depth"},
103*05b00f60SXin Li     {  9, "Label switched but no MPLS forwarding at stack-depth"},
104*05b00f60SXin Li     { 10, "Mapping for this FEC is not the given label at stack depth"},
105*05b00f60SXin Li     { 11, "No label entry at stack-depth"},
106*05b00f60SXin Li     { 12, "Protocol not associated with interface at FEC stack depth"},
107*05b00f60SXin Li     { 13, "Premature termination of ping due to label stack shrinking to a single label"},
108*05b00f60SXin Li     { 0,  NULL},
109*05b00f60SXin Li };
110*05b00f60SXin Li 
111*05b00f60SXin Li 
112*05b00f60SXin Li /*
113*05b00f60SXin Li  * LSPPING TLV header
114*05b00f60SXin Li  *  0                   1                   2                   3
115*05b00f60SXin Li  *  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
116*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117*05b00f60SXin Li  * |             Type              |            Length             |
118*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119*05b00f60SXin Li  * |                             Value                             |
120*05b00f60SXin Li  * .                                                               .
121*05b00f60SXin Li  * .                                                               .
122*05b00f60SXin Li  * .                                                               .
123*05b00f60SXin Li  * |                                                               |
124*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125*05b00f60SXin Li  */
126*05b00f60SXin Li 
127*05b00f60SXin Li struct lspping_tlv_header {
128*05b00f60SXin Li     nd_uint16_t type;
129*05b00f60SXin Li     nd_uint16_t length;
130*05b00f60SXin Li };
131*05b00f60SXin Li 
132*05b00f60SXin Li #define	LSPPING_TLV_TARGET_FEC_STACK      1
133*05b00f60SXin Li #define	LSPPING_TLV_DOWNSTREAM_MAPPING    2
134*05b00f60SXin Li #define	LSPPING_TLV_PAD                   3
135*05b00f60SXin Li /* not assigned                           4 */
136*05b00f60SXin Li #define LSPPING_TLV_VENDOR_ENTERPRISE     5
137*05b00f60SXin Li #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
138*05b00f60SXin Li /* not assigned                           6 */
139*05b00f60SXin Li #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
140*05b00f60SXin Li /* not assigned                           8 */
141*05b00f60SXin Li #define	LSPPING_TLV_ERROR_CODE            9
142*05b00f60SXin Li #define LSPPING_TLV_REPLY_TOS_BYTE        10
143*05b00f60SXin Li #define	LSPPING_TLV_BFD_DISCRIMINATOR     15 /* draft-ietf-bfd-mpls-02 */
144*05b00f60SXin Li #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
145*05b00f60SXin Li #define	LSPPING_TLV_VENDOR_PRIVATE        0xfc00
146*05b00f60SXin Li 
147*05b00f60SXin Li static const struct tok lspping_tlv_values[] = {
148*05b00f60SXin Li     { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
149*05b00f60SXin Li     { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
150*05b00f60SXin Li     { LSPPING_TLV_PAD, "Pad" },
151*05b00f60SXin Li     { LSPPING_TLV_ERROR_CODE, "Error Code" },
152*05b00f60SXin Li     { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
153*05b00f60SXin Li     { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
154*05b00f60SXin Li     { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
155*05b00f60SXin Li     { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
156*05b00f60SXin Li     { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
157*05b00f60SXin Li     { 0, NULL}
158*05b00f60SXin Li };
159*05b00f60SXin Li 
160*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4       1
161*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6       2
162*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4      3
163*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6      4
164*05b00f60SXin Li /* not assigned                                     5 */
165*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4     6
166*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6     7
167*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT    8
168*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9
169*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW     10
170*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW     11
171*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4       12
172*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6       13
173*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4   14
174*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6   15
175*05b00f60SXin Li #define	LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC        16
176*05b00f60SXin Li 
177*05b00f60SXin Li static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
178*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
179*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
180*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
181*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
182*05b00f60SXin Li     { 5, "Reserved"},
183*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
184*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
185*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
186*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"},
187*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"},
188*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
189*05b00f60SXin Li     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
190*05b00f60SXin Li     { 0, NULL}
191*05b00f60SXin Li };
192*05b00f60SXin Li 
193*05b00f60SXin Li /*
194*05b00f60SXin Li  *  0                   1                   2                   3
195*05b00f60SXin Li  *  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
196*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197*05b00f60SXin Li  * |                          IPv4 prefix                          |
198*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199*05b00f60SXin Li  * | Prefix Length |         Must Be Zero                          |
200*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201*05b00f60SXin Li  */
202*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
203*05b00f60SXin Li     nd_ipv4    prefix;
204*05b00f60SXin Li     nd_uint8_t prefix_len;
205*05b00f60SXin Li };
206*05b00f60SXin Li 
207*05b00f60SXin Li /*
208*05b00f60SXin Li  *  0                   1                   2                   3
209*05b00f60SXin Li  *  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
210*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211*05b00f60SXin Li  * |                          IPv6 prefix                          |
212*05b00f60SXin Li  * |                          (16 octets)                          |
213*05b00f60SXin Li  * |                                                               |
214*05b00f60SXin Li  * |                                                               |
215*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
216*05b00f60SXin Li  * | Prefix Length |         Must Be Zero                          |
217*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218*05b00f60SXin Li  */
219*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
220*05b00f60SXin Li     nd_ipv6    prefix;
221*05b00f60SXin Li     nd_uint8_t prefix_len;
222*05b00f60SXin Li };
223*05b00f60SXin Li 
224*05b00f60SXin Li /*
225*05b00f60SXin Li  *  0                   1                   2                   3
226*05b00f60SXin Li  *  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
227*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228*05b00f60SXin Li  * |                 IPv4 tunnel end point address                 |
229*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230*05b00f60SXin Li  * |          Must Be Zero         |     Tunnel ID                 |
231*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232*05b00f60SXin Li  * |                       Extended Tunnel ID                      |
233*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234*05b00f60SXin Li  * |                   IPv4 tunnel sender address                  |
235*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
236*05b00f60SXin Li  * |          Must Be Zero         |            LSP ID             |
237*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238*05b00f60SXin Li  */
239*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
240*05b00f60SXin Li     nd_ipv4     tunnel_endpoint;
241*05b00f60SXin Li     nd_byte     res[2];
242*05b00f60SXin Li     nd_uint16_t tunnel_id;
243*05b00f60SXin Li     nd_ipv4     extended_tunnel_id;
244*05b00f60SXin Li     nd_ipv4     tunnel_sender;
245*05b00f60SXin Li     nd_byte     res2[2];
246*05b00f60SXin Li     nd_uint16_t lsp_id;
247*05b00f60SXin Li };
248*05b00f60SXin Li 
249*05b00f60SXin Li /*
250*05b00f60SXin Li  *  0                   1                   2                   3
251*05b00f60SXin Li  *  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
252*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
253*05b00f60SXin Li  * |                 IPv6 tunnel end point address                 |
254*05b00f60SXin Li  * |                                                               |
255*05b00f60SXin Li  * |                                                               |
256*05b00f60SXin Li  * |                                                               |
257*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
258*05b00f60SXin Li  * |          Must Be Zero         |          Tunnel ID            |
259*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
260*05b00f60SXin Li  * |                       Extended Tunnel ID                      |
261*05b00f60SXin Li  * |                                                               |
262*05b00f60SXin Li  * |                                                               |
263*05b00f60SXin Li  * |                                                               |
264*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265*05b00f60SXin Li  * |                   IPv6 tunnel sender address                  |
266*05b00f60SXin Li  * |                                                               |
267*05b00f60SXin Li  * |                                                               |
268*05b00f60SXin Li  * |                                                               |
269*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270*05b00f60SXin Li  * |          Must Be Zero         |            LSP ID             |
271*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272*05b00f60SXin Li  */
273*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
274*05b00f60SXin Li     nd_ipv6     tunnel_endpoint;
275*05b00f60SXin Li     nd_byte     res[2];
276*05b00f60SXin Li     nd_uint16_t tunnel_id;
277*05b00f60SXin Li     nd_ipv6     extended_tunnel_id;
278*05b00f60SXin Li     nd_ipv6     tunnel_sender;
279*05b00f60SXin Li     nd_byte     res2[2];
280*05b00f60SXin Li     nd_uint16_t lsp_id;
281*05b00f60SXin Li };
282*05b00f60SXin Li 
283*05b00f60SXin Li /*
284*05b00f60SXin Li  *  0                   1                   2                   3
285*05b00f60SXin Li  *  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
286*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
287*05b00f60SXin Li  * |                      Route Distinguisher                      |
288*05b00f60SXin Li  * |                          (8 octets)                           |
289*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
290*05b00f60SXin Li  * |                         IPv4 prefix                           |
291*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
292*05b00f60SXin Li  * | Prefix Length |                 Must Be Zero                  |
293*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
294*05b00f60SXin Li  */
295*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
296*05b00f60SXin Li     nd_byte    rd[8];
297*05b00f60SXin Li     nd_ipv4    prefix;
298*05b00f60SXin Li     nd_uint8_t prefix_len;
299*05b00f60SXin Li };
300*05b00f60SXin Li 
301*05b00f60SXin Li /*
302*05b00f60SXin Li  *  0                   1                   2                   3
303*05b00f60SXin Li  *  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
304*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305*05b00f60SXin Li  * |                      Route Distinguisher                      |
306*05b00f60SXin Li  * |                          (8 octets)                           |
307*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
308*05b00f60SXin Li  * |                          IPv6 prefix                          |
309*05b00f60SXin Li  * |                          (16 octets)                          |
310*05b00f60SXin Li  * |                                                               |
311*05b00f60SXin Li  * |                                                               |
312*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
313*05b00f60SXin Li  * | Prefix Length |                 Must Be Zero                  |
314*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
315*05b00f60SXin Li  */
316*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
317*05b00f60SXin Li     nd_byte    rd[8];
318*05b00f60SXin Li     nd_ipv6    prefix;
319*05b00f60SXin Li     nd_uint8_t prefix_len;
320*05b00f60SXin Li };
321*05b00f60SXin Li 
322*05b00f60SXin Li /*
323*05b00f60SXin Li  *  0                   1                   2                   3
324*05b00f60SXin Li  *  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
325*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326*05b00f60SXin Li  * |                      Route Distinguisher                      |
327*05b00f60SXin Li  * |                          (8 octets)                           |
328*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
329*05b00f60SXin Li  * |         Sender's VE ID        |       Receiver's VE ID        |
330*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
331*05b00f60SXin Li  * |      Encapsulation Type       |         Must Be Zero          |
332*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
333*05b00f60SXin Li  *  0                   1                   2                   3
334*05b00f60SXin Li  */
335*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
336*05b00f60SXin Li     nd_byte     rd[8];
337*05b00f60SXin Li     nd_uint16_t sender_ve_id;
338*05b00f60SXin Li     nd_uint16_t receiver_ve_id;
339*05b00f60SXin Li     nd_uint16_t encapsulation;
340*05b00f60SXin Li };
341*05b00f60SXin Li 
342*05b00f60SXin Li /*
343*05b00f60SXin Li  *  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
344*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345*05b00f60SXin Li  * |                      Remote PE Address                        |
346*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347*05b00f60SXin Li  * |                             PW ID                             |
348*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349*05b00f60SXin Li  * |            PW Type            |          Must Be Zero         |
350*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351*05b00f60SXin Li  */
352*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_fec_128_pw_old {
353*05b00f60SXin Li     nd_ipv4     remote_pe_address;
354*05b00f60SXin Li     nd_uint32_t pw_id;
355*05b00f60SXin Li     nd_uint16_t pw_type;
356*05b00f60SXin Li };
357*05b00f60SXin Li 
358*05b00f60SXin Li /*
359*05b00f60SXin Li  *  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
360*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361*05b00f60SXin Li  * |                     Sender's PE Address                       |
362*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363*05b00f60SXin Li  * |                      Remote PE Address                        |
364*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365*05b00f60SXin Li  * |                             PW ID                             |
366*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367*05b00f60SXin Li  * |            PW Type            |          Must Be Zero         |
368*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369*05b00f60SXin Li  */
370*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_fec_128_pw {
371*05b00f60SXin Li     nd_ipv4     sender_pe_address;
372*05b00f60SXin Li     nd_ipv4     remote_pe_address;
373*05b00f60SXin Li     nd_uint32_t pw_id;
374*05b00f60SXin Li     nd_uint16_t pw_type;
375*05b00f60SXin Li };
376*05b00f60SXin Li 
377*05b00f60SXin Li /*
378*05b00f60SXin Li  * 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
379*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380*05b00f60SXin Li  * |                         IPv4 prefix                           |
381*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
382*05b00f60SXin Li  * | Prefix Length |                 Must Be Zero                  |
383*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
384*05b00f60SXin Li  */
385*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
386*05b00f60SXin Li     nd_ipv4    prefix;
387*05b00f60SXin Li     nd_uint8_t prefix_len;
388*05b00f60SXin Li };
389*05b00f60SXin Li 
390*05b00f60SXin Li /*
391*05b00f60SXin Li  * 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
392*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
393*05b00f60SXin Li  * |                          IPv6 prefix                          |
394*05b00f60SXin Li  * |                          (16 octets)                          |
395*05b00f60SXin Li  * |                                                               |
396*05b00f60SXin Li  * |                                                               |
397*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398*05b00f60SXin Li  * | Prefix Length |                 Must Be Zero                  |
399*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400*05b00f60SXin Li  */
401*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
402*05b00f60SXin Li     nd_ipv6    prefix;
403*05b00f60SXin Li     nd_uint8_t prefix_len;
404*05b00f60SXin Li };
405*05b00f60SXin Li 
406*05b00f60SXin Li /*
407*05b00f60SXin Li  *  0                   1                   2                   3
408*05b00f60SXin Li  *  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
409*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
410*05b00f60SXin Li  * |               MTU             | Address Type  |  Resvd (SBZ)  |
411*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
412*05b00f60SXin Li  * |             Downstream IP Address (4 or 16 octets)            |
413*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
414*05b00f60SXin Li  * |         Downstream Interface Address (4 or 16 octets)         |
415*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416*05b00f60SXin Li  * | Multipath Type| Depth Limit   |        Multipath Length       |
417*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
418*05b00f60SXin Li  * .                                                               .
419*05b00f60SXin Li  * .                     (Multipath Information)                   .
420*05b00f60SXin Li  * .                                                               .
421*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
422*05b00f60SXin Li  * |               Downstream Label                |    Protocol   |
423*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
424*05b00f60SXin Li  * .                                                               .
425*05b00f60SXin Li  * .                                                               .
426*05b00f60SXin Li  * .                                                               .
427*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428*05b00f60SXin Li  * |               Downstream Label                |    Protocol   |
429*05b00f60SXin Li  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
430*05b00f60SXin Li  */
431*05b00f60SXin Li /* Enough to get the address type */
432*05b00f60SXin Li struct lspping_tlv_downstream_map_t {
433*05b00f60SXin Li     nd_uint16_t mtu;
434*05b00f60SXin Li     nd_uint8_t  address_type;
435*05b00f60SXin Li     nd_uint8_t  ds_flags;
436*05b00f60SXin Li };
437*05b00f60SXin Li 
438*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv4_t {
439*05b00f60SXin Li     nd_uint16_t mtu;
440*05b00f60SXin Li     nd_uint8_t  address_type;
441*05b00f60SXin Li     nd_uint8_t  ds_flags;
442*05b00f60SXin Li     nd_ipv4     downstream_ip;
443*05b00f60SXin Li     nd_ipv4     downstream_interface;
444*05b00f60SXin Li };
445*05b00f60SXin Li 
446*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv4_unmb_t {
447*05b00f60SXin Li     nd_uint16_t mtu;
448*05b00f60SXin Li     nd_uint8_t  address_type;
449*05b00f60SXin Li     nd_uint8_t  ds_flags;
450*05b00f60SXin Li     nd_ipv4     downstream_ip;
451*05b00f60SXin Li     nd_uint32_t downstream_interface;
452*05b00f60SXin Li };
453*05b00f60SXin Li 
454*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv6_t {
455*05b00f60SXin Li     nd_uint16_t mtu;
456*05b00f60SXin Li     nd_uint8_t  address_type;
457*05b00f60SXin Li     nd_uint8_t  ds_flags;
458*05b00f60SXin Li     nd_ipv6     downstream_ip;
459*05b00f60SXin Li     nd_ipv6     downstream_interface;
460*05b00f60SXin Li };
461*05b00f60SXin Li 
462*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv6_unmb_t {
463*05b00f60SXin Li     nd_uint16_t mtu;
464*05b00f60SXin Li     nd_uint8_t  address_type;
465*05b00f60SXin Li     nd_uint8_t  ds_flags;
466*05b00f60SXin Li     nd_ipv6     downstream_ip;
467*05b00f60SXin Li     nd_uint32_t downstream_interface;
468*05b00f60SXin Li };
469*05b00f60SXin Li 
470*05b00f60SXin Li struct lspping_tlv_downstream_map_info_t {
471*05b00f60SXin Li     nd_uint8_t  multipath_type;
472*05b00f60SXin Li     nd_uint8_t  depth_limit;
473*05b00f60SXin Li     nd_uint16_t multipath_length;
474*05b00f60SXin Li };
475*05b00f60SXin Li 
476*05b00f60SXin Li #define LSPPING_AFI_IPV4      1
477*05b00f60SXin Li #define LSPPING_AFI_IPV4_UNMB 2
478*05b00f60SXin Li #define LSPPING_AFI_IPV6      3
479*05b00f60SXin Li #define LSPPING_AFI_IPV6_UNMB 4
480*05b00f60SXin Li 
481*05b00f60SXin Li static const struct tok lspping_tlv_downstream_addr_values[] = {
482*05b00f60SXin Li     { LSPPING_AFI_IPV4,      "IPv4"},
483*05b00f60SXin Li     { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"},
484*05b00f60SXin Li     { LSPPING_AFI_IPV6,      "IPv6"},
485*05b00f60SXin Li     { LSPPING_AFI_IPV6_UNMB, "IPv6"},
486*05b00f60SXin Li     { 0, NULL}
487*05b00f60SXin Li };
488*05b00f60SXin Li 
489*05b00f60SXin Li void
lspping_print(netdissect_options * ndo,const u_char * pptr,u_int len)490*05b00f60SXin Li lspping_print(netdissect_options *ndo,
491*05b00f60SXin Li               const u_char *pptr, u_int len)
492*05b00f60SXin Li {
493*05b00f60SXin Li     const struct lspping_common_header *lspping_com_header;
494*05b00f60SXin Li     const struct lspping_tlv_header *lspping_tlv_header;
495*05b00f60SXin Li     const struct lspping_tlv_header *lspping_subtlv_header;
496*05b00f60SXin Li     const u_char *tptr,*tlv_tptr,*subtlv_tptr;
497*05b00f60SXin Li     u_int return_code, return_subcode;
498*05b00f60SXin Li     u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
499*05b00f60SXin Li     int tlv_hexdump,subtlv_hexdump;
500*05b00f60SXin Li     u_int lspping_subtlv_len,lspping_subtlv_type;
501*05b00f60SXin Li     uint32_t int_part, fraction;
502*05b00f60SXin Li     u_int address_type;
503*05b00f60SXin Li 
504*05b00f60SXin Li     union {
505*05b00f60SXin Li         const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map;
506*05b00f60SXin Li         const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
507*05b00f60SXin Li         const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb;
508*05b00f60SXin Li         const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
509*05b00f60SXin Li         const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb;
510*05b00f60SXin Li         const struct lspping_tlv_downstream_map_info_t  *lspping_tlv_downstream_map_info;
511*05b00f60SXin Li     } tlv_ptr;
512*05b00f60SXin Li 
513*05b00f60SXin Li     union {
514*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
515*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
516*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
517*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
518*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
519*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
520*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
521*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
522*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
523*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
524*05b00f60SXin Li         const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
525*05b00f60SXin Li     } subtlv_ptr;
526*05b00f60SXin Li 
527*05b00f60SXin Li     ndo->ndo_protocol = "lspping";
528*05b00f60SXin Li     tptr=pptr;
529*05b00f60SXin Li     lspping_com_header = (const struct lspping_common_header *)pptr;
530*05b00f60SXin Li     if (len < sizeof(struct lspping_common_header))
531*05b00f60SXin Li         goto tooshort;
532*05b00f60SXin Li     ND_TCHECK_SIZE(lspping_com_header);
533*05b00f60SXin Li 
534*05b00f60SXin Li     /*
535*05b00f60SXin Li      * Sanity checking of the header.
536*05b00f60SXin Li      */
537*05b00f60SXin Li     if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) {
538*05b00f60SXin Li 	ND_PRINT("LSP-PING version %u packet not supported",
539*05b00f60SXin Li                GET_BE_U_2(lspping_com_header->version));
540*05b00f60SXin Li 	return;
541*05b00f60SXin Li     }
542*05b00f60SXin Li 
543*05b00f60SXin Li     /* in non-verbose mode just lets print the basic Message Type*/
544*05b00f60SXin Li     if (ndo->ndo_vflag < 1) {
545*05b00f60SXin Li         ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u",
546*05b00f60SXin Li                GET_BE_U_2(lspping_com_header->version),
547*05b00f60SXin Li                tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)),
548*05b00f60SXin Li                GET_BE_U_4(lspping_com_header->seq_number),
549*05b00f60SXin Li                len);
550*05b00f60SXin Li         return;
551*05b00f60SXin Li     }
552*05b00f60SXin Li 
553*05b00f60SXin Li     /* ok they seem to want to know everything - lets fully decode it */
554*05b00f60SXin Li 
555*05b00f60SXin Li     tlen=len;
556*05b00f60SXin Li 
557*05b00f60SXin Li     ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t  reply-mode: %s (%u)",
558*05b00f60SXin Li            GET_BE_U_2(lspping_com_header->version),
559*05b00f60SXin Li            tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)),
560*05b00f60SXin Li            GET_U_1(lspping_com_header->msg_type),
561*05b00f60SXin Li            len,
562*05b00f60SXin Li            tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)),
563*05b00f60SXin Li            GET_U_1(lspping_com_header->reply_mode));
564*05b00f60SXin Li 
565*05b00f60SXin Li     /*
566*05b00f60SXin Li      *  the following return codes require that the subcode is attached
567*05b00f60SXin Li      *  at the end of the translated token output
568*05b00f60SXin Li      */
569*05b00f60SXin Li     return_code = GET_U_1(lspping_com_header->return_code);
570*05b00f60SXin Li     return_subcode = GET_U_1(lspping_com_header->return_subcode);
571*05b00f60SXin Li     if (return_code == 3 ||
572*05b00f60SXin Li         return_code == 4 ||
573*05b00f60SXin Li         return_code == 8 ||
574*05b00f60SXin Li         return_code == 10 ||
575*05b00f60SXin Li         return_code == 11 ||
576*05b00f60SXin Li         return_code == 12 )
577*05b00f60SXin Li         ND_PRINT("\n\t  Return Code: %s %u (%u)\n\t  Return Subcode: (%u)",
578*05b00f60SXin Li                tok2str(lspping_return_code_values, "unknown",return_code),
579*05b00f60SXin Li                return_subcode,
580*05b00f60SXin Li                return_code,
581*05b00f60SXin Li                return_subcode);
582*05b00f60SXin Li     else
583*05b00f60SXin Li         ND_PRINT("\n\t  Return Code: %s (%u)\n\t  Return Subcode: (%u)",
584*05b00f60SXin Li                tok2str(lspping_return_code_values, "unknown",return_code),
585*05b00f60SXin Li                return_code,
586*05b00f60SXin Li                return_subcode);
587*05b00f60SXin Li 
588*05b00f60SXin Li     ND_PRINT("\n\t  Sender Handle: 0x%08x, Sequence: %u",
589*05b00f60SXin Li            GET_BE_U_4(lspping_com_header->sender_handle),
590*05b00f60SXin Li            GET_BE_U_4(lspping_com_header->seq_number));
591*05b00f60SXin Li 
592*05b00f60SXin Li     ND_PRINT("\n\t  Sender Timestamp: ");
593*05b00f60SXin Li     p_ntp_time(ndo, &lspping_com_header->ts_sent);
594*05b00f60SXin Li     ND_PRINT(" ");
595*05b00f60SXin Li 
596*05b00f60SXin Li     int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part);
597*05b00f60SXin Li     fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction);
598*05b00f60SXin Li     ND_PRINT("Receiver Timestamp: ");
599*05b00f60SXin Li     if (! (int_part == 0 && fraction == 0))
600*05b00f60SXin Li         p_ntp_time(ndo, &lspping_com_header->ts_rcvd);
601*05b00f60SXin Li     else
602*05b00f60SXin Li         ND_PRINT("no timestamp");
603*05b00f60SXin Li 
604*05b00f60SXin Li     tptr+=sizeof(struct lspping_common_header);
605*05b00f60SXin Li     tlen-=sizeof(struct lspping_common_header);
606*05b00f60SXin Li 
607*05b00f60SXin Li     while (tlen != 0) {
608*05b00f60SXin Li         /* Does the TLV go past the end of the packet? */
609*05b00f60SXin Li         if (tlen < sizeof(struct lspping_tlv_header))
610*05b00f60SXin Li             goto tooshort;
611*05b00f60SXin Li 
612*05b00f60SXin Li         lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
613*05b00f60SXin Li         lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type);
614*05b00f60SXin Li         lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length);
615*05b00f60SXin Li 
616*05b00f60SXin Li         ND_PRINT("\n\t  %s TLV (%u), length: %u",
617*05b00f60SXin Li                tok2str(lspping_tlv_values,
618*05b00f60SXin Li                        "Unknown",
619*05b00f60SXin Li                        lspping_tlv_type),
620*05b00f60SXin Li                lspping_tlv_type,
621*05b00f60SXin Li                lspping_tlv_len);
622*05b00f60SXin Li 
623*05b00f60SXin Li         /* some little sanity checking */
624*05b00f60SXin Li         if (lspping_tlv_len == 0) {
625*05b00f60SXin Li             tptr+=sizeof(struct lspping_tlv_header);
626*05b00f60SXin Li             tlen-=sizeof(struct lspping_tlv_header);
627*05b00f60SXin Li             continue;    /* no value to dissect */
628*05b00f60SXin Li         }
629*05b00f60SXin Li 
630*05b00f60SXin Li         tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
631*05b00f60SXin Li         tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
632*05b00f60SXin Li 
633*05b00f60SXin Li         /* Does the TLV go past the end of the packet? */
634*05b00f60SXin Li         if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
635*05b00f60SXin Li             goto tooshort;
636*05b00f60SXin Li         /* did we capture enough for fully decoding the tlv ? */
637*05b00f60SXin Li         ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len);
638*05b00f60SXin Li         tlv_hexdump=FALSE;
639*05b00f60SXin Li 
640*05b00f60SXin Li         switch(lspping_tlv_type) {
641*05b00f60SXin Li         case LSPPING_TLV_TARGET_FEC_STACK:
642*05b00f60SXin Li             while (tlv_tlen != 0) {
643*05b00f60SXin Li                 /* Does the subTLV header go past the end of the TLV? */
644*05b00f60SXin Li                 if (tlv_tlen < sizeof(struct lspping_tlv_header)) {
645*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
646*05b00f60SXin Li                     tlv_hexdump = TRUE;
647*05b00f60SXin Li                     goto tlv_tooshort;
648*05b00f60SXin Li                 }
649*05b00f60SXin Li                 subtlv_hexdump=FALSE;
650*05b00f60SXin Li 
651*05b00f60SXin Li                 lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
652*05b00f60SXin Li                 lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type);
653*05b00f60SXin Li                 lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length);
654*05b00f60SXin Li                 subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
655*05b00f60SXin Li 
656*05b00f60SXin Li                 /* Does the subTLV go past the end of the TLV? */
657*05b00f60SXin Li                 if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
658*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
659*05b00f60SXin Li                     tlv_hexdump = TRUE;
660*05b00f60SXin Li                     goto tlv_tooshort;
661*05b00f60SXin Li                 }
662*05b00f60SXin Li 
663*05b00f60SXin Li                 /* Did we capture enough for fully decoding the subTLV? */
664*05b00f60SXin Li                 ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len);
665*05b00f60SXin Li 
666*05b00f60SXin Li                 ND_PRINT("\n\t    %s subTLV (%u), length: %u",
667*05b00f60SXin Li                        tok2str(lspping_tlvtargetfec_subtlv_values,
668*05b00f60SXin Li                                "Unknown",
669*05b00f60SXin Li                                lspping_subtlv_type),
670*05b00f60SXin Li                        lspping_subtlv_type,
671*05b00f60SXin Li                        lspping_subtlv_len);
672*05b00f60SXin Li 
673*05b00f60SXin Li                 switch(lspping_subtlv_type) {
674*05b00f60SXin Li 
675*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
676*05b00f60SXin Li                     /* Is the subTLV length correct? */
677*05b00f60SXin Li                     if (lspping_subtlv_len != 5) {
678*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 5");
679*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
680*05b00f60SXin Li                     } else {
681*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 =
682*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
683*05b00f60SXin Li                         ND_PRINT("\n\t      %s/%u",
684*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
685*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len));
686*05b00f60SXin Li                     }
687*05b00f60SXin Li                     break;
688*05b00f60SXin Li 
689*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
690*05b00f60SXin Li                     /* Is the subTLV length correct? */
691*05b00f60SXin Li                     if (lspping_subtlv_len != 17) {
692*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 17");
693*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
694*05b00f60SXin Li                     } else {
695*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 =
696*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
697*05b00f60SXin Li                         ND_PRINT("\n\t      %s/%u",
698*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
699*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
700*05b00f60SXin Li                     }
701*05b00f60SXin Li                     break;
702*05b00f60SXin Li 
703*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
704*05b00f60SXin Li                     /* Is the subTLV length correct? */
705*05b00f60SXin Li                     if (lspping_subtlv_len != 5) {
706*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 5");
707*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
708*05b00f60SXin Li                     } else {
709*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 =
710*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
711*05b00f60SXin Li                         ND_PRINT("\n\t      %s/%u",
712*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
713*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len));
714*05b00f60SXin Li                     }
715*05b00f60SXin Li                     break;
716*05b00f60SXin Li 
717*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
718*05b00f60SXin Li                     /* Is the subTLV length correct? */
719*05b00f60SXin Li                     if (lspping_subtlv_len != 17) {
720*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 17");
721*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
722*05b00f60SXin Li                     } else {
723*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 =
724*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
725*05b00f60SXin Li                         ND_PRINT("\n\t      %s/%u",
726*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
727*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len));
728*05b00f60SXin Li                     }
729*05b00f60SXin Li                     break;
730*05b00f60SXin Li 
731*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
732*05b00f60SXin Li                     /* Is the subTLV length correct? */
733*05b00f60SXin Li                     if (lspping_subtlv_len != 20) {
734*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 20");
735*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
736*05b00f60SXin Li                     } else {
737*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 =
738*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
739*05b00f60SXin Li                         ND_PRINT("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
740*05b00f60SXin Li                                "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
741*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
742*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
743*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
744*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
745*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
746*05b00f60SXin Li                     }
747*05b00f60SXin Li                     break;
748*05b00f60SXin Li 
749*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
750*05b00f60SXin Li                     /* Is the subTLV length correct? */
751*05b00f60SXin Li                     if (lspping_subtlv_len != 56) {
752*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 56");
753*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
754*05b00f60SXin Li                     } else {
755*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 =
756*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
757*05b00f60SXin Li                         ND_PRINT("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
758*05b00f60SXin Li                                "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
759*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
760*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
761*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
762*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
763*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
764*05b00f60SXin Li                     }
765*05b00f60SXin Li                     break;
766*05b00f60SXin Li 
767*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
768*05b00f60SXin Li                     /* Is the subTLV length correct? */
769*05b00f60SXin Li                     if (lspping_subtlv_len != 13) {
770*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 13");
771*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
772*05b00f60SXin Li                     } else {
773*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 =
774*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
775*05b00f60SXin Li                         ND_PRINT("\n\t      RD: %s, %s/%u",
776*05b00f60SXin Li                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
777*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
778*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
779*05b00f60SXin Li                     }
780*05b00f60SXin Li                     break;
781*05b00f60SXin Li 
782*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
783*05b00f60SXin Li                     /* Is the subTLV length correct? */
784*05b00f60SXin Li                     if (lspping_subtlv_len != 25) {
785*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 25");
786*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
787*05b00f60SXin Li                     } else {
788*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 =
789*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
790*05b00f60SXin Li                         ND_PRINT("\n\t      RD: %s, %s/%u",
791*05b00f60SXin Li                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
792*05b00f60SXin Li                                GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
793*05b00f60SXin Li                                GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
794*05b00f60SXin Li                     }
795*05b00f60SXin Li                     break;
796*05b00f60SXin Li 
797*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
798*05b00f60SXin Li                     /* Is the subTLV length correct? */
799*05b00f60SXin Li                     if (lspping_subtlv_len != 14) {
800*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 14");
801*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
802*05b00f60SXin Li                     } else {
803*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt =
804*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
805*05b00f60SXin Li                         ND_PRINT("\n\t      RD: %s, Sender VE ID: %u, Receiver VE ID: %u"
806*05b00f60SXin Li                                "\n\t      Encapsulation Type: %s (%u)",
807*05b00f60SXin Li                                bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
808*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id),
809*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id),
810*05b00f60SXin Li                                tok2str(mpls_pw_types_values,
811*05b00f60SXin Li                                        "unknown",
812*05b00f60SXin Li                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
813*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
814*05b00f60SXin Li                     }
815*05b00f60SXin Li                     break;
816*05b00f60SXin Li 
817*05b00f60SXin Li                     /* the old L2VPN VCID subTLV does not have support for the sender field */
818*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD:
819*05b00f60SXin Li                     /* Is the subTLV length correct? */
820*05b00f60SXin Li                     if (lspping_subtlv_len != 10) {
821*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 10");
822*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
823*05b00f60SXin Li                     } else {
824*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old =
825*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr;
826*05b00f60SXin Li                         ND_PRINT("\n\t      Remote PE: %s"
827*05b00f60SXin Li                                "\n\t      PW ID: 0x%08x, PW Type: %s (%u)",
828*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
829*05b00f60SXin Li                                GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id),
830*05b00f60SXin Li                                tok2str(mpls_pw_types_values,
831*05b00f60SXin Li                                        "unknown",
832*05b00f60SXin Li                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)),
833*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type));
834*05b00f60SXin Li                     }
835*05b00f60SXin Li                     break;
836*05b00f60SXin Li 
837*05b00f60SXin Li                 case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW:
838*05b00f60SXin Li                     /* Is the subTLV length correct? */
839*05b00f60SXin Li                     if (lspping_subtlv_len != 14) {
840*05b00f60SXin Li                         ND_PRINT("\n\t      invalid subTLV length, should be 14");
841*05b00f60SXin Li                         subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
842*05b00f60SXin Li                     } else {
843*05b00f60SXin Li                         subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid =
844*05b00f60SXin Li                             (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr;
845*05b00f60SXin Li                         ND_PRINT("\n\t      Sender PE: %s, Remote PE: %s"
846*05b00f60SXin Li                                "\n\t      PW ID: 0x%08x, PW Type: %s (%u)",
847*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
848*05b00f60SXin Li                                GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
849*05b00f60SXin Li                                GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id),
850*05b00f60SXin Li                                tok2str(mpls_pw_types_values,
851*05b00f60SXin Li                                        "unknown",
852*05b00f60SXin Li                                        GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)),
853*05b00f60SXin Li                                GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type));
854*05b00f60SXin Li                     }
855*05b00f60SXin Li                     break;
856*05b00f60SXin Li 
857*05b00f60SXin Li                 default:
858*05b00f60SXin Li                     subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
859*05b00f60SXin Li                     break;
860*05b00f60SXin Li                 }
861*05b00f60SXin Li                 /* do we want to see an additionally subtlv hexdump ? */
862*05b00f60SXin Li                 if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
863*05b00f60SXin Li                     print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header),
864*05b00f60SXin Li                                        "\n\t      ",
865*05b00f60SXin Li                                        lspping_subtlv_len);
866*05b00f60SXin Li 
867*05b00f60SXin Li                 /* All subTLVs are aligned to four octet boundary */
868*05b00f60SXin Li                 if (lspping_subtlv_len % 4) {
869*05b00f60SXin Li                     lspping_subtlv_len += 4 - (lspping_subtlv_len % 4);
870*05b00f60SXin Li                     /* Does the subTLV, including padding, go past the end of the TLV? */
871*05b00f60SXin Li                     if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
872*05b00f60SXin Li                         ND_PRINT("\n\t\t TLV is too short");
873*05b00f60SXin Li                         return;
874*05b00f60SXin Li                     }
875*05b00f60SXin Li                 }
876*05b00f60SXin Li                 tlv_tptr+=lspping_subtlv_len;
877*05b00f60SXin Li                 tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
878*05b00f60SXin Li             }
879*05b00f60SXin Li             break;
880*05b00f60SXin Li 
881*05b00f60SXin Li         case LSPPING_TLV_DOWNSTREAM_MAPPING:
882*05b00f60SXin Li             /* Does the header go past the end of the TLV? */
883*05b00f60SXin Li             if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
884*05b00f60SXin Li                 ND_PRINT("\n\t      TLV is too short");
885*05b00f60SXin Li                 tlv_hexdump = TRUE;
886*05b00f60SXin Li                 goto tlv_tooshort;
887*05b00f60SXin Li             }
888*05b00f60SXin Li             /* Did we capture enough to get the address family? */
889*05b00f60SXin Li             ND_TCHECK_LEN(tlv_tptr,
890*05b00f60SXin Li                           sizeof(struct lspping_tlv_downstream_map_t));
891*05b00f60SXin Li 
892*05b00f60SXin Li             tlv_ptr.lspping_tlv_downstream_map=
893*05b00f60SXin Li                 (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
894*05b00f60SXin Li 
895*05b00f60SXin Li             /* that strange thing with the downstream map TLV is that until now
896*05b00f60SXin Li              * we do not know if its IPv4 or IPv6 or is unnumbered; after
897*05b00f60SXin Li              * we find the address-type, we recast the tlv_tptr and move on. */
898*05b00f60SXin Li 
899*05b00f60SXin Li             address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type);
900*05b00f60SXin Li             ND_PRINT("\n\t    MTU: %u, Address-Type: %s (%u)",
901*05b00f60SXin Li                    GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu),
902*05b00f60SXin Li                    tok2str(lspping_tlv_downstream_addr_values,
903*05b00f60SXin Li                            "unknown",
904*05b00f60SXin Li                            address_type),
905*05b00f60SXin Li                    address_type);
906*05b00f60SXin Li 
907*05b00f60SXin Li             switch(address_type) {
908*05b00f60SXin Li 
909*05b00f60SXin Li             case LSPPING_AFI_IPV4:
910*05b00f60SXin Li                 /* Does the data go past the end of the TLV? */
911*05b00f60SXin Li                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
912*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
913*05b00f60SXin Li                     tlv_hexdump = TRUE;
914*05b00f60SXin Li                     goto tlv_tooshort;
915*05b00f60SXin Li                 }
916*05b00f60SXin Li                 /* Did we capture enough for this part of the TLV? */
917*05b00f60SXin Li                 ND_TCHECK_LEN(tlv_tptr,
918*05b00f60SXin Li                               sizeof(struct lspping_tlv_downstream_map_ipv4_t));
919*05b00f60SXin Li 
920*05b00f60SXin Li                 tlv_ptr.lspping_tlv_downstream_map_ipv4=
921*05b00f60SXin Li                     (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
922*05b00f60SXin Li                 ND_PRINT("\n\t    Downstream IP: %s"
923*05b00f60SXin Li                        "\n\t    Downstream Interface IP: %s",
924*05b00f60SXin Li                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
925*05b00f60SXin Li                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
926*05b00f60SXin Li                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
927*05b00f60SXin Li                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
928*05b00f60SXin Li                 break;
929*05b00f60SXin Li             case LSPPING_AFI_IPV4_UNMB:
930*05b00f60SXin Li                 /* Does the data go past the end of the TLV? */
931*05b00f60SXin Li                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
932*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
933*05b00f60SXin Li                     tlv_hexdump = TRUE;
934*05b00f60SXin Li                     goto tlv_tooshort;
935*05b00f60SXin Li                 }
936*05b00f60SXin Li                 /* Did we capture enough for this part of the TLV? */
937*05b00f60SXin Li                 ND_TCHECK_LEN(tlv_tptr,
938*05b00f60SXin Li                               sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
939*05b00f60SXin Li 
940*05b00f60SXin Li                 tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb=
941*05b00f60SXin Li                     (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
942*05b00f60SXin Li                 ND_PRINT("\n\t    Downstream IP: %s"
943*05b00f60SXin Li                        "\n\t    Downstream Interface Index: 0x%08x",
944*05b00f60SXin Li                        GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
945*05b00f60SXin Li                        GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface));
946*05b00f60SXin Li                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
947*05b00f60SXin Li                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
948*05b00f60SXin Li                 break;
949*05b00f60SXin Li             case LSPPING_AFI_IPV6:
950*05b00f60SXin Li                 /* Does the data go past the end of the TLV? */
951*05b00f60SXin Li                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
952*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
953*05b00f60SXin Li                     tlv_hexdump = TRUE;
954*05b00f60SXin Li                     goto tlv_tooshort;
955*05b00f60SXin Li                 }
956*05b00f60SXin Li                 /* Did we capture enough for this part of the TLV? */
957*05b00f60SXin Li                 ND_TCHECK_LEN(tlv_tptr,
958*05b00f60SXin Li                               sizeof(struct lspping_tlv_downstream_map_ipv6_t));
959*05b00f60SXin Li 
960*05b00f60SXin Li                 tlv_ptr.lspping_tlv_downstream_map_ipv6=
961*05b00f60SXin Li                     (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
962*05b00f60SXin Li                 ND_PRINT("\n\t    Downstream IP: %s"
963*05b00f60SXin Li                        "\n\t    Downstream Interface IP: %s",
964*05b00f60SXin Li                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
965*05b00f60SXin Li                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
966*05b00f60SXin Li                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
967*05b00f60SXin Li                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
968*05b00f60SXin Li                 break;
969*05b00f60SXin Li              case LSPPING_AFI_IPV6_UNMB:
970*05b00f60SXin Li                 /* Does the data go past the end of the TLV? */
971*05b00f60SXin Li                 if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
972*05b00f60SXin Li                     ND_PRINT("\n\t      TLV is too short");
973*05b00f60SXin Li                     tlv_hexdump = TRUE;
974*05b00f60SXin Li                     goto tlv_tooshort;
975*05b00f60SXin Li                 }
976*05b00f60SXin Li                 /* Did we capture enough for this part of the TLV? */
977*05b00f60SXin Li                 ND_TCHECK_LEN(tlv_tptr,
978*05b00f60SXin Li                               sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
979*05b00f60SXin Li 
980*05b00f60SXin Li                 tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb=
981*05b00f60SXin Li                    (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
982*05b00f60SXin Li                 ND_PRINT("\n\t    Downstream IP: %s"
983*05b00f60SXin Li                        "\n\t    Downstream Interface Index: 0x%08x",
984*05b00f60SXin Li                        GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
985*05b00f60SXin Li                        GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface));
986*05b00f60SXin Li                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
987*05b00f60SXin Li                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
988*05b00f60SXin Li                 break;
989*05b00f60SXin Li 
990*05b00f60SXin Li             default:
991*05b00f60SXin Li                 /* should not happen ! - no error message - tok2str() has barked already */
992*05b00f60SXin Li                 break;
993*05b00f60SXin Li             }
994*05b00f60SXin Li 
995*05b00f60SXin Li             /* Does the data go past the end of the TLV? */
996*05b00f60SXin Li             if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
997*05b00f60SXin Li                 ND_PRINT("\n\t      TLV is too short");
998*05b00f60SXin Li                 tlv_hexdump = TRUE;
999*05b00f60SXin Li                 goto tlv_tooshort;
1000*05b00f60SXin Li             }
1001*05b00f60SXin Li             /* Did we capture enough for this part of the TLV? */
1002*05b00f60SXin Li             ND_TCHECK_LEN(tlv_tptr,
1003*05b00f60SXin Li                           sizeof(struct lspping_tlv_downstream_map_info_t));
1004*05b00f60SXin Li 
1005*05b00f60SXin Li             tlv_ptr.lspping_tlv_downstream_map_info=
1006*05b00f60SXin Li                 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
1007*05b00f60SXin Li 
1008*05b00f60SXin Li             /* FIXME add hash-key type, depth limit, multipath processing */
1009*05b00f60SXin Li 
1010*05b00f60SXin Li             /* FIXME print downstream labels */
1011*05b00f60SXin Li 
1012*05b00f60SXin Li             tlv_hexdump=TRUE; /* dump the TLV until code complete */
1013*05b00f60SXin Li 
1014*05b00f60SXin Li             break;
1015*05b00f60SXin Li 
1016*05b00f60SXin Li         case LSPPING_TLV_BFD_DISCRIMINATOR:
1017*05b00f60SXin Li             if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
1018*05b00f60SXin Li                 ND_PRINT("\n\t      TLV is too short");
1019*05b00f60SXin Li                 tlv_hexdump = TRUE;
1020*05b00f60SXin Li                 goto tlv_tooshort;
1021*05b00f60SXin Li             } else {
1022*05b00f60SXin Li                 ND_PRINT("\n\t    BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr));
1023*05b00f60SXin Li             }
1024*05b00f60SXin Li             break;
1025*05b00f60SXin Li 
1026*05b00f60SXin Li         case  LSPPING_TLV_VENDOR_ENTERPRISE:
1027*05b00f60SXin Li         {
1028*05b00f60SXin Li             uint32_t vendor_id;
1029*05b00f60SXin Li 
1030*05b00f60SXin Li             if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
1031*05b00f60SXin Li                 ND_PRINT("\n\t      TLV is too short");
1032*05b00f60SXin Li                 tlv_hexdump = TRUE;
1033*05b00f60SXin Li                 goto tlv_tooshort;
1034*05b00f60SXin Li             } else {
1035*05b00f60SXin Li                 vendor_id = GET_BE_U_4(tlv_tptr);
1036*05b00f60SXin Li                 ND_PRINT("\n\t    Vendor: %s (0x%04x)",
1037*05b00f60SXin Li                        tok2str(smi_values, "Unknown", vendor_id),
1038*05b00f60SXin Li                        vendor_id);
1039*05b00f60SXin Li             }
1040*05b00f60SXin Li         }
1041*05b00f60SXin Li             break;
1042*05b00f60SXin Li 
1043*05b00f60SXin Li             /*
1044*05b00f60SXin Li              *  FIXME those are the defined TLVs that lack a decoder
1045*05b00f60SXin Li              *  you are welcome to contribute code ;-)
1046*05b00f60SXin Li              */
1047*05b00f60SXin Li         case LSPPING_TLV_PAD:
1048*05b00f60SXin Li         case LSPPING_TLV_ERROR_CODE:
1049*05b00f60SXin Li         case LSPPING_TLV_VENDOR_PRIVATE:
1050*05b00f60SXin Li 
1051*05b00f60SXin Li         default:
1052*05b00f60SXin Li             if (ndo->ndo_vflag <= 1)
1053*05b00f60SXin Li                 print_unknown_data(ndo, tlv_tptr, "\n\t    ", tlv_tlen);
1054*05b00f60SXin Li             break;
1055*05b00f60SXin Li         }
1056*05b00f60SXin Li         /* do we want to see an additionally tlv hexdump ? */
1057*05b00f60SXin Li     tlv_tooshort:
1058*05b00f60SXin Li         if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
1059*05b00f60SXin Li             print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t    ",
1060*05b00f60SXin Li                                lspping_tlv_len);
1061*05b00f60SXin Li 
1062*05b00f60SXin Li 
1063*05b00f60SXin Li         /* All TLVs are aligned to four octet boundary */
1064*05b00f60SXin Li         if (lspping_tlv_len % 4) {
1065*05b00f60SXin Li             lspping_tlv_len += (4 - lspping_tlv_len % 4);
1066*05b00f60SXin Li             /* Does the TLV, including padding, go past the end of the packet? */
1067*05b00f60SXin Li             if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
1068*05b00f60SXin Li                 goto tooshort;
1069*05b00f60SXin Li         }
1070*05b00f60SXin Li 
1071*05b00f60SXin Li         tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
1072*05b00f60SXin Li         tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
1073*05b00f60SXin Li     }
1074*05b00f60SXin Li     return;
1075*05b00f60SXin Li tooshort:
1076*05b00f60SXin Li     ND_PRINT("\n\t\t packet is too short");
1077*05b00f60SXin Li }
1078