print-lspping.c revision 225736
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
17static 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
67struct 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
84static const struct tok lspping_msg_type_values[] = {
85    { 1, "MPLS Echo Request"},
86    { 2, "MPLS Echo Reply"},
87    { 0, NULL}
88};
89
90static 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
98static 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
130struct 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
147static 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
172static 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 */
197struct 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 */
214struct 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 */
229struct 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 */
251struct 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 */
272struct 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 */
306struct 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 */
328struct 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 */
349struct 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 */
368struct 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 */
385struct 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 */
403struct 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 */
435struct 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
443struct 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
451struct 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
461static 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
468void
469lspping_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(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;
894trunc:
895    printf("\n\t\t packet exceeded snapshot");
896}
897