]> The Tcpdump Group git mirrors - tcpdump/blob - print-lspping.c
Rename 'tcpdump-stdinc.h' to 'netdissect-stdinc.h'
[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 #ifdef INET6
633 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
634 subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \
635 (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
636 ND_PRINT((ndo, "\n\t %s/%u",
637 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
638 subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
639 break;
640 #endif
641
642 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
643 subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \
644 (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
645 ND_PRINT((ndo, "\n\t %s/%u, sender-id %s",
646 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
647 subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len,
648 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id)));
649 break;
650
651 #ifdef INET6
652 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
653 subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \
654 (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
655 ND_PRINT((ndo, "\n\t %s/%u, sender-id %s",
656 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
657 subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len,
658 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id)));
659 break;
660 #endif
661
662 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
663 subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \
664 (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
665 ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
666 "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
667 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
668 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
669 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
670 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
671 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)));
672 break;
673
674 #ifdef INET6
675 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
676 subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \
677 (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
678 ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
679 "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
680 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
681 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
682 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
683 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
684 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)));
685 break;
686 #endif
687
688 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
689 subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \
690 (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
691 ND_PRINT((ndo, "\n\t RD: %s, %s/%u",
692 bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
693 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
694 subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
695 break;
696
697 #ifdef INET6
698 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
699 subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \
700 (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
701 ND_PRINT((ndo, "\n\t RD: %s, %s/%u",
702 bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
703 ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
704 subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
705 break;
706 #endif
707
708 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
709 subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \
710 (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
711 ND_PRINT((ndo, "\n\t RD: %s, Sender CE-ID: %u, Receiver CE-ID: %u" \
712 "\n\t Encapsulation Type: %s (%u)",
713 bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
714 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id),
715 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id),
716 tok2str(l2vpn_encaps_values,
717 "unknown",
718 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
719 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)));
720
721 break;
722
723 /* the old L2VPN VCID subTLV does not have support for the sender field */
724 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD:
725 subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \
726 (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr;
727 ND_PRINT((ndo, "\n\t Remote PE: %s" \
728 "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
729 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
730 EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id),
731 tok2str(l2vpn_encaps_values,
732 "unknown",
733 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)),
734 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)));
735
736 break;
737
738 case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID:
739 subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \
740 (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr;
741 ND_PRINT((ndo, "\n\t Sender PE: %s, Remote PE: %s" \
742 "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
743 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
744 ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
745 EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id),
746 tok2str(l2vpn_encaps_values,
747 "unknown",
748 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
749 EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)));
750
751 break;
752
753 default:
754 subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
755 break;
756 }
757 /* do we want to see an additionally subtlv hexdump ? */
758 if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
759 print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), \
760 "\n\t ",
761 lspping_subtlv_len);
762
763 tlv_tptr+=lspping_subtlv_len;
764 tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
765 }
766 break;
767
768 case LSPPING_TLV_DOWNSTREAM_MAPPING:
769 /* that strange thing with the downstream map TLV is that until now
770 * we do not know if its IPv4 or IPv6 , after we found the address-type
771 * lets recast the tlv_tptr and move on */
772
773 tlv_ptr.lspping_tlv_downstream_map_ipv4= \
774 (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
775 tlv_ptr.lspping_tlv_downstream_map_ipv6= \
776 (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
777 ND_PRINT((ndo, "\n\t MTU: %u, Address-Type: %s (%u)",
778 EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu),
779 tok2str(lspping_tlv_downstream_addr_values,
780 "unknown",
781 tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type),
782 tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type));
783
784 switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) {
785
786 case LSPPING_AFI_IPV4:
787 ND_PRINT((ndo, "\n\t Downstream IP: %s" \
788 "\n\t Downstream Interface IP: %s",
789 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
790 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)));
791 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
792 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
793 break;
794 #ifdef INET6
795 case LSPPING_AFI_IPV6:
796 ND_PRINT((ndo, "\n\t Downstream IP: %s" \
797 "\n\t Downstream Interface IP: %s",
798 ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
799 ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)));
800 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
801 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
802 break;
803 #endif
804 case LSPPING_AFI_UNMB:
805 ND_PRINT((ndo, "\n\t Downstream IP: %s" \
806 "\n\t Downstream Interface Index: 0x%08x",
807 ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
808 EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)));
809 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
810 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
811 break;
812
813 default:
814 /* should not happen ! - no error message - tok2str() has barked already */
815 break;
816 }
817
818 tlv_ptr.lspping_tlv_downstream_map_info= \
819 (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
820
821 /* FIXME add hash-key type, depth limit, multipath processing */
822
823
824 tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t);
825 tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t);
826
827 /* FIXME print downstream labels */
828
829
830 tlv_hexdump=TRUE; /* dump the TLV until code complete */
831
832 break;
833
834 case LSPPING_TLV_BFD_DISCRIMINATOR:
835 tptr += sizeof(struct lspping_tlv_header);
836 ND_TCHECK2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN);
837 ND_PRINT((ndo, "\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)));
838 break;
839
840 case LSPPING_TLV_VENDOR_ENTERPRISE:
841 {
842 uint32_t vendor_id;
843
844 ND_TCHECK2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN);
845 vendor_id = EXTRACT_32BITS(tlv_tptr);
846 ND_PRINT((ndo, "\n\t Vendor: %s (0x%04x)",
847 tok2str(smi_values, "Unknown", vendor_id),
848 vendor_id));
849 }
850 break;
851
852 /*
853 * FIXME those are the defined TLVs that lack a decoder
854 * you are welcome to contribute code ;-)
855 */
856 case LSPPING_TLV_PAD:
857 case LSPPING_TLV_ERROR_CODE:
858 case LSPPING_TLV_VENDOR_PRIVATE:
859
860 default:
861 if (ndo->ndo_vflag <= 1)
862 print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen);
863 break;
864 }
865 /* do we want to see an additionally tlv hexdump ? */
866 if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
867 print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ",
868 lspping_tlv_len);
869
870
871 /* All TLVs are aligned to four octet boundary */
872 if (lspping_tlv_len % 4) {
873 lspping_tlv_len += (4 - lspping_tlv_len % 4);
874 }
875
876 tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
877 tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
878 }
879 return;
880 trunc:
881 ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
882 }
883 /*
884 * Local Variables:
885 * c-style: whitesmith
886 * c-basic-offset: 8
887 * End:
888 */