1*05b00f60SXin Li /*
2*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without
3*05b00f60SXin Li * modification, are permitted provided that: (1) source code
4*05b00f60SXin Li * distributions retain the above copyright notice and this paragraph
5*05b00f60SXin Li * in its entirety, and (2) distributions including binary code include
6*05b00f60SXin Li * the above copyright notice and this paragraph in its entirety in
7*05b00f60SXin Li * the documentation or other materials provided with the distribution.
8*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9*05b00f60SXin Li * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10*05b00f60SXin Li * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11*05b00f60SXin Li * FOR A PARTICULAR PURPOSE.
12*05b00f60SXin Li *
13*05b00f60SXin Li * Original code by Hannes Gredler ([email protected])
14*05b00f60SXin Li */
15*05b00f60SXin Li
16*05b00f60SXin Li /* \summary: MPLS LSP PING printer */
17*05b00f60SXin Li
18*05b00f60SXin Li /* specification: RFC 4379 */
19*05b00f60SXin Li
20*05b00f60SXin Li #ifdef HAVE_CONFIG_H
21*05b00f60SXin Li #include <config.h>
22*05b00f60SXin Li #endif
23*05b00f60SXin Li
24*05b00f60SXin Li #include "netdissect-stdinc.h"
25*05b00f60SXin Li
26*05b00f60SXin Li #define ND_LONGJMP_FROM_TCHECK
27*05b00f60SXin Li #include "netdissect.h"
28*05b00f60SXin Li #include "extract.h"
29*05b00f60SXin Li #include "addrtoname.h"
30*05b00f60SXin Li #include "ntp.h"
31*05b00f60SXin Li
32*05b00f60SXin Li #include "l2vpn.h"
33*05b00f60SXin Li #include "oui.h"
34*05b00f60SXin Li
35*05b00f60SXin Li
36*05b00f60SXin Li /*
37*05b00f60SXin Li * LSPPING common header
38*05b00f60SXin Li *
39*05b00f60SXin Li * 0 1 2 3
40*05b00f60SXin Li * 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
41*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42*05b00f60SXin Li * | Version Number | Must Be Zero |
43*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44*05b00f60SXin Li * | Message Type | Reply mode | Return Code | Return Subcode|
45*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46*05b00f60SXin Li * | Sender's Handle |
47*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48*05b00f60SXin Li * | Sequence Number |
49*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50*05b00f60SXin Li * | TimeStamp Sent (seconds) |
51*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52*05b00f60SXin Li * | TimeStamp Sent (microseconds) |
53*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54*05b00f60SXin Li * | TimeStamp Received (seconds) |
55*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56*05b00f60SXin Li * | TimeStamp Received (microseconds) |
57*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58*05b00f60SXin Li * | TLVs ... |
59*05b00f60SXin Li * . .
60*05b00f60SXin Li * . .
61*05b00f60SXin Li * . .
62*05b00f60SXin Li */
63*05b00f60SXin Li
64*05b00f60SXin Li struct lspping_common_header {
65*05b00f60SXin Li nd_uint16_t version;
66*05b00f60SXin Li nd_uint16_t global_flags;
67*05b00f60SXin Li nd_uint8_t msg_type;
68*05b00f60SXin Li nd_uint8_t reply_mode;
69*05b00f60SXin Li nd_uint8_t return_code;
70*05b00f60SXin Li nd_uint8_t return_subcode;
71*05b00f60SXin Li nd_uint32_t sender_handle;
72*05b00f60SXin Li nd_uint32_t seq_number;
73*05b00f60SXin Li struct l_fixedpt ts_sent;
74*05b00f60SXin Li struct l_fixedpt ts_rcvd;
75*05b00f60SXin Li };
76*05b00f60SXin Li
77*05b00f60SXin Li #define LSPPING_VERSION 1
78*05b00f60SXin Li
79*05b00f60SXin Li static const struct tok lspping_msg_type_values[] = {
80*05b00f60SXin Li { 1, "MPLS Echo Request"},
81*05b00f60SXin Li { 2, "MPLS Echo Reply"},
82*05b00f60SXin Li { 0, NULL}
83*05b00f60SXin Li };
84*05b00f60SXin Li
85*05b00f60SXin Li static const struct tok lspping_reply_mode_values[] = {
86*05b00f60SXin Li { 1, "Do not reply"},
87*05b00f60SXin Li { 2, "Reply via an IPv4/IPv6 UDP packet"},
88*05b00f60SXin Li { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
89*05b00f60SXin Li { 4, "Reply via application level control channel"},
90*05b00f60SXin Li { 0, NULL}
91*05b00f60SXin Li };
92*05b00f60SXin Li
93*05b00f60SXin Li static const struct tok lspping_return_code_values[] = {
94*05b00f60SXin Li { 0, "No return code or return code contained in the Error Code TLV"},
95*05b00f60SXin Li { 1, "Malformed echo request received"},
96*05b00f60SXin Li { 2, "One or more of the TLVs was not understood"},
97*05b00f60SXin Li { 3, "Replying router is an egress for the FEC at stack depth"},
98*05b00f60SXin Li { 4, "Replying router has no mapping for the FEC at stack depth"},
99*05b00f60SXin Li { 5, "Reserved"},
100*05b00f60SXin Li { 6, "Reserved"},
101*05b00f60SXin Li { 7, "Reserved"},
102*05b00f60SXin Li { 8, "Label switched at stack-depth"},
103*05b00f60SXin Li { 9, "Label switched but no MPLS forwarding at stack-depth"},
104*05b00f60SXin Li { 10, "Mapping for this FEC is not the given label at stack depth"},
105*05b00f60SXin Li { 11, "No label entry at stack-depth"},
106*05b00f60SXin Li { 12, "Protocol not associated with interface at FEC stack depth"},
107*05b00f60SXin Li { 13, "Premature termination of ping due to label stack shrinking to a single label"},
108*05b00f60SXin Li { 0, NULL},
109*05b00f60SXin Li };
110*05b00f60SXin Li
111*05b00f60SXin Li
112*05b00f60SXin Li /*
113*05b00f60SXin Li * LSPPING TLV header
114*05b00f60SXin Li * 0 1 2 3
115*05b00f60SXin Li * 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
116*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117*05b00f60SXin Li * | Type | Length |
118*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119*05b00f60SXin Li * | Value |
120*05b00f60SXin Li * . .
121*05b00f60SXin Li * . .
122*05b00f60SXin Li * . .
123*05b00f60SXin Li * | |
124*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125*05b00f60SXin Li */
126*05b00f60SXin Li
127*05b00f60SXin Li struct lspping_tlv_header {
128*05b00f60SXin Li nd_uint16_t type;
129*05b00f60SXin Li nd_uint16_t length;
130*05b00f60SXin Li };
131*05b00f60SXin Li
132*05b00f60SXin Li #define LSPPING_TLV_TARGET_FEC_STACK 1
133*05b00f60SXin Li #define LSPPING_TLV_DOWNSTREAM_MAPPING 2
134*05b00f60SXin Li #define LSPPING_TLV_PAD 3
135*05b00f60SXin Li /* not assigned 4 */
136*05b00f60SXin Li #define LSPPING_TLV_VENDOR_ENTERPRISE 5
137*05b00f60SXin Li #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
138*05b00f60SXin Li /* not assigned 6 */
139*05b00f60SXin Li #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
140*05b00f60SXin Li /* not assigned 8 */
141*05b00f60SXin Li #define LSPPING_TLV_ERROR_CODE 9
142*05b00f60SXin Li #define LSPPING_TLV_REPLY_TOS_BYTE 10
143*05b00f60SXin Li #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */
144*05b00f60SXin Li #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
145*05b00f60SXin Li #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00
146*05b00f60SXin Li
147*05b00f60SXin Li static const struct tok lspping_tlv_values[] = {
148*05b00f60SXin Li { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
149*05b00f60SXin Li { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
150*05b00f60SXin Li { LSPPING_TLV_PAD, "Pad" },
151*05b00f60SXin Li { LSPPING_TLV_ERROR_CODE, "Error Code" },
152*05b00f60SXin Li { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
153*05b00f60SXin Li { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
154*05b00f60SXin Li { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
155*05b00f60SXin Li { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
156*05b00f60SXin Li { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
157*05b00f60SXin Li { 0, NULL}
158*05b00f60SXin Li };
159*05b00f60SXin Li
160*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1
161*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2
162*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3
163*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4
164*05b00f60SXin Li /* not assigned 5 */
165*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6
166*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7
167*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8
168*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9
169*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10
170*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11
171*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12
172*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13
173*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14
174*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15
175*05b00f60SXin Li #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16
176*05b00f60SXin Li
177*05b00f60SXin Li static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
178*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
179*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
180*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
181*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
182*05b00f60SXin Li { 5, "Reserved"},
183*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
184*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
185*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
186*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"},
187*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"},
188*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
189*05b00f60SXin Li { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
190*05b00f60SXin Li { 0, NULL}
191*05b00f60SXin Li };
192*05b00f60SXin Li
193*05b00f60SXin Li /*
194*05b00f60SXin Li * 0 1 2 3
195*05b00f60SXin Li * 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
196*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197*05b00f60SXin Li * | IPv4 prefix |
198*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199*05b00f60SXin Li * | Prefix Length | Must Be Zero |
200*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201*05b00f60SXin Li */
202*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
203*05b00f60SXin Li nd_ipv4 prefix;
204*05b00f60SXin Li nd_uint8_t prefix_len;
205*05b00f60SXin Li };
206*05b00f60SXin Li
207*05b00f60SXin Li /*
208*05b00f60SXin Li * 0 1 2 3
209*05b00f60SXin Li * 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
210*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211*05b00f60SXin Li * | IPv6 prefix |
212*05b00f60SXin Li * | (16 octets) |
213*05b00f60SXin Li * | |
214*05b00f60SXin Li * | |
215*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
216*05b00f60SXin Li * | Prefix Length | Must Be Zero |
217*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218*05b00f60SXin Li */
219*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
220*05b00f60SXin Li nd_ipv6 prefix;
221*05b00f60SXin Li nd_uint8_t prefix_len;
222*05b00f60SXin Li };
223*05b00f60SXin Li
224*05b00f60SXin Li /*
225*05b00f60SXin Li * 0 1 2 3
226*05b00f60SXin Li * 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*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228*05b00f60SXin Li * | IPv4 tunnel end point address |
229*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230*05b00f60SXin Li * | Must Be Zero | Tunnel ID |
231*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232*05b00f60SXin Li * | Extended Tunnel ID |
233*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234*05b00f60SXin Li * | IPv4 tunnel sender address |
235*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
236*05b00f60SXin Li * | Must Be Zero | LSP ID |
237*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238*05b00f60SXin Li */
239*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
240*05b00f60SXin Li nd_ipv4 tunnel_endpoint;
241*05b00f60SXin Li nd_byte res[2];
242*05b00f60SXin Li nd_uint16_t tunnel_id;
243*05b00f60SXin Li nd_ipv4 extended_tunnel_id;
244*05b00f60SXin Li nd_ipv4 tunnel_sender;
245*05b00f60SXin Li nd_byte res2[2];
246*05b00f60SXin Li nd_uint16_t lsp_id;
247*05b00f60SXin Li };
248*05b00f60SXin Li
249*05b00f60SXin Li /*
250*05b00f60SXin Li * 0 1 2 3
251*05b00f60SXin Li * 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
252*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
253*05b00f60SXin Li * | IPv6 tunnel end point address |
254*05b00f60SXin Li * | |
255*05b00f60SXin Li * | |
256*05b00f60SXin Li * | |
257*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
258*05b00f60SXin Li * | Must Be Zero | Tunnel ID |
259*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
260*05b00f60SXin Li * | Extended Tunnel ID |
261*05b00f60SXin Li * | |
262*05b00f60SXin Li * | |
263*05b00f60SXin Li * | |
264*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265*05b00f60SXin Li * | IPv6 tunnel sender address |
266*05b00f60SXin Li * | |
267*05b00f60SXin Li * | |
268*05b00f60SXin Li * | |
269*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270*05b00f60SXin Li * | Must Be Zero | LSP ID |
271*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272*05b00f60SXin Li */
273*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
274*05b00f60SXin Li nd_ipv6 tunnel_endpoint;
275*05b00f60SXin Li nd_byte res[2];
276*05b00f60SXin Li nd_uint16_t tunnel_id;
277*05b00f60SXin Li nd_ipv6 extended_tunnel_id;
278*05b00f60SXin Li nd_ipv6 tunnel_sender;
279*05b00f60SXin Li nd_byte res2[2];
280*05b00f60SXin Li nd_uint16_t lsp_id;
281*05b00f60SXin Li };
282*05b00f60SXin Li
283*05b00f60SXin Li /*
284*05b00f60SXin Li * 0 1 2 3
285*05b00f60SXin Li * 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
286*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
287*05b00f60SXin Li * | Route Distinguisher |
288*05b00f60SXin Li * | (8 octets) |
289*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
290*05b00f60SXin Li * | IPv4 prefix |
291*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
292*05b00f60SXin Li * | Prefix Length | Must Be Zero |
293*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
294*05b00f60SXin Li */
295*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
296*05b00f60SXin Li nd_byte rd[8];
297*05b00f60SXin Li nd_ipv4 prefix;
298*05b00f60SXin Li nd_uint8_t prefix_len;
299*05b00f60SXin Li };
300*05b00f60SXin Li
301*05b00f60SXin Li /*
302*05b00f60SXin Li * 0 1 2 3
303*05b00f60SXin Li * 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
304*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305*05b00f60SXin Li * | Route Distinguisher |
306*05b00f60SXin Li * | (8 octets) |
307*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
308*05b00f60SXin Li * | IPv6 prefix |
309*05b00f60SXin Li * | (16 octets) |
310*05b00f60SXin Li * | |
311*05b00f60SXin Li * | |
312*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
313*05b00f60SXin Li * | Prefix Length | Must Be Zero |
314*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
315*05b00f60SXin Li */
316*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
317*05b00f60SXin Li nd_byte rd[8];
318*05b00f60SXin Li nd_ipv6 prefix;
319*05b00f60SXin Li nd_uint8_t prefix_len;
320*05b00f60SXin Li };
321*05b00f60SXin Li
322*05b00f60SXin Li /*
323*05b00f60SXin Li * 0 1 2 3
324*05b00f60SXin Li * 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
325*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326*05b00f60SXin Li * | Route Distinguisher |
327*05b00f60SXin Li * | (8 octets) |
328*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
329*05b00f60SXin Li * | Sender's VE ID | Receiver's VE ID |
330*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
331*05b00f60SXin Li * | Encapsulation Type | Must Be Zero |
332*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
333*05b00f60SXin Li * 0 1 2 3
334*05b00f60SXin Li */
335*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
336*05b00f60SXin Li nd_byte rd[8];
337*05b00f60SXin Li nd_uint16_t sender_ve_id;
338*05b00f60SXin Li nd_uint16_t receiver_ve_id;
339*05b00f60SXin Li nd_uint16_t encapsulation;
340*05b00f60SXin Li };
341*05b00f60SXin Li
342*05b00f60SXin Li /*
343*05b00f60SXin Li * 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
344*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345*05b00f60SXin Li * | Remote PE Address |
346*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347*05b00f60SXin Li * | PW ID |
348*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349*05b00f60SXin Li * | PW Type | Must Be Zero |
350*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351*05b00f60SXin Li */
352*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_fec_128_pw_old {
353*05b00f60SXin Li nd_ipv4 remote_pe_address;
354*05b00f60SXin Li nd_uint32_t pw_id;
355*05b00f60SXin Li nd_uint16_t pw_type;
356*05b00f60SXin Li };
357*05b00f60SXin Li
358*05b00f60SXin Li /*
359*05b00f60SXin Li * 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
360*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361*05b00f60SXin Li * | Sender's PE Address |
362*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363*05b00f60SXin Li * | Remote PE Address |
364*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365*05b00f60SXin Li * | PW ID |
366*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367*05b00f60SXin Li * | PW Type | Must Be Zero |
368*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369*05b00f60SXin Li */
370*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_fec_128_pw {
371*05b00f60SXin Li nd_ipv4 sender_pe_address;
372*05b00f60SXin Li nd_ipv4 remote_pe_address;
373*05b00f60SXin Li nd_uint32_t pw_id;
374*05b00f60SXin Li nd_uint16_t pw_type;
375*05b00f60SXin Li };
376*05b00f60SXin Li
377*05b00f60SXin Li /*
378*05b00f60SXin Li * 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
379*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380*05b00f60SXin Li * | IPv4 prefix |
381*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
382*05b00f60SXin Li * | Prefix Length | Must Be Zero |
383*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
384*05b00f60SXin Li */
385*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
386*05b00f60SXin Li nd_ipv4 prefix;
387*05b00f60SXin Li nd_uint8_t prefix_len;
388*05b00f60SXin Li };
389*05b00f60SXin Li
390*05b00f60SXin Li /*
391*05b00f60SXin Li * 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
392*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
393*05b00f60SXin Li * | IPv6 prefix |
394*05b00f60SXin Li * | (16 octets) |
395*05b00f60SXin Li * | |
396*05b00f60SXin Li * | |
397*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398*05b00f60SXin Li * | Prefix Length | Must Be Zero |
399*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400*05b00f60SXin Li */
401*05b00f60SXin Li struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
402*05b00f60SXin Li nd_ipv6 prefix;
403*05b00f60SXin Li nd_uint8_t prefix_len;
404*05b00f60SXin Li };
405*05b00f60SXin Li
406*05b00f60SXin Li /*
407*05b00f60SXin Li * 0 1 2 3
408*05b00f60SXin Li * 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
409*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
410*05b00f60SXin Li * | MTU | Address Type | Resvd (SBZ) |
411*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
412*05b00f60SXin Li * | Downstream IP Address (4 or 16 octets) |
413*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
414*05b00f60SXin Li * | Downstream Interface Address (4 or 16 octets) |
415*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416*05b00f60SXin Li * | Multipath Type| Depth Limit | Multipath Length |
417*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
418*05b00f60SXin Li * . .
419*05b00f60SXin Li * . (Multipath Information) .
420*05b00f60SXin Li * . .
421*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
422*05b00f60SXin Li * | Downstream Label | Protocol |
423*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
424*05b00f60SXin Li * . .
425*05b00f60SXin Li * . .
426*05b00f60SXin Li * . .
427*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428*05b00f60SXin Li * | Downstream Label | Protocol |
429*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
430*05b00f60SXin Li */
431*05b00f60SXin Li /* Enough to get the address type */
432*05b00f60SXin Li struct lspping_tlv_downstream_map_t {
433*05b00f60SXin Li nd_uint16_t mtu;
434*05b00f60SXin Li nd_uint8_t address_type;
435*05b00f60SXin Li nd_uint8_t ds_flags;
436*05b00f60SXin Li };
437*05b00f60SXin Li
438*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv4_t {
439*05b00f60SXin Li nd_uint16_t mtu;
440*05b00f60SXin Li nd_uint8_t address_type;
441*05b00f60SXin Li nd_uint8_t ds_flags;
442*05b00f60SXin Li nd_ipv4 downstream_ip;
443*05b00f60SXin Li nd_ipv4 downstream_interface;
444*05b00f60SXin Li };
445*05b00f60SXin Li
446*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv4_unmb_t {
447*05b00f60SXin Li nd_uint16_t mtu;
448*05b00f60SXin Li nd_uint8_t address_type;
449*05b00f60SXin Li nd_uint8_t ds_flags;
450*05b00f60SXin Li nd_ipv4 downstream_ip;
451*05b00f60SXin Li nd_uint32_t downstream_interface;
452*05b00f60SXin Li };
453*05b00f60SXin Li
454*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv6_t {
455*05b00f60SXin Li nd_uint16_t mtu;
456*05b00f60SXin Li nd_uint8_t address_type;
457*05b00f60SXin Li nd_uint8_t ds_flags;
458*05b00f60SXin Li nd_ipv6 downstream_ip;
459*05b00f60SXin Li nd_ipv6 downstream_interface;
460*05b00f60SXin Li };
461*05b00f60SXin Li
462*05b00f60SXin Li struct lspping_tlv_downstream_map_ipv6_unmb_t {
463*05b00f60SXin Li nd_uint16_t mtu;
464*05b00f60SXin Li nd_uint8_t address_type;
465*05b00f60SXin Li nd_uint8_t ds_flags;
466*05b00f60SXin Li nd_ipv6 downstream_ip;
467*05b00f60SXin Li nd_uint32_t downstream_interface;
468*05b00f60SXin Li };
469*05b00f60SXin Li
470*05b00f60SXin Li struct lspping_tlv_downstream_map_info_t {
471*05b00f60SXin Li nd_uint8_t multipath_type;
472*05b00f60SXin Li nd_uint8_t depth_limit;
473*05b00f60SXin Li nd_uint16_t multipath_length;
474*05b00f60SXin Li };
475*05b00f60SXin Li
476*05b00f60SXin Li #define LSPPING_AFI_IPV4 1
477*05b00f60SXin Li #define LSPPING_AFI_IPV4_UNMB 2
478*05b00f60SXin Li #define LSPPING_AFI_IPV6 3
479*05b00f60SXin Li #define LSPPING_AFI_IPV6_UNMB 4
480*05b00f60SXin Li
481*05b00f60SXin Li static const struct tok lspping_tlv_downstream_addr_values[] = {
482*05b00f60SXin Li { LSPPING_AFI_IPV4, "IPv4"},
483*05b00f60SXin Li { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"},
484*05b00f60SXin Li { LSPPING_AFI_IPV6, "IPv6"},
485*05b00f60SXin Li { LSPPING_AFI_IPV6_UNMB, "IPv6"},
486*05b00f60SXin Li { 0, NULL}
487*05b00f60SXin Li };
488*05b00f60SXin Li
489*05b00f60SXin Li void
lspping_print(netdissect_options * ndo,const u_char * pptr,u_int len)490*05b00f60SXin Li lspping_print(netdissect_options *ndo,
491*05b00f60SXin Li const u_char *pptr, u_int len)
492*05b00f60SXin Li {
493*05b00f60SXin Li const struct lspping_common_header *lspping_com_header;
494*05b00f60SXin Li const struct lspping_tlv_header *lspping_tlv_header;
495*05b00f60SXin Li const struct lspping_tlv_header *lspping_subtlv_header;
496*05b00f60SXin Li const u_char *tptr,*tlv_tptr,*subtlv_tptr;
497*05b00f60SXin Li u_int return_code, return_subcode;
498*05b00f60SXin Li u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
499*05b00f60SXin Li int tlv_hexdump,subtlv_hexdump;
500*05b00f60SXin Li u_int lspping_subtlv_len,lspping_subtlv_type;
501*05b00f60SXin Li uint32_t int_part, fraction;
502*05b00f60SXin Li u_int address_type;
503*05b00f60SXin Li
504*05b00f60SXin Li union {
505*05b00f60SXin Li const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map;
506*05b00f60SXin Li const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
507*05b00f60SXin Li const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb;
508*05b00f60SXin Li const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
509*05b00f60SXin Li const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb;
510*05b00f60SXin Li const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info;
511*05b00f60SXin Li } tlv_ptr;
512*05b00f60SXin Li
513*05b00f60SXin Li union {
514*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
515*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
516*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
517*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
518*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
519*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
520*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
521*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
522*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
523*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
524*05b00f60SXin Li const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
525*05b00f60SXin Li } subtlv_ptr;
526*05b00f60SXin Li
527*05b00f60SXin Li ndo->ndo_protocol = "lspping";
528*05b00f60SXin Li tptr=pptr;
529*05b00f60SXin Li lspping_com_header = (const struct lspping_common_header *)pptr;
530*05b00f60SXin Li if (len < sizeof(struct lspping_common_header))
531*05b00f60SXin Li goto tooshort;
532*05b00f60SXin Li ND_TCHECK_SIZE(lspping_com_header);
533*05b00f60SXin Li
534*05b00f60SXin Li /*
535*05b00f60SXin Li * Sanity checking of the header.
536*05b00f60SXin Li */
537*05b00f60SXin Li if (GET_BE_U_2(lspping_com_header->version) != LSPPING_VERSION) {
538*05b00f60SXin Li ND_PRINT("LSP-PING version %u packet not supported",
539*05b00f60SXin Li GET_BE_U_2(lspping_com_header->version));
540*05b00f60SXin Li return;
541*05b00f60SXin Li }
542*05b00f60SXin Li
543*05b00f60SXin Li /* in non-verbose mode just lets print the basic Message Type*/
544*05b00f60SXin Li if (ndo->ndo_vflag < 1) {
545*05b00f60SXin Li ND_PRINT("LSP-PINGv%u, %s, seq %u, length: %u",
546*05b00f60SXin Li GET_BE_U_2(lspping_com_header->version),
547*05b00f60SXin Li tok2str(lspping_msg_type_values, "unknown (%u)",GET_U_1(lspping_com_header->msg_type)),
548*05b00f60SXin Li GET_BE_U_4(lspping_com_header->seq_number),
549*05b00f60SXin Li len);
550*05b00f60SXin Li return;
551*05b00f60SXin Li }
552*05b00f60SXin Li
553*05b00f60SXin Li /* ok they seem to want to know everything - lets fully decode it */
554*05b00f60SXin Li
555*05b00f60SXin Li tlen=len;
556*05b00f60SXin Li
557*05b00f60SXin Li ND_PRINT("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)",
558*05b00f60SXin Li GET_BE_U_2(lspping_com_header->version),
559*05b00f60SXin Li tok2str(lspping_msg_type_values, "unknown",GET_U_1(lspping_com_header->msg_type)),
560*05b00f60SXin Li GET_U_1(lspping_com_header->msg_type),
561*05b00f60SXin Li len,
562*05b00f60SXin Li tok2str(lspping_reply_mode_values, "unknown",GET_U_1(lspping_com_header->reply_mode)),
563*05b00f60SXin Li GET_U_1(lspping_com_header->reply_mode));
564*05b00f60SXin Li
565*05b00f60SXin Li /*
566*05b00f60SXin Li * the following return codes require that the subcode is attached
567*05b00f60SXin Li * at the end of the translated token output
568*05b00f60SXin Li */
569*05b00f60SXin Li return_code = GET_U_1(lspping_com_header->return_code);
570*05b00f60SXin Li return_subcode = GET_U_1(lspping_com_header->return_subcode);
571*05b00f60SXin Li if (return_code == 3 ||
572*05b00f60SXin Li return_code == 4 ||
573*05b00f60SXin Li return_code == 8 ||
574*05b00f60SXin Li return_code == 10 ||
575*05b00f60SXin Li return_code == 11 ||
576*05b00f60SXin Li return_code == 12 )
577*05b00f60SXin Li ND_PRINT("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)",
578*05b00f60SXin Li tok2str(lspping_return_code_values, "unknown",return_code),
579*05b00f60SXin Li return_subcode,
580*05b00f60SXin Li return_code,
581*05b00f60SXin Li return_subcode);
582*05b00f60SXin Li else
583*05b00f60SXin Li ND_PRINT("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)",
584*05b00f60SXin Li tok2str(lspping_return_code_values, "unknown",return_code),
585*05b00f60SXin Li return_code,
586*05b00f60SXin Li return_subcode);
587*05b00f60SXin Li
588*05b00f60SXin Li ND_PRINT("\n\t Sender Handle: 0x%08x, Sequence: %u",
589*05b00f60SXin Li GET_BE_U_4(lspping_com_header->sender_handle),
590*05b00f60SXin Li GET_BE_U_4(lspping_com_header->seq_number));
591*05b00f60SXin Li
592*05b00f60SXin Li ND_PRINT("\n\t Sender Timestamp: ");
593*05b00f60SXin Li p_ntp_time(ndo, &lspping_com_header->ts_sent);
594*05b00f60SXin Li ND_PRINT(" ");
595*05b00f60SXin Li
596*05b00f60SXin Li int_part=GET_BE_U_4(lspping_com_header->ts_rcvd.int_part);
597*05b00f60SXin Li fraction=GET_BE_U_4(lspping_com_header->ts_rcvd.fraction);
598*05b00f60SXin Li ND_PRINT("Receiver Timestamp: ");
599*05b00f60SXin Li if (! (int_part == 0 && fraction == 0))
600*05b00f60SXin Li p_ntp_time(ndo, &lspping_com_header->ts_rcvd);
601*05b00f60SXin Li else
602*05b00f60SXin Li ND_PRINT("no timestamp");
603*05b00f60SXin Li
604*05b00f60SXin Li tptr+=sizeof(struct lspping_common_header);
605*05b00f60SXin Li tlen-=sizeof(struct lspping_common_header);
606*05b00f60SXin Li
607*05b00f60SXin Li while (tlen != 0) {
608*05b00f60SXin Li /* Does the TLV go past the end of the packet? */
609*05b00f60SXin Li if (tlen < sizeof(struct lspping_tlv_header))
610*05b00f60SXin Li goto tooshort;
611*05b00f60SXin Li
612*05b00f60SXin Li lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
613*05b00f60SXin Li lspping_tlv_type=GET_BE_U_2(lspping_tlv_header->type);
614*05b00f60SXin Li lspping_tlv_len=GET_BE_U_2(lspping_tlv_header->length);
615*05b00f60SXin Li
616*05b00f60SXin Li ND_PRINT("\n\t %s TLV (%u), length: %u",
617*05b00f60SXin Li tok2str(lspping_tlv_values,
618*05b00f60SXin Li "Unknown",
619*05b00f60SXin Li lspping_tlv_type),
620*05b00f60SXin Li lspping_tlv_type,
621*05b00f60SXin Li lspping_tlv_len);
622*05b00f60SXin Li
623*05b00f60SXin Li /* some little sanity checking */
624*05b00f60SXin Li if (lspping_tlv_len == 0) {
625*05b00f60SXin Li tptr+=sizeof(struct lspping_tlv_header);
626*05b00f60SXin Li tlen-=sizeof(struct lspping_tlv_header);
627*05b00f60SXin Li continue; /* no value to dissect */
628*05b00f60SXin Li }
629*05b00f60SXin Li
630*05b00f60SXin Li tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
631*05b00f60SXin Li tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
632*05b00f60SXin Li
633*05b00f60SXin Li /* Does the TLV go past the end of the packet? */
634*05b00f60SXin Li if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
635*05b00f60SXin Li goto tooshort;
636*05b00f60SXin Li /* did we capture enough for fully decoding the tlv ? */
637*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr, lspping_tlv_len);
638*05b00f60SXin Li tlv_hexdump=FALSE;
639*05b00f60SXin Li
640*05b00f60SXin Li switch(lspping_tlv_type) {
641*05b00f60SXin Li case LSPPING_TLV_TARGET_FEC_STACK:
642*05b00f60SXin Li while (tlv_tlen != 0) {
643*05b00f60SXin Li /* Does the subTLV header go past the end of the TLV? */
644*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_header)) {
645*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
646*05b00f60SXin Li tlv_hexdump = TRUE;
647*05b00f60SXin Li goto tlv_tooshort;
648*05b00f60SXin Li }
649*05b00f60SXin Li subtlv_hexdump=FALSE;
650*05b00f60SXin Li
651*05b00f60SXin Li lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
652*05b00f60SXin Li lspping_subtlv_type=GET_BE_U_2(lspping_subtlv_header->type);
653*05b00f60SXin Li lspping_subtlv_len=GET_BE_U_2(lspping_subtlv_header->length);
654*05b00f60SXin Li subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
655*05b00f60SXin Li
656*05b00f60SXin Li /* Does the subTLV go past the end of the TLV? */
657*05b00f60SXin Li if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
658*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
659*05b00f60SXin Li tlv_hexdump = TRUE;
660*05b00f60SXin Li goto tlv_tooshort;
661*05b00f60SXin Li }
662*05b00f60SXin Li
663*05b00f60SXin Li /* Did we capture enough for fully decoding the subTLV? */
664*05b00f60SXin Li ND_TCHECK_LEN(subtlv_tptr, lspping_subtlv_len);
665*05b00f60SXin Li
666*05b00f60SXin Li ND_PRINT("\n\t %s subTLV (%u), length: %u",
667*05b00f60SXin Li tok2str(lspping_tlvtargetfec_subtlv_values,
668*05b00f60SXin Li "Unknown",
669*05b00f60SXin Li lspping_subtlv_type),
670*05b00f60SXin Li lspping_subtlv_type,
671*05b00f60SXin Li lspping_subtlv_len);
672*05b00f60SXin Li
673*05b00f60SXin Li switch(lspping_subtlv_type) {
674*05b00f60SXin Li
675*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
676*05b00f60SXin Li /* Is the subTLV length correct? */
677*05b00f60SXin Li if (lspping_subtlv_len != 5) {
678*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 5");
679*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
680*05b00f60SXin Li } else {
681*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 =
682*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
683*05b00f60SXin Li ND_PRINT("\n\t %s/%u",
684*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
685*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len));
686*05b00f60SXin Li }
687*05b00f60SXin Li break;
688*05b00f60SXin Li
689*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
690*05b00f60SXin Li /* Is the subTLV length correct? */
691*05b00f60SXin Li if (lspping_subtlv_len != 17) {
692*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 17");
693*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
694*05b00f60SXin Li } else {
695*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 =
696*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
697*05b00f60SXin Li ND_PRINT("\n\t %s/%u",
698*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
699*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
700*05b00f60SXin Li }
701*05b00f60SXin Li break;
702*05b00f60SXin Li
703*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
704*05b00f60SXin Li /* Is the subTLV length correct? */
705*05b00f60SXin Li if (lspping_subtlv_len != 5) {
706*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 5");
707*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
708*05b00f60SXin Li } else {
709*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 =
710*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
711*05b00f60SXin Li ND_PRINT("\n\t %s/%u",
712*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
713*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len));
714*05b00f60SXin Li }
715*05b00f60SXin Li break;
716*05b00f60SXin Li
717*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
718*05b00f60SXin Li /* Is the subTLV length correct? */
719*05b00f60SXin Li if (lspping_subtlv_len != 17) {
720*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 17");
721*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
722*05b00f60SXin Li } else {
723*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 =
724*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
725*05b00f60SXin Li ND_PRINT("\n\t %s/%u",
726*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
727*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len));
728*05b00f60SXin Li }
729*05b00f60SXin Li break;
730*05b00f60SXin Li
731*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
732*05b00f60SXin Li /* Is the subTLV length correct? */
733*05b00f60SXin Li if (lspping_subtlv_len != 20) {
734*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 20");
735*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
736*05b00f60SXin Li } else {
737*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 =
738*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
739*05b00f60SXin Li ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
740*05b00f60SXin Li "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
741*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
742*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
743*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
744*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
745*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
746*05b00f60SXin Li }
747*05b00f60SXin Li break;
748*05b00f60SXin Li
749*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
750*05b00f60SXin Li /* Is the subTLV length correct? */
751*05b00f60SXin Li if (lspping_subtlv_len != 56) {
752*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 56");
753*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
754*05b00f60SXin Li } else {
755*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 =
756*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
757*05b00f60SXin Li ND_PRINT("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x"
758*05b00f60SXin Li "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
759*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
760*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
761*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
762*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
763*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
764*05b00f60SXin Li }
765*05b00f60SXin Li break;
766*05b00f60SXin Li
767*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
768*05b00f60SXin Li /* Is the subTLV length correct? */
769*05b00f60SXin Li if (lspping_subtlv_len != 13) {
770*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 13");
771*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
772*05b00f60SXin Li } else {
773*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 =
774*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
775*05b00f60SXin Li ND_PRINT("\n\t RD: %s, %s/%u",
776*05b00f60SXin Li bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
777*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
778*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
779*05b00f60SXin Li }
780*05b00f60SXin Li break;
781*05b00f60SXin Li
782*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
783*05b00f60SXin Li /* Is the subTLV length correct? */
784*05b00f60SXin Li if (lspping_subtlv_len != 25) {
785*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 25");
786*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
787*05b00f60SXin Li } else {
788*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 =
789*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
790*05b00f60SXin Li ND_PRINT("\n\t RD: %s, %s/%u",
791*05b00f60SXin Li bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
792*05b00f60SXin Li GET_IP6ADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
793*05b00f60SXin Li GET_U_1(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
794*05b00f60SXin Li }
795*05b00f60SXin Li break;
796*05b00f60SXin Li
797*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
798*05b00f60SXin Li /* Is the subTLV length correct? */
799*05b00f60SXin Li if (lspping_subtlv_len != 14) {
800*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 14");
801*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
802*05b00f60SXin Li } else {
803*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt =
804*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
805*05b00f60SXin Li ND_PRINT("\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u"
806*05b00f60SXin Li "\n\t Encapsulation Type: %s (%u)",
807*05b00f60SXin Li bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
808*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id),
809*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id),
810*05b00f60SXin Li tok2str(mpls_pw_types_values,
811*05b00f60SXin Li "unknown",
812*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
813*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
814*05b00f60SXin Li }
815*05b00f60SXin Li break;
816*05b00f60SXin Li
817*05b00f60SXin Li /* the old L2VPN VCID subTLV does not have support for the sender field */
818*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD:
819*05b00f60SXin Li /* Is the subTLV length correct? */
820*05b00f60SXin Li if (lspping_subtlv_len != 10) {
821*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 10");
822*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
823*05b00f60SXin Li } else {
824*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old =
825*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr;
826*05b00f60SXin Li ND_PRINT("\n\t Remote PE: %s"
827*05b00f60SXin Li "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
828*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
829*05b00f60SXin Li GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id),
830*05b00f60SXin Li tok2str(mpls_pw_types_values,
831*05b00f60SXin Li "unknown",
832*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)),
833*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type));
834*05b00f60SXin Li }
835*05b00f60SXin Li break;
836*05b00f60SXin Li
837*05b00f60SXin Li case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW:
838*05b00f60SXin Li /* Is the subTLV length correct? */
839*05b00f60SXin Li if (lspping_subtlv_len != 14) {
840*05b00f60SXin Li ND_PRINT("\n\t invalid subTLV length, should be 14");
841*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
842*05b00f60SXin Li } else {
843*05b00f60SXin Li subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid =
844*05b00f60SXin Li (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr;
845*05b00f60SXin Li ND_PRINT("\n\t Sender PE: %s, Remote PE: %s"
846*05b00f60SXin Li "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
847*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
848*05b00f60SXin Li GET_IPADDR_STRING(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
849*05b00f60SXin Li GET_BE_U_4(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id),
850*05b00f60SXin Li tok2str(mpls_pw_types_values,
851*05b00f60SXin Li "unknown",
852*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)),
853*05b00f60SXin Li GET_BE_U_2(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type));
854*05b00f60SXin Li }
855*05b00f60SXin Li break;
856*05b00f60SXin Li
857*05b00f60SXin Li default:
858*05b00f60SXin Li subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
859*05b00f60SXin Li break;
860*05b00f60SXin Li }
861*05b00f60SXin Li /* do we want to see an additionally subtlv hexdump ? */
862*05b00f60SXin Li if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
863*05b00f60SXin Li print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header),
864*05b00f60SXin Li "\n\t ",
865*05b00f60SXin Li lspping_subtlv_len);
866*05b00f60SXin Li
867*05b00f60SXin Li /* All subTLVs are aligned to four octet boundary */
868*05b00f60SXin Li if (lspping_subtlv_len % 4) {
869*05b00f60SXin Li lspping_subtlv_len += 4 - (lspping_subtlv_len % 4);
870*05b00f60SXin Li /* Does the subTLV, including padding, go past the end of the TLV? */
871*05b00f60SXin Li if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
872*05b00f60SXin Li ND_PRINT("\n\t\t TLV is too short");
873*05b00f60SXin Li return;
874*05b00f60SXin Li }
875*05b00f60SXin Li }
876*05b00f60SXin Li tlv_tptr+=lspping_subtlv_len;
877*05b00f60SXin Li tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
878*05b00f60SXin Li }
879*05b00f60SXin Li break;
880*05b00f60SXin Li
881*05b00f60SXin Li case LSPPING_TLV_DOWNSTREAM_MAPPING:
882*05b00f60SXin Li /* Does the header go past the end of the TLV? */
883*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
884*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
885*05b00f60SXin Li tlv_hexdump = TRUE;
886*05b00f60SXin Li goto tlv_tooshort;
887*05b00f60SXin Li }
888*05b00f60SXin Li /* Did we capture enough to get the address family? */
889*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
890*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_t));
891*05b00f60SXin Li
892*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map=
893*05b00f60SXin Li (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
894*05b00f60SXin Li
895*05b00f60SXin Li /* that strange thing with the downstream map TLV is that until now
896*05b00f60SXin Li * we do not know if its IPv4 or IPv6 or is unnumbered; after
897*05b00f60SXin Li * we find the address-type, we recast the tlv_tptr and move on. */
898*05b00f60SXin Li
899*05b00f60SXin Li address_type = GET_U_1(tlv_ptr.lspping_tlv_downstream_map->address_type);
900*05b00f60SXin Li ND_PRINT("\n\t MTU: %u, Address-Type: %s (%u)",
901*05b00f60SXin Li GET_BE_U_2(tlv_ptr.lspping_tlv_downstream_map->mtu),
902*05b00f60SXin Li tok2str(lspping_tlv_downstream_addr_values,
903*05b00f60SXin Li "unknown",
904*05b00f60SXin Li address_type),
905*05b00f60SXin Li address_type);
906*05b00f60SXin Li
907*05b00f60SXin Li switch(address_type) {
908*05b00f60SXin Li
909*05b00f60SXin Li case LSPPING_AFI_IPV4:
910*05b00f60SXin Li /* Does the data go past the end of the TLV? */
911*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
912*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
913*05b00f60SXin Li tlv_hexdump = TRUE;
914*05b00f60SXin Li goto tlv_tooshort;
915*05b00f60SXin Li }
916*05b00f60SXin Li /* Did we capture enough for this part of the TLV? */
917*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
918*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_ipv4_t));
919*05b00f60SXin Li
920*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map_ipv4=
921*05b00f60SXin Li (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
922*05b00f60SXin Li ND_PRINT("\n\t Downstream IP: %s"
923*05b00f60SXin Li "\n\t Downstream Interface IP: %s",
924*05b00f60SXin Li GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
925*05b00f60SXin Li GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
926*05b00f60SXin Li tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
927*05b00f60SXin Li tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
928*05b00f60SXin Li break;
929*05b00f60SXin Li case LSPPING_AFI_IPV4_UNMB:
930*05b00f60SXin Li /* Does the data go past the end of the TLV? */
931*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
932*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
933*05b00f60SXin Li tlv_hexdump = TRUE;
934*05b00f60SXin Li goto tlv_tooshort;
935*05b00f60SXin Li }
936*05b00f60SXin Li /* Did we capture enough for this part of the TLV? */
937*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
938*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
939*05b00f60SXin Li
940*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb=
941*05b00f60SXin Li (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
942*05b00f60SXin Li ND_PRINT("\n\t Downstream IP: %s"
943*05b00f60SXin Li "\n\t Downstream Interface Index: 0x%08x",
944*05b00f60SXin Li GET_IPADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
945*05b00f60SXin Li GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface));
946*05b00f60SXin Li tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
947*05b00f60SXin Li tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
948*05b00f60SXin Li break;
949*05b00f60SXin Li case LSPPING_AFI_IPV6:
950*05b00f60SXin Li /* Does the data go past the end of the TLV? */
951*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
952*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
953*05b00f60SXin Li tlv_hexdump = TRUE;
954*05b00f60SXin Li goto tlv_tooshort;
955*05b00f60SXin Li }
956*05b00f60SXin Li /* Did we capture enough for this part of the TLV? */
957*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
958*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_ipv6_t));
959*05b00f60SXin Li
960*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map_ipv6=
961*05b00f60SXin Li (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
962*05b00f60SXin Li ND_PRINT("\n\t Downstream IP: %s"
963*05b00f60SXin Li "\n\t Downstream Interface IP: %s",
964*05b00f60SXin Li GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
965*05b00f60SXin Li GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
966*05b00f60SXin Li tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
967*05b00f60SXin Li tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
968*05b00f60SXin Li break;
969*05b00f60SXin Li case LSPPING_AFI_IPV6_UNMB:
970*05b00f60SXin Li /* Does the data go past the end of the TLV? */
971*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
972*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
973*05b00f60SXin Li tlv_hexdump = TRUE;
974*05b00f60SXin Li goto tlv_tooshort;
975*05b00f60SXin Li }
976*05b00f60SXin Li /* Did we capture enough for this part of the TLV? */
977*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
978*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
979*05b00f60SXin Li
980*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb=
981*05b00f60SXin Li (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
982*05b00f60SXin Li ND_PRINT("\n\t Downstream IP: %s"
983*05b00f60SXin Li "\n\t Downstream Interface Index: 0x%08x",
984*05b00f60SXin Li GET_IP6ADDR_STRING(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
985*05b00f60SXin Li GET_BE_U_4(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface));
986*05b00f60SXin Li tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
987*05b00f60SXin Li tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
988*05b00f60SXin Li break;
989*05b00f60SXin Li
990*05b00f60SXin Li default:
991*05b00f60SXin Li /* should not happen ! - no error message - tok2str() has barked already */
992*05b00f60SXin Li break;
993*05b00f60SXin Li }
994*05b00f60SXin Li
995*05b00f60SXin Li /* Does the data go past the end of the TLV? */
996*05b00f60SXin Li if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
997*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
998*05b00f60SXin Li tlv_hexdump = TRUE;
999*05b00f60SXin Li goto tlv_tooshort;
1000*05b00f60SXin Li }
1001*05b00f60SXin Li /* Did we capture enough for this part of the TLV? */
1002*05b00f60SXin Li ND_TCHECK_LEN(tlv_tptr,
1003*05b00f60SXin Li sizeof(struct lspping_tlv_downstream_map_info_t));
1004*05b00f60SXin Li
1005*05b00f60SXin Li tlv_ptr.lspping_tlv_downstream_map_info=
1006*05b00f60SXin Li (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
1007*05b00f60SXin Li
1008*05b00f60SXin Li /* FIXME add hash-key type, depth limit, multipath processing */
1009*05b00f60SXin Li
1010*05b00f60SXin Li /* FIXME print downstream labels */
1011*05b00f60SXin Li
1012*05b00f60SXin Li tlv_hexdump=TRUE; /* dump the TLV until code complete */
1013*05b00f60SXin Li
1014*05b00f60SXin Li break;
1015*05b00f60SXin Li
1016*05b00f60SXin Li case LSPPING_TLV_BFD_DISCRIMINATOR:
1017*05b00f60SXin Li if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
1018*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
1019*05b00f60SXin Li tlv_hexdump = TRUE;
1020*05b00f60SXin Li goto tlv_tooshort;
1021*05b00f60SXin Li } else {
1022*05b00f60SXin Li ND_PRINT("\n\t BFD Discriminator 0x%08x", GET_BE_U_4(tlv_tptr));
1023*05b00f60SXin Li }
1024*05b00f60SXin Li break;
1025*05b00f60SXin Li
1026*05b00f60SXin Li case LSPPING_TLV_VENDOR_ENTERPRISE:
1027*05b00f60SXin Li {
1028*05b00f60SXin Li uint32_t vendor_id;
1029*05b00f60SXin Li
1030*05b00f60SXin Li if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
1031*05b00f60SXin Li ND_PRINT("\n\t TLV is too short");
1032*05b00f60SXin Li tlv_hexdump = TRUE;
1033*05b00f60SXin Li goto tlv_tooshort;
1034*05b00f60SXin Li } else {
1035*05b00f60SXin Li vendor_id = GET_BE_U_4(tlv_tptr);
1036*05b00f60SXin Li ND_PRINT("\n\t Vendor: %s (0x%04x)",
1037*05b00f60SXin Li tok2str(smi_values, "Unknown", vendor_id),
1038*05b00f60SXin Li vendor_id);
1039*05b00f60SXin Li }
1040*05b00f60SXin Li }
1041*05b00f60SXin Li break;
1042*05b00f60SXin Li
1043*05b00f60SXin Li /*
1044*05b00f60SXin Li * FIXME those are the defined TLVs that lack a decoder
1045*05b00f60SXin Li * you are welcome to contribute code ;-)
1046*05b00f60SXin Li */
1047*05b00f60SXin Li case LSPPING_TLV_PAD:
1048*05b00f60SXin Li case LSPPING_TLV_ERROR_CODE:
1049*05b00f60SXin Li case LSPPING_TLV_VENDOR_PRIVATE:
1050*05b00f60SXin Li
1051*05b00f60SXin Li default:
1052*05b00f60SXin Li if (ndo->ndo_vflag <= 1)
1053*05b00f60SXin Li print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen);
1054*05b00f60SXin Li break;
1055*05b00f60SXin Li }
1056*05b00f60SXin Li /* do we want to see an additionally tlv hexdump ? */
1057*05b00f60SXin Li tlv_tooshort:
1058*05b00f60SXin Li if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
1059*05b00f60SXin Li print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ",
1060*05b00f60SXin Li lspping_tlv_len);
1061*05b00f60SXin Li
1062*05b00f60SXin Li
1063*05b00f60SXin Li /* All TLVs are aligned to four octet boundary */
1064*05b00f60SXin Li if (lspping_tlv_len % 4) {
1065*05b00f60SXin Li lspping_tlv_len += (4 - lspping_tlv_len % 4);
1066*05b00f60SXin Li /* Does the TLV, including padding, go past the end of the packet? */
1067*05b00f60SXin Li if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
1068*05b00f60SXin Li goto tooshort;
1069*05b00f60SXin Li }
1070*05b00f60SXin Li
1071*05b00f60SXin Li tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
1072*05b00f60SXin Li tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
1073*05b00f60SXin Li }
1074*05b00f60SXin Li return;
1075*05b00f60SXin Li tooshort:
1076*05b00f60SXin Li ND_PRINT("\n\t\t packet is too short");
1077*05b00f60SXin Li }
1078