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(×tamp);
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(×tamp);
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