1 /*
2  * Redistribution and use in source and binary forms, with or without
3  * modification, are permitted provided that: (1) source code
4  * distributions retain the above copyright notice and this paragraph
5  * in its entirety, and (2) distributions including binary code include
6  * the above copyright notice and this paragraph in its entirety in
7  * the documentation or other materials provided with the distribution.
8  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11  * FOR A PARTICULAR PURPOSE.
12  *
13  * Original code by Hannes Gredler (hannes@juniper.net)
14  */
15 
16 #ifndef lint
17 static const char rcsid[] _U_ =
18     "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $";
19 #endif
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <tcpdump-stdinc.h>
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "interface.h"
32 #include "extract.h"
33 #include "addrtoname.h"
34 
35 #include "bgp.h"
36 #include "l2vpn.h"
37 #include "oui.h"
38 
39 /*
40  * LSPPING common header
41  *
42  *  0                   1                   2                   3
43  *  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
44  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45  * |         Version Number        |         Must Be Zero          |
46  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47  * |  Message Type |   Reply mode  |  Return Code  | Return Subcode|
48  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49  * |                        Sender's Handle                        |
50  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51  * |                        Sequence Number                        |
52  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53  * |                    TimeStamp Sent (seconds)                   |
54  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55  * |                  TimeStamp Sent (microseconds)                |
56  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57  * |                  TimeStamp Received (seconds)                 |
58  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59  * |                TimeStamp Received (microseconds)              |
60  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61  * |                            TLVs ...                           |
62  * .                                                               .
63  * .                                                               .
64  * .                                                               .
65  */
66 
67 struct lspping_common_header {
68     u_int8_t version[2];
69     u_int8_t reserved[2];
70     u_int8_t msg_type;
71     u_int8_t reply_mode;
72     u_int8_t return_code;
73     u_int8_t return_subcode;
74     u_int8_t sender_handle[4];
75     u_int8_t seq_number[4];
76     u_int8_t ts_sent_sec[4];
77     u_int8_t ts_sent_usec[4];
78     u_int8_t ts_rcvd_sec[4];
79     u_int8_t ts_rcvd_usec[4];
80 };
81 
82 #define LSPPING_VERSION            1
83 
84 static const struct tok lspping_msg_type_values[] = {
85     { 1, "MPLS Echo Request"},
86     { 2, "MPLS Echo Reply"},
87     { 0, NULL}
88 };
89 
90 static const struct tok lspping_reply_mode_values[] = {
91     { 1, "Do not reply"},
92     { 2, "Reply via an IPv4/IPv6 UDP packet"},
93     { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
94     { 4, "Reply via application level control channel"},
95     { 0, NULL}
96 };
97 
98 static const struct tok lspping_return_code_values[] = {
99     {  0, "No return code or return code contained in the Error Code TLV"},
100     {  1, "Malformed echo request received"},
101     {  2, "One or more of the TLVs was not understood"},
102     {  3, "Replying router is an egress for the FEC at stack depth"},
103     {  4, "Replying router has no mapping for the FEC at stack depth"},
104     {  5, "Reserved"},
105     {  6, "Reserved"},
106     {  7, "Reserved"},
107     {  8, "Label switched at stack-depth"},
108     {  9, "Label switched but no MPLS forwarding at stack-depth"},
109     { 10, "Mapping for this FEC is not the given label at stack depth"},
110     { 11, "No label entry at stack-depth"},
111     { 12, "Protocol not associated with interface at FEC stack depth"},
112 };
113 
114 
115 /*
116  * LSPPING TLV header
117  *  0                   1                   2                   3
118  *  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
119  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120  * |             Type              |            Length             |
121  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122  * |                             Value                             |
123  * .                                                               .
124  * .                                                               .
125  * .                                                               .
126  * |                                                               |
127  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128  */
129 
130 struct lspping_tlv_header {
131     u_int8_t type[2];
132     u_int8_t length[2];
133 };
134 
135 #define	LSPPING_TLV_TARGET_FEC_STACK      1
136 #define	LSPPING_TLV_DOWNSTREAM_MAPPING    2
137 #define	LSPPING_TLV_PAD                   3
138 #define LSPPING_TLV_VENDOR_ENTERPRISE     5
139 #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
140 #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
141 #define	LSPPING_TLV_ERROR_CODE            9
142 #define LSPPING_TLV_REPLY_TOS_BYTE        10
143 #define	LSPPING_TLV_BFD_DISCRIMINATOR     15 /* draft-ietf-bfd-mpls-02 */
144 #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
145 #define	LSPPING_TLV_VENDOR_PRIVATE        0xfc00
146 
147 static const struct tok lspping_tlv_values[] = {
148     { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
149     { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
150     { LSPPING_TLV_PAD, "Pad" },
151     { LSPPING_TLV_ERROR_CODE, "Error Code" },
152     { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
153     { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
154     { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
155     { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
156     { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
157     { 0, NULL}
158 };
159 
160 #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4      1
161 #define	LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6      2
162 #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4     3
163 #define	LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6     4
164 #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4    6
165 #define	LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6    7
166 #define	LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT   8
167 #define	LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9
168 #define	LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID   10
169 #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4     11
170 #define	LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6     12
171 
172 static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
173     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
174     { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
175     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
176     { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
177     { 5, "Reserved"},
178     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
179     { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
180     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
181     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"},
182     { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"},
183     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
184     { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
185     { 0, NULL}
186 };
187 
188 /*
189  *  0                   1                   2                   3
190  *  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
191  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192  * |                          IPv4 prefix                          |
193  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
194  * | Prefix Length |         Must Be Zero                          |
195  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
196  */
197 struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
198     u_int8_t prefix [4];
199     u_int8_t prefix_len;
200 };
201 
202 /*
203  *  0                   1                   2                   3
204  *  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
205  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
206  * |                          IPv6 prefix                          |
207  * |                          (16 octets)                          |
208  * |                                                               |
209  * |                                                               |
210  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211  * | Prefix Length |         Must Be Zero                          |
212  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213  */
214 struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
215     u_int8_t prefix [16];
216     u_int8_t prefix_len;
217 };
218 
219 /*
220  * 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
221  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
222  * |                    Sender identifier                          |
223  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
224  * |                         IPv4 prefix                           |
225  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
226  * | Prefix Length |                 Must Be Zero                  |
227  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228  */
229 struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
230     u_int8_t sender_id [4];
231     u_int8_t prefix [4];
232     u_int8_t prefix_len;
233 };
234 
235 /*
236  * 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
237  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238  * |                    Sender identifier                          |
239  * |                          (16 octets)                          |
240  * |                                                               |
241  * |                                                               |
242  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
243  * |                          IPv6 prefix                          |
244  * |                          (16 octets)                          |
245  * |                                                               |
246  * |                                                               |
247  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
248  * | Prefix Length |                 Must Be Zero                  |
249  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
250  */
251 struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
252     u_int8_t sender_id [16];
253     u_int8_t prefix [16];
254     u_int8_t prefix_len;
255 };
256 
257 /*
258  *  0                   1                   2                   3
259  *  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
260  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
261  * |                 IPv4 tunnel end point address                 |
262  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
263  * |          Must Be Zero         |     Tunnel ID                 |
264  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265  * |                       Extended Tunnel ID                      |
266  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
267  * |                   IPv4 tunnel sender address                  |
268  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269  * |          Must Be Zero         |            LSP ID             |
270  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271  */
272 struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
273     u_int8_t tunnel_endpoint [4];
274     u_int8_t res[2];
275     u_int8_t tunnel_id[2];
276     u_int8_t extended_tunnel_id[4];
277     u_int8_t tunnel_sender [4];
278     u_int8_t res2[2];
279     u_int8_t lsp_id [2];
280 };
281 
282 /*
283  *  0                   1                   2                   3
284  *  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
285  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
286  * |                 IPv6 tunnel end point address                 |
287  * |                                                               |
288  * |                                                               |
289  * |                                                               |
290  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
291  * |          Must Be Zero         |          Tunnel ID            |
292  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
293  * |                       Extended Tunnel ID                      |
294  * |                                                               |
295  * |                                                               |
296  * |                                                               |
297  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
298  * |                   IPv6 tunnel sender address                  |
299  * |                                                               |
300  * |                                                               |
301  * |                                                               |
302  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
303  * |          Must Be Zero         |            LSP ID             |
304  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305  */
306 struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
307     u_int8_t tunnel_endpoint [16];
308     u_int8_t res[2];
309     u_int8_t tunnel_id[2];
310     u_int8_t extended_tunnel_id[16];
311     u_int8_t tunnel_sender [16];
312     u_int8_t res2[2];
313     u_int8_t lsp_id [2];
314 };
315 
316 /*
317  *  0                   1                   2                   3
318  *  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
319  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
320  * |                      Route Distinguisher                      |
321  * |                          (8 octets)                           |
322  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323  * |                         IPv4 prefix                           |
324  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
325  * | Prefix Length |                 Must Be Zero                  |
326  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
327  */
328 struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
329     u_int8_t rd [8];
330     u_int8_t prefix [4];
331     u_int8_t prefix_len;
332 };
333 
334 /*
335  *  0                   1                   2                   3
336  *  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
337  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
338  * |                      Route Distinguisher                      |
339  * |                          (8 octets)                           |
340  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
341  * |                          IPv6 prefix                          |
342  * |                          (16 octets)                          |
343  * |                                                               |
344  * |                                                               |
345  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
346  * | Prefix Length |                 Must Be Zero                  |
347  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
348  */
349 struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
350     u_int8_t rd [8];
351     u_int8_t prefix [16];
352     u_int8_t prefix_len;
353 };
354 
355 /*
356  *  0                   1                   2                   3
357  *  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
358  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359  * |                      Route Distinguisher                      |
360  * |                          (8 octets)                           |
361  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
362  * |         Sender's CE ID        |       Receiver's CE ID        |
363  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
364  * |      Encapsulation Type       |         Must Be Zero          |
365  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
366  *  0                   1                   2                   3
367  */
368 struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
369     u_int8_t rd [8];
370     u_int8_t sender_ce_id [2];
371     u_int8_t receiver_ce_id [2];
372     u_int8_t encapsulation[2];
373 };
374 
375 /*
376  *  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
377  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
378  * |                      Remote PE Address                        |
379  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380  * |                             VC ID                             |
381  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
382  * |      Encapsulation Type       |         Must Be Zero          |
383  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
384  */
385 struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t {
386     u_int8_t remote_pe_address [4];
387     u_int8_t vc_id [4];
388     u_int8_t encapsulation[2];
389 };
390 
391 /*
392  *  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
393  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
394  * |                     Sender's PE Address                       |
395  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
396  * |                      Remote PE Address                        |
397  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398  * |                             VC ID                             |
399  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400  * |      Encapsulation Type       |         Must Be Zero          |
401  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402  */
403 struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t {
404     u_int8_t sender_pe_address [4];
405     u_int8_t remote_pe_address [4];
406     u_int8_t vc_id [4];
407     u_int8_t encapsulation[2];
408 };
409 
410 /*
411  *  0                   1                   2                   3
412  *  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
413  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
414  * |               MTU             | Address Type  |  Resvd (SBZ)  |
415  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416  * |             Downstream IP Address (4 or 16 octets)            |
417  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
418  * |         Downstream Interface Address (4 or 16 octets)         |
419  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
420  * | Hash Key Type | Depth Limit   |        Multipath Length       |
421  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
422  * .                                                               .
423  * .                     (Multipath Information)                   .
424  * .                                                               .
425  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
426  * |               Downstream Label                |    Protocol   |
427  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428  * .                                                               .
429  * .                                                               .
430  * .                                                               .
431  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
432  * |               Downstream Label                |    Protocol   |
433  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434  */
435 struct lspping_tlv_downstream_map_ipv4_t {
436     u_int8_t mtu [2];
437     u_int8_t address_type;
438     u_int8_t res;
439     u_int8_t downstream_ip[4];
440     u_int8_t downstream_interface[4];
441 };
442 
443 struct lspping_tlv_downstream_map_ipv6_t {
444     u_int8_t mtu [2];
445     u_int8_t address_type;
446     u_int8_t res;
447     u_int8_t downstream_ip[16];
448     u_int8_t downstream_interface[16];
449 };
450 
451 struct lspping_tlv_downstream_map_info_t {
452     u_int8_t hash_key_type;
453     u_int8_t depth_limit;
454     u_int8_t multipath_length [2];
455 };
456 
457 #define LSPPING_AFI_IPV4 1
458 #define LSPPING_AFI_UNMB 2
459 #define LSPPING_AFI_IPV6 3
460 
461 static const struct tok lspping_tlv_downstream_addr_values[] = {
462     { LSPPING_AFI_IPV4, "IPv4"},
463     { LSPPING_AFI_IPV6, "IPv6"},
464     { LSPPING_AFI_UNMB, "Unnumbered"},
465     { 0, NULL}
466 };
467 
468 void
lspping_print(register const u_char * pptr,register u_int len)469 lspping_print(register const u_char *pptr, register u_int len) {
470 
471     const struct lspping_common_header *lspping_com_header;
472     const struct lspping_tlv_header *lspping_tlv_header;
473     const struct lspping_tlv_header *lspping_subtlv_header;
474     const u_char *tptr,*tlv_tptr,*subtlv_tptr;
475     int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
476     int tlv_hexdump,subtlv_hexdump;
477     int lspping_subtlv_len,lspping_subtlv_type;
478     struct timeval timestamp;
479 
480     union {
481         const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
482         const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
483         const struct lspping_tlv_downstream_map_info_t  *lspping_tlv_downstream_map_info;
484     } tlv_ptr;
485 
486     union {
487         const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
488         const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
489         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
490         const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
491         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
492         const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
493         const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
494         const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
495         const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
496         const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
497         const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
498     } subtlv_ptr;
499 
500     tptr=pptr;
501     lspping_com_header = (const struct lspping_common_header *)pptr;
502     TCHECK(*lspping_com_header);
503 
504     /*
505      * Sanity checking of the header.
506      */
507     if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) {
508 	printf("LSP-PING version %u packet not supported",
509                EXTRACT_16BITS(&lspping_com_header->version[0]));
510 	return;
511     }
512 
513     /* in non-verbose mode just lets print the basic Message Type*/
514     if (vflag < 1) {
515         printf("LSP-PINGv%u, %s, seq %u, length: %u",
516                EXTRACT_16BITS(&lspping_com_header->version[0]),
517                tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type),
518                EXTRACT_32BITS(lspping_com_header->seq_number),
519                len);
520         return;
521     }
522 
523     /* ok they seem to want to know everything - lets fully decode it */
524 
525     tlen=len;
526 
527     printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t  reply-mode: %s (%u)",
528            EXTRACT_16BITS(&lspping_com_header->version[0]),
529            tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type),
530            lspping_com_header->msg_type,
531            len,
532            tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode),
533            lspping_com_header->reply_mode);
534 
535     /*
536      *  the following return codes require that the subcode is attached
537      *  at the end of the translated token output
538      */
539     if (lspping_com_header->return_code == 3 ||
540         lspping_com_header->return_code == 4 ||
541         lspping_com_header->return_code == 8 ||
542         lspping_com_header->return_code == 10 ||
543         lspping_com_header->return_code == 11 ||
544         lspping_com_header->return_code == 12 )
545         printf("\n\t  Return Code: %s %u (%u)\n\t  Return Subcode: (%u)",
546                tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
547                lspping_com_header->return_subcode,
548                lspping_com_header->return_code,
549                lspping_com_header->return_subcode);
550     else
551         printf("\n\t  Return Code: %s (%u)\n\t  Return Subcode: (%u)",
552                tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
553                lspping_com_header->return_code,
554                lspping_com_header->return_subcode);
555 
556     printf("\n\t  Sender Handle: 0x%08x, Sequence: %u",
557            EXTRACT_32BITS(lspping_com_header->sender_handle),
558            EXTRACT_32BITS(lspping_com_header->seq_number));
559 
560     timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec);
561     timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec);
562     printf("\n\t  Sender Timestamp: ");
563     ts_print(&timestamp);
564 
565     timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec);
566     timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec);
567     printf("Receiver Timestamp: ");
568     if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0))
569         ts_print(&timestamp);
570     else
571         printf("no timestamp");
572 
573     tptr+=sizeof(const struct lspping_common_header);
574     tlen-=sizeof(const struct lspping_common_header);
575 
576     while(tlen>(int)sizeof(struct lspping_tlv_header)) {
577 
578         /* did we capture enough for fully decoding the tlv header ? */
579         if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header)))
580             goto trunc;
581 
582         lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
583         lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type);
584         lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length);
585 
586         /* some little sanity checking */
587         if (lspping_tlv_type == 0 || lspping_tlv_len == 0)
588             return;
589 
590         if(lspping_tlv_len < 4) {
591             printf("\n\t  ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len);
592             return;
593         }
594 
595         printf("\n\t  %s TLV (%u), length: %u",
596                tok2str(lspping_tlv_values,
597                        "Unknown",
598                        lspping_tlv_type),
599                lspping_tlv_type,
600                lspping_tlv_len);
601 
602         tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
603         tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
604 
605         /* did we capture enough for fully decoding the tlv ? */
606         if (!TTEST2(*tptr, lspping_tlv_len))
607             goto trunc;
608         tlv_hexdump=FALSE;
609 
610         switch(lspping_tlv_type) {
611         case LSPPING_TLV_TARGET_FEC_STACK:
612             while(tlv_tlen>(int)sizeof(struct lspping_tlv_header)) {
613 
614                 /* did we capture enough for fully decoding the subtlv header ? */
615                 if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header)))
616                     goto trunc;
617                 subtlv_hexdump=FALSE;
618 
619                 lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
620                 lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type);
621                 lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length);
622                 subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
623 
624                 if (lspping_subtlv_len == 0)
625                     break;
626 
627                 printf("\n\t    %s subTLV (%u), length: %u",
628                        tok2str(lspping_tlvtargetfec_subtlv_values,
629                                "Unknown",
630                                lspping_subtlv_type),
631                        lspping_subtlv_type,
632                        lspping_subtlv_len);
633 
634                 switch(lspping_subtlv_type) {
635 
636                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
637                     subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \
638                         (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
639                     printf("\n\t      %s/%u",
640                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
641                            subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len);
642                     break;
643 
644 #ifdef INET6
645                 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
646                     subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \
647                         (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
648                     printf("\n\t      %s/%u",
649                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
650                            subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len);
651                     break;
652 #endif
653 
654                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
655                     subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \
656                         (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
657                     printf("\n\t      %s/%u, sender-id %s",
658                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
659                            subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len,
660                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id));
661                     break;
662 
663 #ifdef INET6
664                 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
665                     subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \
666                         (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
667                     printf("\n\t      %s/%u, sender-id %s",
668                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
669                            subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len,
670                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id));
671                     break;
672 #endif
673 
674                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
675                     subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \
676                         (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
677                     printf("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
678                            "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
679                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
680                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
681                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
682                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
683                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
684                     break;
685 
686 #ifdef INET6
687                 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
688                     subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \
689                         (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
690                     printf("\n\t      tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
691                            "\n\t      tunnel-id 0x%04x, extended tunnel-id %s",
692                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
693                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
694                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
695                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
696                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
697                     break;
698 #endif
699 
700                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
701                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \
702                         (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
703                     printf("\n\t      RD: %s, %s/%u",
704                            bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
705                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
706                            subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len);
707                     break;
708 
709 #ifdef INET6
710                 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
711                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \
712                         (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
713                     printf("\n\t      RD: %s, %s/%u",
714                            bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
715                            ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
716                            subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len);
717                     break;
718 #endif
719 
720                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
721                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \
722                         (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
723                     printf("\n\t      RD: %s, Sender CE-ID: %u, Receiver CE-ID: %u" \
724                            "\n\t      Encapsulation Type: %s (%u)",
725                            bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
726                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id),
727                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id),
728                            tok2str(l2vpn_encaps_values,
729                                    "unknown",
730                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
731                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
732 
733                     break;
734 
735                     /* the old L2VPN VCID subTLV does not have support for the sender field */
736                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD:
737                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \
738                         (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr;
739                     printf("\n\t      Remote PE: %s" \
740                            "\n\t      VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
741                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
742                            EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id),
743                            tok2str(l2vpn_encaps_values,
744                                    "unknown",
745                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)),
746                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation));
747 
748                     break;
749 
750                 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID:
751                     subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \
752                         (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr;
753                     printf("\n\t      Sender PE: %s, Remote PE: %s" \
754                            "\n\t      VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
755                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
756                            ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
757                            EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id),
758                            tok2str(l2vpn_encaps_values,
759                                    "unknown",
760                                    EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
761                            EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation));
762 
763                     break;
764 
765                 default:
766                     subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
767                     break;
768                 }
769                 /* do we want to see an additionally subtlv hexdump ? */
770                 if (vflag > 1 || subtlv_hexdump==TRUE)
771                     print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \
772                                        "\n\t      ",
773                                        lspping_subtlv_len);
774 
775                 tlv_tptr+=lspping_subtlv_len;
776                 tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
777             }
778             break;
779 
780         case LSPPING_TLV_DOWNSTREAM_MAPPING:
781             /* that strange thing with the downstream map TLV is that until now
782              * we do not know if its IPv4 or IPv6 , after we found the adress-type
783              * lets recast the tlv_tptr and move on */
784 
785             tlv_ptr.lspping_tlv_downstream_map_ipv4= \
786                 (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
787             tlv_ptr.lspping_tlv_downstream_map_ipv6= \
788                 (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
789             printf("\n\t    MTU: %u, Address-Type: %s (%u)",
790                    EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu),
791                    tok2str(lspping_tlv_downstream_addr_values,
792                            "unknown",
793                            tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type),
794                    tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type);
795 
796             switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) {
797 
798             case LSPPING_AFI_IPV4:
799                 printf("\n\t    Downstream IP: %s" \
800                        "\n\t    Downstream Interface IP: %s",
801                        ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
802                        ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
803                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
804                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
805                 break;
806 #ifdef INET6
807              case LSPPING_AFI_IPV6:
808                 printf("\n\t    Downstream IP: %s" \
809                        "\n\t    Downstream Interface IP: %s",
810                        ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
811                        ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
812                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
813                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
814                 break;
815 #endif
816             case LSPPING_AFI_UNMB:
817                 printf("\n\t    Downstream IP: %s" \
818                        "\n\t    Downstream Interface Index: 0x%08x",
819                        ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
820                        EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
821                 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
822                 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
823                 break;
824 
825             default:
826                 /* should not happen ! - no error message - tok2str() has barked already */
827                 break;
828             }
829 
830             tlv_ptr.lspping_tlv_downstream_map_info= \
831                 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
832 
833             /* FIXME add hash-key type, depth limit, multipath processing */
834 
835 
836             tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t);
837             tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t);
838 
839             /* FIXME print downstream labels */
840 
841 
842             tlv_hexdump=TRUE; /* dump the TLV until code complete */
843 
844             break;
845 
846         case LSPPING_TLV_BFD_DISCRIMINATOR:
847             tptr += sizeof(struct lspping_tlv_header);
848             if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN))
849                 goto trunc;
850             printf("\n\t    BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr));
851             break;
852 
853         case  LSPPING_TLV_VENDOR_ENTERPRISE:
854         {
855             u_int32_t vendor_id;
856 
857             if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN))
858                 goto trunc;
859             vendor_id = EXTRACT_32BITS(tlv_tptr);
860             printf("\n\t    Vendor: %s (0x%04x)",
861                    tok2str(smi_values, "Unknown", vendor_id),
862                    vendor_id);
863         }
864             break;
865 
866             /*
867              *  FIXME those are the defined TLVs that lack a decoder
868              *  you are welcome to contribute code ;-)
869              */
870         case LSPPING_TLV_PAD:
871         case LSPPING_TLV_ERROR_CODE:
872         case LSPPING_TLV_VENDOR_PRIVATE:
873 
874         default:
875             if (vflag <= 1)
876                 print_unknown_data(tlv_tptr,"\n\t    ",tlv_tlen);
877             break;
878         }
879         /* do we want to see an additionally tlv hexdump ? */
880         if (vflag > 1 || tlv_hexdump==TRUE)
881             print_unknown_data(tptr+sizeof(struct lspping_tlv_header),"\n\t    ",
882                                lspping_tlv_len);
883 
884 
885         /* All TLVs are aligned to four octet boundary */
886         if (lspping_tlv_len % 4) {
887             lspping_tlv_len += (4 - lspping_tlv_len % 4);
888         }
889 
890         tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
891         tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
892     }
893     return;
894 trunc:
895     printf("\n\t\t packet exceeded snapshot");
896 }
897