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