1 /* packet-mpls-echo.c
2  * Routines for Multiprotocol Label Switching Echo dissection
3  * Copyright 2004, Carlos Pignataro <cpignata@cisco.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * (c) Copyright 2011, Jaihari Kalijanakiraman <jaiharik@ipinfusion.com>
10  *                     Krishnamurthy Mayya <krishnamurthy.mayya@ipinfusion.com>
11  *                     Nikitha Malgi       <malgi.nikitha@ipinfusion.com>
12  *                     - Support for LSP Ping extensions as per RFC 6426
13  *                     Mayuresh Raut    <msraut@ncsu.edu>
14  *                     - Support for LSP ping over MPLS as per RFC 6424
15  * (c) Copyright 2012, Subramanian Ramachandran <sramach6@ncsu.edu>
16  *                     - Support for BFD for MPLS as per RFC 5884
17  *
18  * SPDX-License-Identifier: GPL-2.0-or-later
19  */
20 
21 #include "config.h"
22 
23 #include <epan/packet.h>
24 #include <epan/addr_resolv.h>
25 #include <epan/expert.h>
26 #include <epan/to_str.h>
27 
28 #include "packet-ldp.h"
29 #include "packet-mpls.h"
30 
31 void proto_register_mpls_echo(void);
32 void proto_reg_handoff_mpls_echo(void);
33 
34 #define UDP_PORT_MPLS_ECHO 3503
35 
36 static int proto_mpls_echo = -1;
37 static int hf_mpls_echo_version = -1;
38 static int hf_mpls_echo_mbz = -1;
39 static int hf_mpls_echo_gflags = -1;
40 static int hf_mpls_echo_flag_sbz = -1;
41 static int hf_mpls_echo_flag_v = -1;
42 static int hf_mpls_echo_flag_t = -1;
43 static int hf_mpls_echo_flag_r = -1;
44 static int hf_mpls_echo_msgtype = -1;
45 static int hf_mpls_echo_replymode = -1;
46 static int hf_mpls_echo_returncode = -1;
47 static int hf_mpls_echo_returnsubcode = -1;
48 static int hf_mpls_echo_handle = -1;
49 static int hf_mpls_echo_sequence = -1;
50 static int hf_mpls_echo_ts_sent = -1;
51 static int hf_mpls_echo_ts_rec = -1;
52 static int hf_mpls_echo_tlv_type = -1;
53 static int hf_mpls_echo_tlv_len = -1;
54 static int hf_mpls_echo_tlv_value = -1;
55 static int hf_mpls_echo_tlv_fec_type = -1;
56 static int hf_mpls_echo_tlv_fec_len = -1;
57 static int hf_mpls_echo_tlv_fec_value = -1;
58 static int hf_mpls_echo_tlv_fec_ldp_ipv4 = -1;
59 static int hf_mpls_echo_tlv_fec_ldp_ipv4_mask = -1;
60 static int hf_mpls_echo_tlv_fec_ldp_ipv6 = -1;
61 static int hf_mpls_echo_tlv_fec_ldp_ipv6_mask = -1;
62 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint = -1;
63 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint = -1;
64 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz1 = -1;
65 static int hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id = -1;
66 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id = -1;
67 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender = -1;
68 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id = -1;
69 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender = -1;
70 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz2 = -1;
71 static int hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id = -1;
72 static int hf_mpls_echo_tlv_fec_vpn_route_dist = -1;
73 static int hf_mpls_echo_tlv_fec_vpn_ipv4 = -1;
74 static int hf_mpls_echo_tlv_fec_vpn_len = -1;
75 static int hf_mpls_echo_tlv_fec_vpn_ipv6 = -1;
76 static int hf_mpls_echo_tlv_fec_l2_vpn_route_dist = -1;
77 static int hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id = -1;
78 static int hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id = -1;
79 static int hf_mpls_echo_tlv_fec_l2_vpn_encap_type = -1;
80 static int hf_mpls_echo_tlv_fec_l2cid_sender = -1;
81 static int hf_mpls_echo_tlv_fec_l2cid_remote = -1;
82 static int hf_mpls_echo_tlv_fec_l2cid_vcid = -1;
83 static int hf_mpls_echo_tlv_fec_l2cid_encap = -1;
84 static int hf_mpls_echo_tlv_fec_l2cid_mbz = -1;
85 static int hf_mpls_echo_tlv_fec_bgp_ipv4 = -1;
86 static int hf_mpls_echo_tlv_fec_bgp_ipv6 = -1;
87 static int hf_mpls_echo_tlv_fec_bgp_len = -1;
88 static int hf_mpls_echo_tlv_fec_gen_ipv4 = -1;
89 static int hf_mpls_echo_tlv_fec_gen_ipv4_mask = -1;
90 static int hf_mpls_echo_tlv_fec_gen_ipv6 = -1;
91 static int hf_mpls_echo_tlv_fec_gen_ipv6_mask = -1;
92 static int hf_mpls_echo_tlv_fec_nil_label = -1;
93 static int hf_mpls_echo_tlv_fec_pw_ipv6_128_sender = -1;
94 static int hf_mpls_echo_tlv_fec_pw_ipv6_128_remote = -1;
95 static int hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_id = -1;
96 static int hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_type = -1;
97 static int hf_mpls_echo_tlv_fec_pw_ipv6_128_mbz = -1;
98 static int hf_mpls_echo_tlv_fec_igp_ipv4 = -1;
99 static int hf_mpls_echo_tlv_fec_igp_ipv6 = -1;
100 static int hf_mpls_echo_tlv_fec_igp_mask = -1;
101 static int hf_mpls_echo_tlv_fec_igp_protocol = -1;
102 static int hf_mpls_echo_tlv_fec_igp_reserved = -1;
103 static int hf_mpls_echo_tlv_fec_igp_adj_type = -1;
104 static int hf_mpls_echo_tlv_fec_igp_adj_local_ipv4 = -1;
105 static int hf_mpls_echo_tlv_fec_igp_adj_local_ipv6 = -1;
106 static int hf_mpls_echo_tlv_fec_igp_adj_local_ident = -1;
107 static int hf_mpls_echo_tlv_fec_igp_adj_remote_ipv4 = -1;
108 static int hf_mpls_echo_tlv_fec_igp_adj_remote_ipv6 = -1;
109 static int hf_mpls_echo_tlv_fec_igp_adj_remote_ident = -1;
110 static int hf_mpls_echo_tlv_fec_igp_adj_adv_ident_ospf = -1;
111 static int hf_mpls_echo_tlv_fec_igp_adj_adv_ident_isis = -1;
112 static int hf_mpls_echo_tlv_fec_igp_adj_adv_ident = -1;
113 static int hf_mpls_echo_tlv_fec_igp_adj_rec_ident_ospf = -1;
114 static int hf_mpls_echo_tlv_fec_igp_adj_rec_ident_isis = -1;
115 static int hf_mpls_echo_tlv_fec_igp_adj_rec_ident = -1;
116 static int hf_mpls_echo_tlv_ds_map_mtu = -1;
117 static int hf_mpls_echo_tlv_ds_map_addr_type = -1;
118 static int hf_mpls_echo_tlv_ds_map_res = -1;
119 static int hf_mpls_echo_tlv_ds_map_flag_res = -1;
120 static int hf_mpls_echo_tlv_ds_map_flag_i = -1;
121 static int hf_mpls_echo_tlv_ds_map_flag_n = -1;
122 static int hf_mpls_echo_tlv_ds_map_ds_ip = -1;
123 static int hf_mpls_echo_tlv_ds_map_int_ip = -1;
124 static int hf_mpls_echo_tlv_ds_map_if_index = -1;
125 static int hf_mpls_echo_tlv_ds_map_ds_ipv6 = -1;
126 static int hf_mpls_echo_tlv_ds_map_int_ipv6 = -1;
127 static int hf_mpls_echo_tlv_ds_map_hash_type = -1;
128 static int hf_mpls_echo_tlv_ds_map_depth = -1;
129 static int hf_mpls_echo_tlv_ds_map_muti_len = -1;
130 static int hf_mpls_echo_tlv_ds_map_mp_ip = -1;
131 static int hf_mpls_echo_tlv_ds_map_mp_mask = -1;
132 static int hf_mpls_echo_tlv_ds_map_mp_ip_low = -1;
133 static int hf_mpls_echo_tlv_ds_map_mp_ip_high = -1;
134 static int hf_mpls_echo_tlv_ds_map_mp_no_multipath_info = -1;
135 static int hf_mpls_echo_tlv_ds_map_mp_value = -1;
136 static int hf_mpls_echo_tlv_ds_map_mp_label = -1;
137 static int hf_mpls_echo_tlv_ds_map_mp_exp = -1;
138 static int hf_mpls_echo_tlv_ds_map_mp_bos = -1;
139 static int hf_mpls_echo_tlv_ds_map_mp_proto = -1;
140 static int hf_mpls_echo_tlv_dd_map_mtu = -1;
141 static int hf_mpls_echo_tlv_dd_map_addr_type = -1;
142 static int hf_mpls_echo_tlv_dd_map_res = -1;
143 static int hf_mpls_echo_tlv_dd_map_flag_res = -1;
144 static int hf_mpls_echo_tlv_dd_map_flag_i = -1;
145 static int hf_mpls_echo_tlv_dd_map_flag_n = -1;
146 static int hf_mpls_echo_tlv_dd_map_ds_ip = -1;
147 static int hf_mpls_echo_tlv_dd_map_int_ip = -1;
148 static int hf_mpls_echo_tlv_dd_map_ds_ipv6 = -1;
149 static int hf_mpls_echo_tlv_dd_map_int_ipv6 = -1;
150 static int hf_mpls_echo_tlv_dd_map_return_code = -1;
151 static int hf_mpls_echo_tlv_dd_map_return_subcode = -1;
152 static int hf_mpls_echo_tlv_dd_map_subtlv_len = -1;
153 static int hf_mpls_echo_tlv_dd_map_ingress_if_num = -1;
154 static int hf_mpls_echo_tlv_dd_map_egress_if_num = -1;
155 static int hf_mpls_echo_sub_tlv_multipath_type = -1;
156 static int hf_mpls_echo_sub_tlv_multipath_length = -1;
157 static int hf_mpls_echo_sub_tlv_multipath_value = -1;
158 static int hf_mpls_echo_sub_tlv_resv = -1;
159 static int hf_mpls_echo_sub_tlv_multipath_info = -1;
160 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_label = -1; */
161 static int hf_mpls_echo_tlv_ddstlv_map_mp_proto = -1;
162 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_exp = -1; */
163 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_bos = -1; */
164 static int hf_mpls_echo_sub_tlv_multipath_ip = -1;
165 static int hf_mpls_echo_sub_tlv_mp_ip_low = -1;
166 static int hf_mpls_echo_sub_tlv_mp_ip_high = -1;
167 static int hf_mpls_echo_sub_tlv_mp_mask = -1;
168 static int hf_mpls_echo_sub_tlv_op_type = -1;
169 static int hf_mpls_echo_sub_tlv_addr_type = -1;
170 static int hf_mpls_echo_sub_tlv_fec_tlv_value = -1;
171 static int hf_mpls_echo_sub_tlv_label = -1;
172 static int hf_mpls_echo_sub_tlv_traffic_class = -1;
173 static int hf_mpls_echo_sub_tlv_s_bit = -1;
174 static int hf_mpls_echo_sub_tlv_res = -1;
175 static int hf_mpls_echo_sub_tlv_remote_peer_unspecified = -1;
176 static int hf_mpls_echo_sub_tlv_remote_peer_ip = -1;
177 static int hf_mpls_echo_sub_tlv_remore_peer_ipv6 = -1;
178 static int hf_mpls_echo_tlv_dd_map_type = -1;
179 static int hf_mpls_echo_tlv_dd_map_length = -1;
180 static int hf_mpls_echo_tlv_dd_map_value = -1;
181 static int hf_mpls_echo_tlv_padaction = -1;
182 static int hf_mpls_echo_tlv_padding = -1;
183 static int hf_mpls_echo_tlv_vendor = -1;
184 static int hf_mpls_echo_tlv_ilso_addr_type = -1;
185 static int hf_mpls_echo_tlv_ilso_mbz = -1;
186 static int hf_mpls_echo_tlv_ilso_ipv4_addr = -1;
187 static int hf_mpls_echo_tlv_ilso_ipv4_int_addr = -1;
188 static int hf_mpls_echo_tlv_ilso_ipv6_addr = -1;
189 static int hf_mpls_echo_tlv_ilso_ipv6_int_addr = -1;
190 static int hf_mpls_echo_tlv_ilso_int_index = -1;
191 static int hf_mpls_echo_tlv_ilso_label = -1;
192 static int hf_mpls_echo_tlv_ilso_exp = -1;
193 static int hf_mpls_echo_tlv_ilso_bos = -1;
194 static int hf_mpls_echo_tlv_ilso_ttl = -1;
195 #if 0
196 static int hf_mpls_echo_tlv_rto_ipv4 = -1;
197 static int hf_mpls_echo_tlv_rto_ipv6 = -1;
198 #endif
199 static int hf_mpls_echo_tlv_reply_tos = -1;
200 static int hf_mpls_echo_tlv_reply_tos_mbz = -1;
201 static int hf_mpls_echo_tlv_errored_type = -1;
202 static int hf_mpls_echo_tlv_ds_map_ingress_if_num = -1;
203 static int hf_mpls_echo_tlv_ds_map_egress_if_num = -1;
204 static int hf_mpls_echo_lspping_tlv_src_gid = -1;
205 static int hf_mpls_echo_lspping_tlv_src_nid = -1;
206 static int hf_mpls_echo_lspping_tlv_src_tunnel_no = -1;
207 static int hf_mpls_echo_lspping_tlv_lsp_no = -1;
208 static int hf_mpls_echo_lspping_tlv_dst_gid = -1;
209 static int hf_mpls_echo_lspping_tlv_dst_nid = -1;
210 static int hf_mpls_echo_lspping_tlv_dst_tunnel_no = -1;
211 static int hf_mpls_echo_lspping_tlv_resv = -1;
212 static int hf_mpls_echo_lspping_tlv_src_addr_gid = -1;
213 static int hf_mpls_echo_lspping_tlv_src_addr_nid=-1;
214 static int hf_mpls_echo_lspping_tlv_pw_serv_identifier = -1;
215 static int hf_mpls_echo_lspping_tlv_pw_src_ac_id = -1;
216 static int hf_mpls_echo_lspping_tlv_pw_dst_ac_id = -1;
217 static int hf_mpls_echo_padding = -1;
218 /* static int hf_mpls_echo_lspping_tlv_pw_agi_type = -1; */
219 /* static int hf_mpls_echo_lspping_tlv_pw_agi_len = -1; */
220 /* static int hf_mpls_echo_lspping_tlv_pw_agi_val = -1; */
221 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id = -1;
222 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1 = -1;
223 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id = -1;
224 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id = -1;
225 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender = -1;
226 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2 = -1;
227 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id = -1;
228 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id = -1;
229 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id = -1;
230 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender = -1;
231 static int hf_mpls_echo_tlv_echo_jitter = -1;
232 static int hf_mpls_echo_tlv_responder_indent_type = -1;
233 static int hf_mpls_echo_tlv_responder_indent_len = -1;
234 static int hf_mpls_echo_tlv_responder_indent_ipv4 = -1;
235 /* static int hf_mpls_echo_tlv_responder_indent_ipv6 = -1; */
236 static int hf_mpls_echo_tlv_bfd = -1;
237 
238 static gint ett_mpls_echo = -1;
239 static gint ett_mpls_echo_gflags = -1;
240 static gint ett_mpls_echo_tlv = -1;
241 static gint ett_mpls_echo_tlv_fec = -1;
242 static gint ett_mpls_echo_tlv_ds_map = -1;
243 static gint ett_mpls_echo_tlv_ilso = -1;
244 static gint ett_mpls_echo_tlv_dd_map = -1;
245 static gint ett_mpls_echo_tlv_ddstlv_map = -1;
246 
247 static expert_field ei_mpls_echo_tlv_fec_len = EI_INIT;
248 static expert_field ei_mpls_echo_tlv_dd_map_subtlv_len = EI_INIT;
249 static expert_field ei_mpls_echo_tlv_len = EI_INIT;
250 static expert_field ei_mpls_echo_tlv_ds_map_muti_len = EI_INIT;
251 static expert_field ei_mpls_echo_unknown_address_type = EI_INIT;
252 static expert_field ei_mpls_echo_incorrect_address_type = EI_INIT;
253 static expert_field ei_mpls_echo_malformed = EI_INIT;
254 
255 static const value_string mpls_echo_msgtype[] = {
256     {1, "MPLS Echo Request"},
257     {2, "MPLS Echo Reply"},
258     {3, "MPLS Data Plane Verification Request"},
259     {4, "MPLS Data Plane Verification Reply"},
260     {0, NULL}
261 };
262 
263 static const value_string mpls_echo_replymode[] = {
264     {1, "Do not reply"},
265     {2, "Reply via an IPv4/IPv6 UDP packet"},
266     {3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
267     {4, "Reply via application level control channel"},
268     {0, NULL}
269 };
270 
271 /* http://www.iana.org/assignments/mpls-lsp-ping-parameters/mpls-lsp-ping-parameters.xml */
272 static const value_string mpls_echo_returncode[] = {
273     { 0, "No return code"},
274     { 1, "Malformed echo request received"},
275     { 2, "One or more of the TLVs was not understood"},
276     { 3, "Replying router is an egress for the FEC at stack depth RSC"},
277     { 4, "Replying router has no mapping for the FEC at stack depth RSC"},
278     { 5, "Downstream Mapping Mismatch"}, /*[RFC4379] */
279     { 6, "Upstream Interface Index Unknown"}, /*[RFC4379]*/
280     { 7, "Reserved"},
281     { 8, "Label switched at stack-depth RSC"},
282     { 9, "Label switched but no MPLS forwarding at stack-depth RSC"},
283     {10, "Mapping for this FEC is not the given label at stack depth RSC"},
284     {11, "No label entry at stack-depth RSC"},
285     {12, "Protocol not associated with interface at FEC stack depth RSC"},
286     {13, "Premature termination, label stack shrinking to a single label"},
287     {14, "See DDM TLV for meaning of Return Code and Return SubCode"}, /* [RFC6424] */
288     {15, "Label switched with FEC change"}, /* [RFC6424] */
289     /* 16-251 Unassigned */
290     /* 252-255 Reserved for Vendor private use [RFC4379 */
291     {0, NULL}
292 };
293 static value_string_ext mpls_echo_returncode_ext = VALUE_STRING_EXT_INIT(mpls_echo_returncode);
294 
295 #define TLV_TARGET_FEC_STACK       0x0001
296 #define TLV_DOWNSTREAM_MAPPING     0x0002
297 #define TLV_PAD                    0x0003
298 #define TLV_ERROR_CODE             0x0004
299 #define TLV_VENDOR_CODE            0x0005
300 #define TLV_TBD                    0x0006
301 #define TLV_ILSO_IPv4              0x0007
302 #define TLV_ILSO_IPv6              0x0008
303 #define TLV_ERRORED_TLV            0x0009
304 #define TLV_REPLY_TOS              0x000A
305 #if 0
306 #define TLV_RTO_IPv4               0x000B
307 #define TLV_RTO_IPv6               0x000C
308 #endif
309 #define TLV_P2MP_RESPONDER_IDENT   0x000B
310 #define TLV_P2MP_ECHO_JITTER       0x000C
311 /* As per RFC 6426 https://tools.ietf.org/html/rfc6426 Section: 2.2.1 */
312 #define TLV_SRC_IDENTIFIER         0x000D
313 #define TLV_DST_IDENTIFIER         0x000E
314 /* As per RFC 5884 https://tools.ietf.org/html/rfc5884 Section: 6.1 */
315 #define TLV_BFD_DISCRIMINATOR      0x000F
316 /* As per RFC 6426 https://tools.ietf.org/html/rfc6426 Section: 7.3 */
317 #define TLV_REVERSE_PATH_FEC_STACK 0x0010
318 #define TLV_DETAILED_DOWNSTREAM    0x0014 /* [RFC6424] */
319 #define TLV_VENDOR_PRIVATE_START   0xFC00
320 #define TLV_VENDOR_PRIVATE_END     0xFFFF
321 
322 /* MPLS Echo TLV Type names */
323 static const value_string mpls_echo_tlv_type_names[] = {
324     { TLV_TARGET_FEC_STACK,          "Target FEC Stack" },
325     { TLV_DOWNSTREAM_MAPPING,        "Downstream Mapping" },
326     { TLV_PAD,                       "Pad" },
327     { TLV_ERROR_CODE,                "Error Code" },
328     { TLV_VENDOR_CODE,               "Vendor Enterprise Code" },
329     { TLV_TBD,                       "TDB" },
330     { TLV_ILSO_IPv4,                 "IPv4 Interface and Label Stack Object" },
331     { TLV_ILSO_IPv6,                 "IPv6 Interface and Label Stack Object" },
332     { TLV_ERRORED_TLV,               "Errored TLVs" },
333     { TLV_REPLY_TOS,                 "Reply TOS Byte" },
334 #if 0
335     { TLV_RTO_IPv4,                  "IPv4 Reply-to Object" },
336     { TLV_RTO_IPv6,                  "IPv6 Reply-to Object" },
337 #endif
338     { TLV_P2MP_RESPONDER_IDENT,      "P2MP Responder Identifier" },
339     { TLV_P2MP_ECHO_JITTER,          "P2MP Echo Jitter" },
340     { TLV_SRC_IDENTIFIER,            "Source Identifier TLV" },
341     { TLV_DST_IDENTIFIER,            "Destination Identifier TLV" },
342     { TLV_BFD_DISCRIMINATOR,         "BFD Discriminator TLV" },
343     { TLV_REVERSE_PATH_FEC_STACK,    "Reverse-path Target FEC Stack" },
344     { TLV_DETAILED_DOWNSTREAM,       "Detailed Downstream Mapping"},
345     { TLV_VENDOR_PRIVATE_START,      "Vendor Private" },
346     { 0, NULL}
347 };
348 static value_string_ext mpls_echo_tlv_type_names_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_type_names);
349 
350 /*As per RFC 4379, https://tools.ietf.org/html/rfc4379 Section: 3.2 */
351 #define TLV_FEC_STACK_LDP_IPv4              1
352 #define TLV_FEC_STACK_LDP_IPv6              2
353 #define TLV_FEC_STACK_RSVP_IPv4             3
354 #define TLV_FEC_STACK_RSVP_IPv6             4
355 #define TLV_FEC_STACK_RES                   5
356 #define TLV_FEC_STACK_VPN_IPv4              6
357 #define TLV_FEC_STACK_VPN_IPv6              7
358 #define TLV_FEC_STACK_L2_VPN                8
359 #define TLV_FEC_STACK_L2_CID_OLD            9
360 #define TLV_FEC_STACK_L2_CID_NEW           10
361 #define TLV_FEC_STACK_L2_FEC_129           11
362 #define TLV_FEC_STACK_BGP_LAB_v4           12
363 #define TLV_FEC_STACK_BGP_LAB_v6           13
364 #define TLV_FEC_STACK_GEN_IPv4             14
365 #define TLV_FEC_STACK_GEN_IPv6             15
366 #define TLV_FEC_STACK_NIL                  16
367 /*As per RFC 6425, https://tools.ietf.org/html/rfc6425 Section: 3.1 */
368 #define TLV_FEC_STACK_P2MP_IPv4            17
369 #define TLV_FEC_STACK_P2MP_IPv6            18
370 /*As per RFC 6426, https://tools.ietf.org/html/rfc6426 Section: 2.3 */
371 #define TLV_FEC_STACK_STATIC_LSP           22
372 #define TLV_FEC_STACK_STATIC_PW            23
373 /*As per RFC 8029, https://tools.ietf.org/html/rfc8029 Section 3.2 */
374 #define TLV_FEC_STACK_PW_IPv6_FEC_128      24
375 #define TLV_FEC_STACK_PW_IPv6_FEC_129      25
376 #define TLV_FEC_VENDOR_PRIVATE_START   0xFC00
377 #define TLV_FEC_VENDOR_PRIVATE_END     0xFFFF
378 /*As per RFC 8287, https://tools.ietf.org/html/rfc8287 Section: 9.1 */
379 #define TLV_FEC_STACK_SR_IGP_IPv4          34
380 #define TLV_FEC_STACK_SR_IGP_IPv6          35
381 #define TLV_FEC_STACK_SR_IGP_ADJ           36
382 
383 /* FEC sub-TLV Type names */
384 static const value_string mpls_echo_tlv_fec_names[] = {
385     { TLV_FEC_STACK_LDP_IPv4,       "LDP IPv4 prefix"},
386     { TLV_FEC_STACK_LDP_IPv6,       "LDP IPv6 prefix"},
387     { TLV_FEC_STACK_RSVP_IPv4,      "RSVP IPv4 Session Query"},
388     { TLV_FEC_STACK_RSVP_IPv6,      "RSVP IPv6 Session Query"},
389     { TLV_FEC_STACK_RES,            "Reserved"},
390     { TLV_FEC_STACK_VPN_IPv4,       "VPN IPv4 prefix"},
391     { TLV_FEC_STACK_VPN_IPv6,       "VPN IPv6 prefix"},
392     { TLV_FEC_STACK_L2_VPN,         "L2 VPN endpoint"},
393     { TLV_FEC_STACK_L2_CID_OLD,     "FEC 128 Pseudowire - IPv4 (Deprecated)"},
394     { TLV_FEC_STACK_L2_CID_NEW,     "FEC 128 Pseudowire - IPv4"},
395     { TLV_FEC_STACK_L2_FEC_129,     "FEC 129 Pseudowire - IPv4"},
396     { TLV_FEC_STACK_BGP_LAB_v4,     "BGP labeled IPv4 prefix"},
397     { TLV_FEC_STACK_BGP_LAB_v6,     "BGP labeled IPv6 prefix"},
398     { TLV_FEC_STACK_GEN_IPv4,       "Generic IPv4 prefix"},
399     { TLV_FEC_STACK_GEN_IPv6,       "Generic IPv6 prefix"},
400     { TLV_FEC_STACK_NIL,            "Nil FEC"},
401     { TLV_FEC_STACK_P2MP_IPv4,      "RSVP P2MP IPv4 Session Query"},
402     { TLV_FEC_STACK_P2MP_IPv6,      "RSVP P2MP IPv6 Session Query"},
403     { TLV_FEC_STACK_STATIC_LSP,     "Static LSP"},
404     { TLV_FEC_STACK_STATIC_PW,      "Static Pseudowire"},
405     { TLV_FEC_STACK_PW_IPv6_FEC_128,"FEC 128 Pseudowire - IPv6"},
406     { TLV_FEC_STACK_PW_IPv6_FEC_129,"FEC 129 Pseudowire - IPv6"},
407     { TLV_FEC_STACK_SR_IGP_IPv4,    "IPv4 IGP-Prefix Segment ID"},
408     { TLV_FEC_STACK_SR_IGP_IPv6,    "IPv6 IGP-Prefix Segment ID"},
409     { TLV_FEC_STACK_SR_IGP_ADJ,     "IGP-Adjacency Segment ID"},
410     { TLV_FEC_VENDOR_PRIVATE_START, "Vendor Private"},
411     { 0, NULL}
412 };
413 static value_string_ext mpls_echo_tlv_fec_names_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_fec_names);
414 
415 /* [RFC 6424] */
416 #define TLV_FEC_MULTIPATH_DATA     1
417 #define TLV_FEC_LABEL_STACK        2
418 #define TLV_FEC_STACK_CHANGE       3
419 
420 #if 0
421 static const value_string mpls_echo_subtlv_names[] = {
422     { TLV_FEC_MULTIPATH_DATA,    "Multipath data"},
423     { TLV_FEC_LABEL_STACK,       "Label stack"},
424     { TLV_FEC_STACK_CHANGE,      "FEC stack change"},
425     { 0, NULL}
426 };
427 #endif
428 
429 /* [RFC 6424] */
430 #define TLV_MULTIPATH_NO_MULTIPATH          0
431 #define TLV_MULTIPATH_IP_ADDRESS            2
432 #define TLV_MULTIPATH_IP_ADDRESS_RANGE      4
433 #define TLV_MULTIPATH_BIT_MASKED_IP         8
434 #define TLV_MULTIPATH_BIT_MASKED_LABEL_SET  9
435 
436 #if 0
437 static const value_string mpls_echo_multipathtlv_type[] = {
438     { TLV_MULTIPATH_NO_MULTIPATH,         "Empty (Multipath Length = 0)"},
439     { TLV_MULTIPATH_IP_ADDRESS,           "IP addresses"},
440     { TLV_MULTIPATH_IP_ADDRESS_RANGE,     "low/high address pairs"},
441     { TLV_MULTIPATH_BIT_MASKED_IP,        "IP address prefix and bit mask"},
442     { TLV_MULTIPATH_BIT_MASKED_LABEL_SET, "Label prefix and bit mask"},
443     { 0, NULL}
444 };
445 #endif
446 
447 /* [RFC 6424] */
448 #define SUB_TLV_FEC_PUSH     1
449 #define SUB_TLV_FEC_POP      2
450 
451 static const value_string mpls_echo_subtlv_op_types[] = {
452     { SUB_TLV_FEC_PUSH,    "Push"},
453     { SUB_TLV_FEC_POP,     "Pop"},
454     { 0, NULL}
455 };
456 
457 /* [RFC 6424] */
458 #define SUB_TLV_FEC_UNSPECIFIED     0
459 #define SUB_TLV_FEC_IPV4            1
460 #define SUB_TLV_FEC_IPV6            2
461 
462 static const value_string mpls_echo_subtlv_addr_types[] = {
463     { SUB_TLV_FEC_UNSPECIFIED,    "Unspecified"},
464     { SUB_TLV_FEC_IPV4,           "IPv4"},
465     { SUB_TLV_FEC_IPV6,           "IPv6"},
466     { 0, NULL}
467 };
468 
469 /* [RFC 8287] */
470 #define SUB_TLV_FEC_SR_PROTO_ANY     0
471 #define SUB_TLV_FEC_SR_PROTO_OSPF    1
472 #define SUB_TLV_FEC_SR_PROTO_ISIS    2
473 
474 static const value_string mpls_echo_subtlv_sr_protocol_types[] = {
475     { SUB_TLV_FEC_SR_PROTO_ANY,  "Any IGP protocol"},
476     { SUB_TLV_FEC_SR_PROTO_OSPF, "OSPF"},
477     { SUB_TLV_FEC_SR_PROTO_ISIS, "IS-IS"},
478     { 0, NULL}
479 };
480 
481 /* [RFC 8287] */
482 #define SUB_TLV_FEC_SR_IGP_ADJ_UNNUMBERED    0
483 #define SUB_TLV_FEC_SR_IGP_ADJ_PARALLEL      1
484 #define SUB_TLV_FEC_SR_IGP_ADJ_IPv4          4
485 #define SUB_TLV_FEC_SR_IGP_ADJ_IPv6          6
486 
487 static const value_string mpls_echo_subtlv_igp_adjacency_types[] = {
488     { SUB_TLV_FEC_SR_IGP_ADJ_UNNUMBERED, "Unnumbered Interface Adjacency"},
489     { SUB_TLV_FEC_SR_IGP_ADJ_PARALLEL,   "Parallel Adjacency"},
490     { SUB_TLV_FEC_SR_IGP_ADJ_IPv4,       "IPv4, Non-parallel Adjacency"},
491     { SUB_TLV_FEC_SR_IGP_ADJ_IPv6,       "IPv6, Non-parallel Adjacency"},
492     { 0, NULL}
493 };
494 
495 static const value_string mpls_echo_tlv_pad[] = {
496     { 1, "Drop Pad TLV from reply" },
497     { 2, "Copy Pad TLV to reply" },
498     { 0, NULL}
499 };
500 
501 /* [RFC 6425] */
502 #define TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR 1
503 #define TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR 2
504 #define TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR 3
505 #define TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR 4
506 static const value_string mpls_echo_tlv_responder_ident_sub_tlv_type[] = {
507     { TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR, "IPv4 Egress Address P2MP Responder Identifier"},
508     { TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR, "IPv6 Egress Address P2MP Responder Identifier"},
509     { TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR,   "IPv4 Node Address P2MP Responder Identifier"},
510     { TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR,   "IPv6 Node Address P2MP Responder Identifier"},
511     {0, NULL}
512 };
513 
514 #define TLV_ADDR_IPv4           1
515 #define TLV_ADDR_UNNUM_IPv4     2
516 #define TLV_ADDR_IPv6           3
517 #define TLV_ADDR_UNNUM_IPv6     4
518 /* As per RFC 6426, https://tools.ietf.org/html/rfc6426 Section: 2.1 */
519 #define TLV_ADDR_NONIP          5
520 
521 static const value_string mpls_echo_tlv_addr_type[] = {
522     {TLV_ADDR_IPv4,       "IPv4 Numbered"},
523     {TLV_ADDR_UNNUM_IPv4, "IPv4 Unnumbered"},
524     {TLV_ADDR_IPv6,       "IPv6 Numbered"},
525     {TLV_ADDR_UNNUM_IPv6, "IPv6 Unnumbered"},
526     {TLV_ADDR_NONIP,      "Non IP"},
527     {0, NULL}
528 };
529 
530 #define TLV_DS_MAP_HASH_NO_MP           0
531 #define TLV_DS_MAP_HASH_LABEL           1
532 #define TLV_DS_MAP_HASH_IP              2
533 #define TLV_DS_MAP_HASH_LABEL_RANGE     3
534 #define TLV_DS_MAP_HASH_IP_RANGE        4
535 #define TLV_DS_MAP_HASH_NO_LABEL        5
536 #define TLV_DS_MAP_HASH_ALL_IP          6
537 #define TLV_DS_MAP_HASH_NO_MATCH        7
538 #define TLV_DS_MAP_HASH_BITMASK_IP      8
539 #define TLV_DS_MAP_HASH_BITMASK_LABEL   9
540 
541 static const value_string mpls_echo_tlv_ds_map_hash_type[] = {
542     {TLV_DS_MAP_HASH_NO_MP,         "no multipath"},
543     {TLV_DS_MAP_HASH_LABEL,         "label"},
544     {TLV_DS_MAP_HASH_IP,            "IP address"},
545     {TLV_DS_MAP_HASH_LABEL_RANGE,   "label range"},
546     {TLV_DS_MAP_HASH_IP_RANGE,      "IP address range"},
547     {TLV_DS_MAP_HASH_NO_LABEL,      "no more labels"},
548     {TLV_DS_MAP_HASH_ALL_IP,        "All IP addresses"},
549     {TLV_DS_MAP_HASH_NO_MATCH,      "no match"},
550     {TLV_DS_MAP_HASH_BITMASK_IP,    "Bit-masked IPv4 address set"},
551     {TLV_DS_MAP_HASH_BITMASK_LABEL, "Bit-masked label set"},
552     {0, NULL}
553 };
554 static value_string_ext mpls_echo_tlv_ds_map_hash_type_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_ds_map_hash_type);
555 
556 static const value_string mpls_echo_tlv_ds_map_mp_proto[] = {
557     {0, "Unknown"},
558     {1, "Static"},
559     {2, "BGP"},
560     {3, "LDP"},
561     {4, "RSVP-TE"},
562     {5, "OSPF"},
563     {6, "IS-IS"},
564     {0, NULL}
565 };
566 
567 /*
568  * Dissector for FEC sub-TLVs
569  */
570 static void
dissect_mpls_echo_tlv_fec(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem)571 dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
572 {
573     proto_tree *ti, *tlv_fec_tree;
574     guint16     idx = 1, nil_idx = 1, type, saved_type;
575     int         length, nil_length, pad;
576     guint32     label, adj_offset, adj_type, adj_proto;
577     guint8      exp, bos, ttl;
578 
579     while (rem >= 4) { /* Type, Length */
580         type = tvb_get_ntohs(tvb, offset);
581         saved_type = type;
582         /* Check for Vendor Private sub-TLVs */
583         if (type >= TLV_FEC_VENDOR_PRIVATE_START) /* && <= TLV_FEC_VENDOR_PRIVATE_END always true */
584             type = TLV_FEC_VENDOR_PRIVATE_START;
585 
586         length = tvb_get_ntohs(tvb, offset + 2);
587 
588         ti = NULL;
589         tlv_fec_tree = NULL;
590 
591         if (tree) {
592             tlv_fec_tree = proto_tree_add_subtree_format(tree, tvb, offset, length + (4-(length%4)),
593                                      ett_mpls_echo_tlv_fec, NULL, "FEC Element %u: %s",
594                                      idx, val_to_str_ext(type, &mpls_echo_tlv_fec_names_ext,
595                                                          "Unknown FEC type (0x%04X)"));
596 
597             /* FEC sub-TLV Type and Length */
598             proto_tree_add_uint_format_value(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb,
599                                        offset, 2, saved_type, "%s (%u)",
600                                        val_to_str_ext_const(type, &mpls_echo_tlv_fec_names_ext,
601                                                             "Unknown sub-TLV type"), saved_type);
602 
603             ti = proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_len, tvb, offset + 2,
604                                      2, ENC_BIG_ENDIAN);
605         }
606 
607         if (length + 4 > rem) {
608             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
609                                    "Invalid FEC Sub-TLV Length (claimed %u, found %u)",
610                                    length, rem - 4);
611             return;
612         }
613 
614         /* FEC sub-TLV Value */
615         switch (type) {
616         case TLV_FEC_STACK_LDP_IPv4:
617             if (tree) {
618                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4,
619                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
620                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
621                                     tvb, offset + 8, 1, ENC_BIG_ENDIAN);
622             }
623             break;
624         case TLV_FEC_STACK_LDP_IPv6:
625             if (tree) {
626                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6,
627                                     tvb, offset + 4, 16, ENC_NA);
628                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
629                                     tvb, offset + 20, 1, ENC_BIG_ENDIAN);
630             }
631             break;
632         case TLV_FEC_STACK_RSVP_IPv4:
633             if (length != 20) {
634                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
635                                        "Invalid FEC Sub-TLV Length "
636                                        "(claimed %u, should be %u)",
637                                        length, 20);
638                 return;
639             }
640             if (tree) {
641                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
642                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
643                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
644                                     tvb, offset + 8, 2, ENC_BIG_ENDIAN);
645                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
646                                     tvb, offset + 10, 2, ENC_BIG_ENDIAN);
647                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
648                                                   tvb, offset + 12, 4, ENC_BIG_ENDIAN);
649                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
650                                     tvb, offset + 16, 4, ENC_BIG_ENDIAN);
651                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
652                                     tvb, offset + 20, 2, ENC_BIG_ENDIAN);
653                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
654                                     tvb, offset + 22, 2, ENC_BIG_ENDIAN);
655             }
656             break;
657         case TLV_FEC_STACK_RSVP_IPv6:
658             if (length != 56) {
659                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
660                                        "Invalid FEC Sub-TLV Length "
661                                        "(claimed %u, should be %u)",
662                                        length, 56);
663                 return;
664             }
665             if (tree) {
666                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
667                                     tvb, offset + 4, 16, ENC_NA);
668                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
669                                     tvb, offset + 20, 2, ENC_BIG_ENDIAN);
670                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
671                                     tvb, offset + 22, 2, ENC_BIG_ENDIAN);
672                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
673                                                   tvb, offset + 24, 16, ENC_NA);
674                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
675                                     tvb, offset + 40, 16, ENC_NA);
676                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
677                                     tvb, offset + 56, 2, ENC_BIG_ENDIAN);
678                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
679                                     tvb, offset + 58, 2, ENC_BIG_ENDIAN);
680             }
681             break;
682         case TLV_FEC_STACK_VPN_IPv4:
683             if (tree) {
684                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_route_dist,
685                                     tvb, offset + 4, 8, ENC_NA);
686                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_ipv4,
687                                     tvb, offset + 12, 4, ENC_BIG_ENDIAN);
688                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_len,
689                                     tvb, offset + 16, 1, ENC_BIG_ENDIAN);
690             }
691             break;
692         case TLV_FEC_STACK_VPN_IPv6:
693             if (tree) {
694                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_route_dist,
695                                     tvb, offset + 4, 8, ENC_NA);
696                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_ipv6,
697                                     tvb, offset + 12, 16, ENC_NA);
698                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_len,
699                                     tvb, offset + 28, 1, ENC_BIG_ENDIAN);
700             }
701             break;
702         case TLV_FEC_STACK_L2_VPN:
703             if (tree) {
704                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_route_dist,
705                                     tvb, offset + 4, 8, ENC_NA);
706                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id,
707                                     tvb, offset + 12, 2, ENC_BIG_ENDIAN);
708                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id,
709                                     tvb, offset + 14, 2, ENC_BIG_ENDIAN);
710                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_encap_type,
711                                     tvb, offset + 16, 2, ENC_BIG_ENDIAN);
712             }
713             break;
714         case TLV_FEC_STACK_L2_CID_OLD:
715             if (tree) {
716                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
717                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
718                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
719                                     tvb, offset + 8, 4, ENC_BIG_ENDIAN);
720                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
721                                     tvb, offset + 12, 2, ENC_BIG_ENDIAN);
722                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
723                                     tvb, offset + 14, 2, ENC_BIG_ENDIAN);
724             }
725             break;
726         case TLV_FEC_STACK_L2_CID_NEW:
727             if (length < 14) {
728                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
729                                        "Invalid FEC Sub-TLV Length "
730                                        "(claimed %u, should be %u)",
731                                        length, 14);
732                 return;
733             }
734             if (tree) {
735                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_sender,
736                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
737                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
738                                     tvb, offset + 8, 4, ENC_BIG_ENDIAN);
739                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
740                                     tvb, offset + 12, 4, ENC_BIG_ENDIAN);
741                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
742                                     tvb, offset + 16, 2, ENC_BIG_ENDIAN);
743                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
744                                     tvb, offset + 18, 2, ENC_BIG_ENDIAN);
745             }
746             break;
747         case TLV_FEC_VENDOR_PRIVATE_START:
748             if (length < 4) { /* SMI Enterprise code */
749                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
750                                        "Invalid FEC Sub-TLV Length "
751                                        "(claimed %u, should be >= %u)",
752                                        length, 4);
753             } else {
754                 if (tree) {
755                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_vendor, tvb,
756                                         offset + 4, 4, ENC_BIG_ENDIAN);
757                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_value, tvb,
758                                         offset + 8, length - 4, ENC_NA);
759                 }
760             }
761             break;
762         case TLV_FEC_STACK_BGP_LAB_v4:
763             if (tree) {
764                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv4,
765                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
766                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
767                                     tvb, offset + 8, 1, ENC_BIG_ENDIAN);
768             }
769             break;
770         case TLV_FEC_STACK_BGP_LAB_v6:
771             if (tree) {
772                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv6,
773                                     tvb, offset + 4, 16, ENC_NA);
774                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
775                                     tvb, offset + 20, 1, ENC_BIG_ENDIAN);
776             }
777             break;
778         case TLV_FEC_STACK_GEN_IPv4:
779             if (tree) {
780                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4,
781                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
782                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4_mask,
783                                     tvb, offset + 8, 1, ENC_BIG_ENDIAN);
784             }
785             break;
786         case TLV_FEC_STACK_GEN_IPv6:
787             if (tree) {
788                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6,
789                                     tvb, offset + 4, 16, ENC_NA);
790                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6_mask,
791                                     tvb, offset + 20, 1, ENC_BIG_ENDIAN);
792             }
793             break;
794         case TLV_FEC_STACK_PW_IPv6_FEC_128:
795             if (length != 38) {
796                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
797                                        "Invalid FEC Sub-TLV Length "
798                                        "(claimed %u, should be %u)",
799                                        length, 38);
800                 return;
801             }
802             if (tree) {
803                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_pw_ipv6_128_sender,
804                                     tvb, offset + 4, 16, ENC_NA);
805                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_pw_ipv6_128_remote,
806                                     tvb, offset + 20, 16, ENC_NA);
807                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_id,
808                                     tvb, offset + 36, 2, ENC_BIG_ENDIAN);
809                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_type,
810                                     tvb, offset + 38, 2, ENC_BIG_ENDIAN);
811                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_pw_ipv6_128_mbz,
812                                     tvb, offset + 40, 2, ENC_BIG_ENDIAN);
813             }
814             break;
815         case TLV_FEC_STACK_NIL:
816                 nil_length = length;
817                 while (nil_length >= 4) {
818                     decode_mpls_label(tvb, offset + 4, &label, &exp, &bos, &ttl);
819                     if (label <= MPLS_LABEL_MAX_RESERVED) {
820                         proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
821                                                    tvb, offset + 4, 3, label, "Label %u: %u (%s)", nil_idx, label,
822                                                    val_to_str_const(label, special_labels, "Reserved - Unknown"));
823                     } else {
824                         proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
825                                                    tvb, offset + 4, 3, label, "Label %u: %u", nil_idx, label);
826                     }
827                     nil_length -= 4;
828                     offset     += 4;
829                     nil_idx++;
830                 }
831             break;
832         case TLV_FEC_STACK_P2MP_IPv4:
833             if (length != 20) {
834                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
835                                        "Invalid FEC Sub-TLV Length "
836                                        "(claimed %u, should be %u)",
837                                        length, 20);
838                 return;
839             }
840             if (tree) {
841                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id,
842                                     tvb, offset + 4, 4, ENC_BIG_ENDIAN);
843                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
844                                     tvb, offset + 8, 2, ENC_BIG_ENDIAN);
845                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
846                                     tvb, offset + 10, 2, ENC_BIG_ENDIAN);
847                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id,
848                                                   tvb, offset + 12, 4, ENC_BIG_ENDIAN);
849                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender,
850                                     tvb, offset + 16, 4, ENC_BIG_ENDIAN);
851                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2,
852                                     tvb, offset + 20, 2, ENC_BIG_ENDIAN);
853                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
854                                     tvb, offset + 22, 2, ENC_BIG_ENDIAN);
855             }
856             break;
857 
858         case TLV_FEC_STACK_P2MP_IPv6:
859             if (length != 56) {
860                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
861                                        "Invalid FEC Sub-TLV Length "
862                                        "(claimed %u, should be %u)",
863                                        length, 56);
864                 return;
865             }
866             if (tree) {
867                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id,
868                                     tvb, offset + 4, 16, ENC_NA);
869                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
870                                     tvb, offset + 20, 2, ENC_BIG_ENDIAN);
871                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
872                                     tvb, offset + 22, 2, ENC_BIG_ENDIAN);
873                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id,
874                                                   tvb, offset + 24, 16, ENC_NA);
875                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender,
876                                     tvb, offset + 40, 16, ENC_NA);
877                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
878                                     tvb, offset + 56, 2, ENC_BIG_ENDIAN);
879                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
880                                     tvb, offset + 58, 2, ENC_BIG_ENDIAN);
881             }
882             break;
883         case TLV_FEC_STACK_STATIC_LSP:
884             if (tree) {
885                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_gid,
886                                     tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
887                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_nid,
888                                     tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
889                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_tunnel_no,
890                                     tvb, (offset + 12), 2, ENC_BIG_ENDIAN);
891                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_lsp_no,
892                                     tvb, (offset + 14), 2, ENC_BIG_ENDIAN);
893                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_gid,
894                                     tvb, (offset + 16), 4, ENC_BIG_ENDIAN);
895                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_nid,
896                                     tvb, (offset + 20), 4, ENC_BIG_ENDIAN);
897                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_tunnel_no,
898                                     tvb, (offset + 24), 2, ENC_BIG_ENDIAN);
899                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_resv,
900                                     tvb, (offset + 26), 2, ENC_BIG_ENDIAN);
901             }
902             break;
903         case TLV_FEC_STACK_STATIC_PW:
904             if (tree) {
905                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_serv_identifier,
906                                     tvb, (offset + 4), 8, ENC_BIG_ENDIAN);
907                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_gid,
908                                     tvb, (offset + 12), 4, ENC_BIG_ENDIAN);
909                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_nid,
910                                     tvb, (offset + 16), 4, ENC_BIG_ENDIAN);
911                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_src_ac_id,
912                                     tvb, (offset + 20), 4, ENC_BIG_ENDIAN);
913                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_gid,
914                                     tvb, (offset + 24), 4, ENC_BIG_ENDIAN);
915                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_nid,
916                                     tvb, (offset + 28), 4, ENC_BIG_ENDIAN);
917                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_dst_ac_id,
918                                     tvb, (offset + 32), 4, ENC_BIG_ENDIAN);
919             }
920             break;
921         case TLV_FEC_STACK_SR_IGP_IPv4:
922             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_ipv4,
923                                 tvb, offset + 4, 4, ENC_NA);
924             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_mask,
925                                 tvb, offset + 8, 1, ENC_BIG_ENDIAN);
926             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_protocol,
927                                 tvb, offset + 9, 1, ENC_BIG_ENDIAN);
928             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_reserved,
929                                 tvb, offset + 10, 2, ENC_NA);
930             break;
931         case TLV_FEC_STACK_SR_IGP_IPv6:
932             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_ipv6,
933                                 tvb, offset + 4, 16, ENC_NA);
934             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_mask,
935                                 tvb, offset + 20, 1, ENC_BIG_ENDIAN);
936             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_protocol,
937                                 tvb, offset + 21, 1, ENC_BIG_ENDIAN);
938             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_reserved,
939                                 tvb, offset + 22, 2, ENC_NA);
940             break;
941         case TLV_FEC_STACK_SR_IGP_ADJ:
942             adj_offset = offset +4;
943             proto_tree_add_item_ret_uint(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_type,
944                                 tvb, adj_offset, 1, ENC_BIG_ENDIAN, &adj_type);
945             adj_offset += 1;
946             proto_tree_add_item_ret_uint(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_protocol,
947                                 tvb, adj_offset, 1, ENC_BIG_ENDIAN, &adj_proto);
948             adj_offset += 1;
949             proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_reserved,
950                                 tvb, adj_offset, 2, ENC_NA);
951             adj_offset += 2;
952             switch(adj_type) {
953                 case SUB_TLV_FEC_SR_IGP_ADJ_IPv4:
954                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_local_ipv4,
955                                         tvb, adj_offset, 4, ENC_NA);
956                     adj_offset += 4;
957                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_remote_ipv4,
958                                         tvb, adj_offset, 4, ENC_NA);
959                     adj_offset += 4;
960                     break;
961                 case SUB_TLV_FEC_SR_IGP_ADJ_IPv6:
962                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_local_ipv6,
963                                         tvb, adj_offset, 16, ENC_NA);
964                     adj_offset += 16;
965                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_remote_ipv6,
966                                         tvb, adj_offset, 16, ENC_NA);
967                     adj_offset += 16;
968                     break;
969                 case SUB_TLV_FEC_SR_IGP_ADJ_UNNUMBERED:
970                 case SUB_TLV_FEC_SR_IGP_ADJ_PARALLEL:
971                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_local_ident,
972                                         tvb, adj_offset, 4, ENC_NA);
973                     adj_offset += 4;
974                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_remote_ident,
975                                         tvb, adj_offset, 4, ENC_NA);
976                     adj_offset += 4;
977                     break;
978             }
979             switch(adj_proto) {
980                 case SUB_TLV_FEC_SR_PROTO_OSPF:
981                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_adv_ident_ospf,
982                                         tvb, adj_offset, 4, ENC_NA);
983                     adj_offset += 4;
984                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_rec_ident_ospf,
985                                         tvb, adj_offset, 4, ENC_NA);
986                     break;
987                 case SUB_TLV_FEC_SR_PROTO_ISIS:
988                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_adv_ident_isis,
989                                         tvb, adj_offset, 6, ENC_NA);
990                     adj_offset += 6;
991                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_rec_ident_isis,
992                                         tvb, adj_offset, 6, ENC_NA);
993                     break;
994                 case SUB_TLV_FEC_SR_PROTO_ANY:
995                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_adv_ident,
996                                         tvb, adj_offset, 4, ENC_NA);
997                     adj_offset += 4;
998                     proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_igp_adj_rec_ident,
999                                         tvb, adj_offset, 4, ENC_NA);
1000                     break;
1001             }
1002             break;
1003         case TLV_FEC_STACK_RES:
1004         default:
1005             if (length)
1006                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value,
1007                                         tvb, offset + 4, length, ENC_NA);
1008             break;
1009         }
1010 
1011         /*
1012          * Check for padding based on sub-TLV length alignment;
1013          * FEC sub-TLVs is zero-padded to align to four-octet boundary.
1014          */
1015         if (length  % 4) {
1016             pad = 4 - (length % 4);
1017             if (length + 4 + pad > rem) {
1018                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
1019                                        "Invalid FEC Sub-TLV Padded Length (claimed %u, found %u)",
1020                                        length + pad, rem - 4);
1021                 return;
1022             } else {
1023                 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_padding, tvb, offset + 4 + length, pad, ENC_NA);
1024             }
1025             length += pad;
1026         }
1027 
1028         rem    -= 4 + length;
1029         offset += 4 + length;
1030         idx++;
1031     }
1032 }
1033 
1034 
1035 /*
1036  * Dissector for Downstream Mapping TLV
1037  */
1038 static void
dissect_mpls_echo_tlv_ds_map(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem)1039 dissect_mpls_echo_tlv_ds_map(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
1040 {
1041     proto_tree *ti, *tlv_ds_map_tree;
1042     proto_tree *addr_ti;
1043     guint16     mplen, idx = 1;
1044     guint32     label;
1045     guint8      exp, bos, proto;
1046     guint8      hash_type, addr_type;
1047 
1048     proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mtu, tvb,
1049                         offset, 2, ENC_BIG_ENDIAN);
1050     addr_ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_addr_type, tvb,
1051                         offset + 2, 1, ENC_BIG_ENDIAN);
1052     ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_res, tvb,
1053                              offset + 3, 1, ENC_BIG_ENDIAN);
1054     tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
1055 
1056     proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_res, tvb,
1057                         offset + 3, 1, ENC_BIG_ENDIAN);
1058     proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_i, tvb,
1059                         offset + 3, 1, ENC_BIG_ENDIAN);
1060     proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_n, tvb,
1061                         offset + 3, 1, ENC_BIG_ENDIAN);
1062 
1063     addr_type = tvb_get_guint8(tvb, offset + 2);
1064     switch (addr_type) {
1065     case TLV_ADDR_IPv4:
1066         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
1067                             offset + 4, 4, ENC_BIG_ENDIAN);
1068         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ip, tvb,
1069                             offset + 8, 4, ENC_BIG_ENDIAN);
1070         break;
1071     case TLV_ADDR_UNNUM_IPv4:
1072     case TLV_ADDR_UNNUM_IPv6:
1073         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
1074                             offset + 4, 4, ENC_BIG_ENDIAN);
1075         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_if_index, tvb,
1076                             offset + 8, 4, ENC_BIG_ENDIAN);
1077         break;
1078     case TLV_ADDR_IPv6:
1079         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ipv6, tvb,
1080                             offset + 4, 16, ENC_NA);
1081         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ipv6, tvb,
1082                             offset + 20, 16, ENC_NA);
1083         rem    -= 24;
1084         offset += 24;
1085         break;
1086     case TLV_ADDR_NONIP :
1087         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ingress_if_num, tvb,
1088                              (offset + 4), 4, ENC_BIG_ENDIAN);
1089         proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_egress_if_num, tvb,
1090                              (offset + 8), 4, ENC_BIG_ENDIAN);
1091         break;
1092     default:
1093         expert_add_info_format(pinfo, addr_ti, &ei_mpls_echo_unknown_address_type,
1094                                "Unknown Address Type (%u)", addr_type);
1095         break;
1096     }
1097     proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_hash_type, tvb,
1098                         offset + 12, 1, ENC_BIG_ENDIAN);
1099     proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_depth, tvb,
1100                         offset + 13, 1, ENC_BIG_ENDIAN);
1101     ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_muti_len, tvb,
1102                         offset + 14, 2, ENC_BIG_ENDIAN);
1103 
1104     /* Get the Multipath Length and Hash Type */
1105     mplen     = tvb_get_ntohs(tvb, offset + 14);
1106     hash_type = tvb_get_guint8(tvb, offset + 12);
1107 
1108     rem    -= 16;
1109     offset += 16;
1110     if (rem < mplen) {
1111         expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
1112                                "Invalid FEC Multipath (claimed %u, found %u)",
1113                                 mplen, rem);
1114         return;
1115     }
1116     rem -= mplen;
1117     if (mplen) {
1118         switch (hash_type) {
1119         case TLV_DS_MAP_HASH_IP:
1120             if (mplen != 4) {
1121                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
1122                                        "Invalid FEC Multipath (claimed %u, should be 4)",
1123                                        mplen);
1124                 break;
1125             }
1126             tlv_ds_map_tree = proto_tree_add_subtree(tree, tvb, offset, 4,
1127                                      ett_mpls_echo_tlv_ds_map, NULL, "Multipath Information");
1128             proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
1129                                 offset, 4, ENC_BIG_ENDIAN);
1130             break;
1131         case TLV_DS_MAP_HASH_IP_RANGE:
1132             if (mplen != 8) {
1133                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
1134                                        "Invalid FEC Multipath (claimed %u, should be 8)",
1135                                        mplen);
1136                 break;
1137             }
1138             tlv_ds_map_tree = proto_tree_add_subtree(tree, tvb, offset, 8,
1139                                      ett_mpls_echo_tlv_ds_map, NULL, "Multipath Information");
1140             proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_low, tvb,
1141                                 offset, 4, ENC_BIG_ENDIAN);
1142             proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_high, tvb,
1143                                 offset + 4, 4, ENC_BIG_ENDIAN);
1144             break;
1145         case TLV_DS_MAP_HASH_NO_MP:
1146         case TLV_DS_MAP_HASH_NO_LABEL:
1147         case TLV_DS_MAP_HASH_ALL_IP:
1148         case TLV_DS_MAP_HASH_NO_MATCH:
1149             proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mp_no_multipath_info, tvb, offset, mplen, ENC_NA);
1150             break;
1151         case TLV_DS_MAP_HASH_BITMASK_IP:
1152             if (mplen < 4) {
1153                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
1154                                        "Invalid FEC Multipath (claimed %u, should be 4)",
1155                                        mplen);
1156                 break;
1157             }
1158             tlv_ds_map_tree = proto_tree_add_subtree(tree, tvb, offset, mplen,
1159                                      ett_mpls_echo_tlv_ds_map, NULL, "Multipath Information");
1160             proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
1161                                 offset, 4, ENC_BIG_ENDIAN);
1162             if (mplen > 4)
1163                 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_mask, tvb,
1164                                     offset + 4, mplen - 4, ENC_NA);
1165             break;
1166         default:
1167             proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mp_value, tvb,
1168                                 offset, mplen, ENC_NA);
1169             break;
1170         }
1171     }
1172 
1173     offset += mplen;
1174 
1175     if (tree) {
1176         while (rem >= 4) {
1177             decode_mpls_label(tvb, offset, &label, &exp, &bos, &proto);
1178             tlv_ds_map_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
1179                     ett_mpls_echo_tlv_ds_map, &ti, "Downstream Label Element %u", idx);
1180             proto_item_append_text(ti, ", Label: %u", label);
1181             if (label <= MPLS_LABEL_MAX_RESERVED) {
1182                 proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
1183                                            tvb, offset, 3, label);
1184                 proto_item_append_text(ti, " (%s)", val_to_str_const(label, special_labels,
1185                                                                      "Reserved - Unknown"));
1186             } else {
1187                 proto_tree_add_uint_format_value(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
1188                                            tvb, offset, 3, label, "%u", label);
1189             }
1190             proto_item_append_text(ti, ", Exp: %u, BOS: %u", exp, bos);
1191             proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_exp,
1192                                        tvb, offset + 2, 1, exp);
1193             proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_bos,
1194                                        tvb, offset + 2, 1, bos);
1195             proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_proto,
1196                                 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1197             proto_item_append_text(ti, ", Protocol: %u (%s)", proto,
1198                                    val_to_str_const(proto, mpls_echo_tlv_ds_map_mp_proto, "Unknown"));
1199             rem    -= 4;
1200             offset += 4;
1201             idx++;
1202         }
1203     }
1204 }
1205 
1206 /* Dissector for Detailed Downstream Mapping TLV - RFC [6424] */
1207 static void
dissect_mpls_echo_tlv_dd_map(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem)1208 dissect_mpls_echo_tlv_dd_map(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
1209 {
1210     proto_tree *ddti = NULL, *tlv_dd_map_tree, *tlv_ddstlv_map_tree;
1211     proto_tree *ddsti, *ddsti2;
1212     guint16     subtlv_length, subtlv_type, multipath_length;
1213     guint8      addr_type, multipath_type, fec_tlv_length;
1214     guint16     idx = 1;
1215     guint32     label;
1216     guint8      tc, s_bit, proto;
1217 
1218     if (tree) {
1219         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_mtu, tvb,
1220                             offset, 2, ENC_BIG_ENDIAN);
1221         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_addr_type, tvb,
1222                             offset + 2, 1, ENC_BIG_ENDIAN);
1223         ddti = proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_res, tvb,
1224                                    offset + 3, 1, ENC_BIG_ENDIAN);
1225         tlv_dd_map_tree = proto_item_add_subtree(ddti, ett_mpls_echo_tlv_dd_map);
1226 
1227         proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_res, tvb,
1228                             offset + 3, 1, ENC_BIG_ENDIAN);
1229         proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_i, tvb,
1230                             offset + 3, 1, ENC_BIG_ENDIAN);
1231         ddti = proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_n, tvb,
1232                                    offset + 3, 1, ENC_BIG_ENDIAN);
1233     }
1234     addr_type = tvb_get_guint8(tvb, offset + 2);
1235     switch (addr_type) {
1236     case TLV_ADDR_IPv4:
1237         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_ds_ip, tvb,
1238                             offset + 4, 4, ENC_BIG_ENDIAN);
1239         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_int_ip, tvb,
1240                             offset + 8, 4, ENC_BIG_ENDIAN);
1241         break;
1242     case TLV_ADDR_IPv6:
1243         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_ds_ipv6, tvb,
1244                             offset + 4, 16, ENC_NA);
1245         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_int_ipv6, tvb,
1246                             offset + 20, 16, ENC_NA);
1247         rem    -= 24;
1248         offset += 24;
1249         break;
1250     case TLV_ADDR_NONIP :
1251         proto_tree_add_item (tree, hf_mpls_echo_tlv_dd_map_ingress_if_num, tvb,
1252                              (offset + 4), 4, ENC_BIG_ENDIAN);
1253         proto_tree_add_item (tree, hf_mpls_echo_tlv_dd_map_egress_if_num, tvb,
1254                              (offset + 8), 4, ENC_BIG_ENDIAN);
1255         break;
1256     default:
1257         expert_add_info_format(pinfo, ddti, &ei_mpls_echo_unknown_address_type,
1258                                "Unknown Address Type (%u)", addr_type);
1259         break;
1260     }
1261 
1262     if (tree) {
1263         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_return_code, tvb,
1264                             offset + 12, 1, ENC_BIG_ENDIAN);
1265         proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_return_subcode, tvb,
1266                             offset + 13, 1, ENC_BIG_ENDIAN);
1267         ddti = proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_subtlv_len, tvb,
1268                                    offset + 14, 2, ENC_BIG_ENDIAN);
1269     }
1270 
1271     rem    -= 16;
1272     offset += 16;
1273 
1274     while (rem > 4) {
1275        /* Get the Sub-tlv Type and Length */
1276        subtlv_type   = tvb_get_ntohs(tvb, offset);
1277        subtlv_length = tvb_get_ntohs(tvb, offset+2);
1278        rem -= 4;
1279        offset += 4;
1280 
1281        if (rem<subtlv_length){
1282           expert_add_info_format(pinfo, ddti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1283                 "Invalid Sub-tlv Length (claimed %u, found %u)",
1284                 subtlv_length, rem);
1285           return;
1286        }
1287 
1288         switch (subtlv_type) {
1289         case TLV_FEC_MULTIPATH_DATA:
1290             multipath_type   = tvb_get_guint8(tvb, offset);
1291             multipath_length = tvb_get_ntohs(tvb, offset + 1);
1292             tlv_dd_map_tree = proto_tree_add_subtree(tree, tvb, offset - 4, multipath_length + 8,
1293                                         ett_mpls_echo_tlv_dd_map, &ddsti, "Multipath sub-TLV");
1294 
1295             switch (multipath_type) {
1296             case TLV_MULTIPATH_NO_MULTIPATH:
1297                 if (!tree)
1298                     break;
1299                 proto_tree_add_item(tlv_dd_map_tree,
1300                                     hf_mpls_echo_sub_tlv_multipath_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1301                 proto_tree_add_item(tlv_dd_map_tree,
1302                                     hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1303                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1304                                     offset + 3, 1, ENC_BIG_ENDIAN);
1305                 tlv_ddstlv_map_tree = proto_tree_add_subtree(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1306                                              ett_mpls_echo_tlv_ddstlv_map, NULL, "Empty (Multipath Length = 0)");
1307                 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_info,
1308                                     tvb, offset + 4, multipath_length, ENC_NA);
1309                 break;
1310 
1311             case TLV_MULTIPATH_IP_ADDRESS:
1312                 if (multipath_length != 4) {
1313                     expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1314                                "Invalid Sub-tlv Length (claimed %u, should be 4)",
1315                                multipath_length);
1316                     break;
1317                 }
1318                 if (!tree)
1319                     break;
1320                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1321                                     offset, 1, ENC_BIG_ENDIAN);
1322                 proto_tree_add_item(tlv_dd_map_tree,
1323                                     hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1324                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1325                                     offset + 3, 1, ENC_BIG_ENDIAN);
1326 
1327                 tlv_ddstlv_map_tree = proto_tree_add_subtree(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1328                                              ett_mpls_echo_tlv_ddstlv_map, NULL, "Multipath Information (IP addresses)");
1329 
1330                 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_ip, tvb,
1331                                     offset + 4, 4, ENC_BIG_ENDIAN);
1332                 break;
1333 
1334             case TLV_MULTIPATH_IP_ADDRESS_RANGE:
1335                 if (multipath_length != 8) {
1336                     expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1337                                "Invalid Sub-tlv Length (claimed %u, should be 8)",
1338                                multipath_length);
1339                     break;
1340                 }
1341                 if (!tree)
1342                     break;
1343                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1344                                     offset, 1, ENC_BIG_ENDIAN);
1345                 proto_tree_add_item(tlv_dd_map_tree,
1346                                     hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1347                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1348                                     offset + 3, 1, ENC_BIG_ENDIAN);
1349 
1350                 tlv_ddstlv_map_tree = proto_tree_add_subtree(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1351                                              ett_mpls_echo_tlv_ddstlv_map, NULL, "Multipath Information (low/high address pairs)");
1352 
1353                 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_ip_low, tvb,
1354                                     offset + 4, 4, ENC_BIG_ENDIAN);
1355                 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_ip_high, tvb,
1356                                     offset + 8, 4, ENC_BIG_ENDIAN);
1357                 break;
1358 
1359             case TLV_MULTIPATH_BIT_MASKED_IP:
1360                 if (multipath_length < 4) {
1361                     expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1362                                "Invalid Sub-tlv Length (claimed %u, should be >= 4)",
1363                                multipath_length);
1364                     break;
1365                 }
1366                 if (!tree)
1367                     break;
1368                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1369                                     offset, 1, ENC_BIG_ENDIAN);
1370                 proto_tree_add_item(tlv_dd_map_tree,
1371                                     hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1372                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1373                                     offset + 3, 1, ENC_BIG_ENDIAN);
1374 
1375                 tlv_ddstlv_map_tree = proto_tree_add_subtree(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1376                                              ett_mpls_echo_tlv_ddstlv_map, NULL, "Multipath Information (IP address prefix and bit mask)");
1377 
1378                 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_ip, tvb,
1379                                     offset + 4, 4, ENC_BIG_ENDIAN);
1380                 if (multipath_length > 4)
1381                     proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_mask,
1382                                         tvb, offset + 8, multipath_length - 4, ENC_NA);
1383                 break;
1384 
1385             case TLV_MULTIPATH_BIT_MASKED_LABEL_SET:
1386                 proto_tree_add_uint_format(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb, offset, 1, multipath_type,
1387                                             "Multipath Information (Label prefix and bit mask)");
1388                 break;
1389 
1390             default:
1391                 if (!tree)
1392                     break;
1393                 proto_tree_add_uint_format(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb, offset, 1, multipath_type,
1394                                             "Multipath Type not identified (%u)", multipath_type);
1395                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1396                                     offset, 1, ENC_BIG_ENDIAN);
1397                 proto_tree_add_item(tlv_dd_map_tree,
1398                                     hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1399                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_value, tvb,
1400                                     offset + 3, rem, ENC_NA);
1401                 break;
1402             }
1403 
1404             rem -= (multipath_length + 4);
1405             break;
1406 
1407         case TLV_FEC_LABEL_STACK:
1408             tlv_dd_map_tree = proto_tree_add_subtree(tree, tvb, offset - 4, subtlv_length + 4,
1409                                 ett_mpls_echo_tlv_dd_map, NULL, "Label stack sub-TLV");
1410 
1411             while (subtlv_length >= 4) {
1412                 if (tree) {
1413                     decode_mpls_label(tvb, offset, &label, &tc, &s_bit, &proto);
1414 
1415                     tlv_ddstlv_map_tree = proto_tree_add_subtree_format(tlv_dd_map_tree, tvb, offset, 4,
1416                                                  ett_mpls_echo_tlv_ddstlv_map, &ddsti2, "Downstream Label Element %u", idx);
1417                     proto_item_append_text(ddsti2, ", Label: %u , Protocol: %u", label, proto);
1418                     proto_tree_add_uint(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_label, tvb, offset, 3, label);
1419                     proto_tree_add_uint(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_traffic_class, tvb, offset + 2, 1, tc);
1420                     proto_tree_add_uint(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_s_bit, tvb, offset + 2, 1, s_bit);
1421                     proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_tlv_ddstlv_map_mp_proto,
1422                                         tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1423                 }
1424                 subtlv_length -= 4;
1425                 rem           -= 4;
1426                 offset        += 4;
1427                 idx++;
1428             }
1429             break;
1430 
1431         case TLV_FEC_STACK_CHANGE: {
1432             addr_type       = tvb_get_guint8(tvb, offset + 1);
1433             fec_tlv_length  = tvb_get_guint8(tvb, offset + 2);
1434             tlv_dd_map_tree = proto_tree_add_subtree(tree, tvb, offset - 4, fec_tlv_length + 12,
1435                                             ett_mpls_echo_tlv_dd_map, NULL, "Stack change sub-TLV");
1436 
1437             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_op_type,       tvb, offset,     1, ENC_BIG_ENDIAN);
1438             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_addr_type,     tvb, offset + 1, 1, ENC_BIG_ENDIAN);
1439             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_fec_tlv_value, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
1440             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_res,           tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1441             switch (addr_type) {
1442             case SUB_TLV_FEC_UNSPECIFIED:
1443                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_remote_peer_unspecified, tvb, offset + 4, 0, ENC_NA);
1444                 rem    += 4;
1445                 offset -= 4;
1446                 break;
1447             case SUB_TLV_FEC_IPV4:
1448                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_remote_peer_ip, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1449                 break;
1450             case SUB_TLV_FEC_IPV6:
1451                 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_remore_peer_ipv6, tvb, offset + 4, 16, ENC_NA);
1452                 rem    -= 12;
1453                 offset += 12;
1454                 break;
1455             }
1456 
1457             offset -= 8;
1458             dissect_mpls_echo_tlv_fec(tvb, pinfo, offset, tlv_dd_map_tree, fec_tlv_length);
1459 
1460             rem -= (fec_tlv_length + 8);
1461             break;
1462         }
1463 
1464         default:
1465             tlv_dd_map_tree = proto_tree_add_subtree(tree, tvb, offset, subtlv_length, ett_mpls_echo_tlv_dd_map, NULL, "Error processing sub-TLV");
1466             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_type,   tvb, offset - 4, 2, ENC_BIG_ENDIAN);
1467             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_length, tvb, offset - 2, 2, ENC_BIG_ENDIAN);
1468             proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_value,  tvb, offset, subtlv_length, ENC_NA);
1469             rem -= subtlv_length;
1470             break;
1471         }
1472     }
1473 }
1474 
1475 /*
1476  * Dissector for IPv4 and IPv6 Interface and Label Stack Object
1477  */
1478 static void
dissect_mpls_echo_tlv_ilso(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem,gboolean is_ipv6)1479 dissect_mpls_echo_tlv_ilso(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean is_ipv6)
1480 {
1481     proto_tree *ti;
1482     guint8      type;
1483     guint16     idx = 1;
1484     guint32     label;
1485     guint8      exp, bos, ttl;
1486 
1487     ti      = proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_addr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1488     type    = tvb_get_guint8(tvb, offset);
1489     offset += 1;
1490     rem    -= 1;
1491 
1492     proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_mbz, tvb, offset, 3, ENC_BIG_ENDIAN);
1493     offset += 3;
1494     rem    -= 3;
1495 
1496     if ((type == TLV_ADDR_IPv4) || (type == TLV_ADDR_UNNUM_IPv4)) {
1497         if (is_ipv6) {
1498             expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1499         }
1500         proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_addr, tvb,
1501                             offset, 4, ENC_BIG_ENDIAN);
1502         if (type == TLV_ADDR_IPv4) {
1503             proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_int_addr, tvb,
1504                                 offset + 4, 4, ENC_BIG_ENDIAN);
1505         } else {
1506             proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_int_index, tvb,
1507                                 offset + 4, 4, ENC_BIG_ENDIAN);
1508         }
1509         offset += 8;
1510         rem    -= 8;
1511     } else if ((type == TLV_ADDR_IPv6) || (type == TLV_ADDR_UNNUM_IPv6)) {
1512         if (!is_ipv6) {
1513             expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1514         }
1515 
1516         proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_addr, tvb,
1517                             offset, 16, ENC_NA);
1518         if (type == TLV_ADDR_IPv6) {
1519             proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_int_addr, tvb,
1520                                 offset + 16, 16, ENC_NA);
1521             offset += 32;
1522             rem    -= 32;
1523         } else {
1524             proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_int_index, tvb,
1525                                 offset + 16, 4, ENC_BIG_ENDIAN);
1526             offset += 20;
1527             rem    -= 20;
1528         }
1529     } else {
1530         expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1531         return;
1532     }
1533 
1534     if (tree) {
1535         while (rem >= 4) {
1536             proto_tree *tlv_ilso;
1537 
1538             decode_mpls_label(tvb, offset, &label, &exp, &bos, &ttl);
1539             tlv_ilso = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_mpls_echo_tlv_ilso, &ti, "Label Stack Element %u", idx);
1540             proto_item_append_text(ti, ", Label: %u", label);
1541             if (label <= MPLS_LABEL_MAX_RESERVED) {
1542                 proto_tree_add_uint_format_value(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
1543                                            tvb, offset, 3, label, "%u (%s)", label,
1544                                            val_to_str_const(label, special_labels, "Reserved - Unknown"));
1545                 proto_item_append_text(ti, " (%s)", val_to_str_const(label, special_labels,
1546                                                                      "Reserved - Unknown"));
1547             } else {
1548                 proto_tree_add_uint_format_value(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
1549                                            tvb, offset, 3, label, "%u", label);
1550             }
1551             proto_item_append_text(ti, ", Exp: %u, BOS: %u, TTL: %u",
1552                                    exp, bos, ttl);
1553             proto_tree_add_uint(tlv_ilso, hf_mpls_echo_tlv_ilso_exp,
1554                                        tvb, offset + 2, 1, exp);
1555             proto_tree_add_uint(tlv_ilso, hf_mpls_echo_tlv_ilso_bos,
1556                                        tvb, offset + 2, 1, bos);
1557             proto_tree_add_item(tlv_ilso, hf_mpls_echo_tlv_ilso_ttl,
1558                                 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1559             rem    -= 4;
1560             offset += 4;
1561             idx++;
1562         }
1563     }
1564 }
1565 
1566 static int
1567 dissect_mpls_echo_tlv(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean in_errored);
1568 
1569 /*
1570  * Dissector for Errored TLVs
1571  */
1572 static void
dissect_mpls_echo_tlv_errored(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem)1573 dissect_mpls_echo_tlv_errored(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
1574 {
1575     int errored_tlv_length;
1576 
1577     while (rem >= 4) {
1578         errored_tlv_length = dissect_mpls_echo_tlv(tvb, pinfo, offset, tree, rem, TRUE);
1579         rem    -= errored_tlv_length;
1580         offset += errored_tlv_length;
1581     }
1582 }
1583 
1584 /*
1585  * Dissector for MPLS Echo TLVs and return bytes consumed
1586  */
1587 static int
dissect_mpls_echo_tlv(tvbuff_t * tvb,packet_info * pinfo,guint offset,proto_tree * tree,int rem,gboolean in_errored)1588 dissect_mpls_echo_tlv(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean in_errored)
1589 {
1590     proto_tree *ti = NULL, *mpls_echo_tlv_tree = NULL;
1591     guint16     type, saved_type;
1592     int         length;
1593 
1594     length = tvb_reported_length_remaining(tvb, offset);
1595     rem    = MIN(rem, length);
1596 
1597     if ( rem < 4 ) { /* Type Length */
1598         proto_tree_add_expert_format(tree, pinfo, &ei_mpls_echo_tlv_len, tvb, offset, rem,
1599                                     "Error processing TLV: length is %d, should be >= 4", rem);
1600         return rem;
1601     }
1602 
1603     type    = tvb_get_ntohs(tvb, offset);
1604     length  = tvb_get_ntohs(tvb, offset + 2);
1605     rem    -= 4;                /* do not count Type Length */
1606     length  = MIN(length, rem);
1607 
1608     /* Check for Vendor Private TLVs */
1609     saved_type = type;
1610     if (type >= TLV_VENDOR_PRIVATE_START) /* && <= TLV_VENDOR_PRIVATE_END always true */
1611         type = TLV_VENDOR_PRIVATE_START;
1612 
1613     if (tree) {
1614         mpls_echo_tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, length + 4, ett_mpls_echo_tlv, NULL,
1615                                   "%s%s", in_errored ? "Errored TLV Type: " : "",
1616                                  val_to_str_ext(type, &mpls_echo_tlv_type_names_ext, "Unknown TLV type (0x%04X)"));
1617 
1618         /* MPLS Echo TLV Type and Length */
1619         if (in_errored) {
1620             proto_tree_add_uint_format_value(mpls_echo_tlv_tree, hf_mpls_echo_tlv_errored_type, tvb,
1621                                        offset, 2, saved_type, "%s (%u)",
1622                                        val_to_str_ext_const(type, &mpls_echo_tlv_type_names_ext,
1623                                                             "Unknown TLV type"), saved_type);
1624         } else {
1625             proto_tree_add_uint_format_value(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
1626                                        offset, 2, saved_type, "%s (%u)",
1627                                        val_to_str_ext_const(type, &mpls_echo_tlv_type_names_ext,
1628                                                             "Unknown TLV type"), saved_type);
1629         }
1630         ti = proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1631     }
1632 
1633     /* MPLS Echo TLV Value */
1634     if (length == 0)
1635         return 4; /* Empty TLV, return Type and Length consumed. */
1636 
1637     switch (type) {
1638     case TLV_TARGET_FEC_STACK:
1639         dissect_mpls_echo_tlv_fec(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1640         break;
1641     case TLV_PAD:
1642         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padaction, tvb,
1643                             offset + 4, 1, ENC_BIG_ENDIAN);
1644         if (length > 1)
1645             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
1646                                 offset + 5, length - 1, ENC_NA);
1647         break;
1648     case TLV_VENDOR_CODE:
1649         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
1650                             offset + 4, 4, ENC_BIG_ENDIAN);
1651         break;
1652     case TLV_ILSO_IPv4:
1653         if (length < 12) {
1654             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1655                                    "Invalid TLV Length (claimed %u, should be >= 12)",
1656                                    length);
1657             break;
1658         }
1659         dissect_mpls_echo_tlv_ilso(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length, FALSE);
1660         break;
1661     case TLV_ILSO_IPv6:
1662         if (length < 24) {
1663             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1664                                    "Invalid TLV Length (claimed %u, should be >= 24)",
1665                                    length);
1666             break;
1667         }
1668         dissect_mpls_echo_tlv_ilso(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length, TRUE);
1669         break;
1670 #if 0
1671     case TLV_RTO_IPv4:
1672         if (length != 4) {
1673             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1674                                    "Invalid TLV Length (claimed %u, should be 4)",
1675                                    length);
1676             break;
1677         }
1678         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv4,
1679                             tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1680         break;
1681     case TLV_RTO_IPv6:
1682         if (length != 16) {
1683             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1684                                    "Invalid TLV Length (claimed %u, should be 16)",
1685                                    length);
1686             break;
1687         }
1688         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv6,
1689                             tvb, offset + 4, 16, ENC_NA);
1690         break;
1691 #endif
1692     case TLV_P2MP_ECHO_JITTER:
1693         if (length != 4) {
1694             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1695                                    "Invalid TLV Length (claimed %u, should be 4)",
1696                                    length);
1697             break;
1698         }
1699         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_echo_jitter,
1700                             tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1701         break;
1702     case TLV_P2MP_RESPONDER_IDENT: {
1703         guint16     resp_ident_type, resp_ident_len;
1704         proto_item *hidden_item;
1705 
1706         resp_ident_type = tvb_get_ntohs(tvb, offset + 4);
1707         resp_ident_len  = tvb_get_ntohs(tvb, offset + 6);
1708         /* Check addr length */
1709         switch (resp_ident_type) {
1710         case TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR:
1711         case TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR:
1712             if (resp_ident_len != 4) {
1713                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1714                                        "Invalid TLV Length (claimed %u, should be 4)",
1715                                        length);
1716                 break;
1717             }
1718             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_type,
1719                                 tvb, offset + 4, 2, ENC_BIG_ENDIAN);
1720             hidden_item = proto_tree_add_item(mpls_echo_tlv_tree,
1721                                               hf_mpls_echo_tlv_responder_indent_len, tvb,
1722                                               offset + 6, 2, ENC_BIG_ENDIAN);
1723             proto_item_set_hidden(hidden_item);
1724             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_ipv4,
1725                                 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1726             break;
1727         case TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR:
1728         case TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR:
1729             if (resp_ident_len != 16) {
1730                 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1731                                        "Invalid TLV Length (claimed %u, should be 16)",
1732                                        length);
1733                 break;
1734             }
1735             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_type,
1736                                 tvb, offset + 4, 2, ENC_BIG_ENDIAN);
1737             hidden_item = proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_len,
1738                                               tvb, offset + 6, 2, ENC_BIG_ENDIAN);
1739             proto_item_set_hidden(hidden_item);
1740             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_ipv4,
1741                                 tvb, offset + 8, 16, ENC_BIG_ENDIAN);
1742             break;
1743         }
1744         break;
1745     }
1746     case TLV_VENDOR_PRIVATE_START:
1747         if (length < 4) { /* SMI Enterprise code */
1748             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1749                                    "Invalid TLV Length (claimed %u, should be >= 4)",
1750                                    length);
1751         } else {
1752             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
1753                                 offset + 4, 4, ENC_BIG_ENDIAN);
1754             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1755                                 offset + 8, length - 4, ENC_NA);
1756         }
1757         break;
1758     case TLV_DOWNSTREAM_MAPPING:
1759         if (length < 16) {
1760             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1761                                    "Invalid TLV Length (claimed %u, should be >= 16)",
1762                                    length);
1763             break;
1764         }
1765         dissect_mpls_echo_tlv_ds_map(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1766         break;
1767     case TLV_DETAILED_DOWNSTREAM:   /* [RFC 6424] */
1768         if (length < 16) {
1769             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1770                                    "Invalid TLV Length (claimed %u, should be >= 16)",
1771                                    length);
1772             break;
1773         }
1774         dissect_mpls_echo_tlv_dd_map(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1775         break;
1776     case TLV_ERRORED_TLV:
1777         if (in_errored)
1778             proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1779                                 offset + 4, length, ENC_NA);
1780         else
1781             dissect_mpls_echo_tlv_errored(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1782         break;
1783     case TLV_REPLY_TOS:
1784         if (length != 4) {
1785             expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1786                                    "Invalid TLV Length (claimed %u, should be 4)",
1787                                    length);
1788             break;
1789         }
1790         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos, tvb,
1791                             offset + 4, 1, ENC_BIG_ENDIAN);
1792         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos_mbz, tvb,
1793                             offset + 5, 3, ENC_BIG_ENDIAN);
1794         break;
1795     case TLV_SRC_IDENTIFIER:
1796         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_gid,
1797                             tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1798         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_nid,
1799                             tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
1800         break;
1801     case TLV_DST_IDENTIFIER:
1802         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_gid,
1803                             tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1804         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_nid,
1805                             tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
1806         break;
1807     case TLV_BFD_DISCRIMINATOR:
1808         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_bfd,
1809                             tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1810         break;
1811     case TLV_REVERSE_PATH_FEC_STACK:
1812         dissect_mpls_echo_tlv_fec (tvb, pinfo, (offset + 4), mpls_echo_tlv_tree, length);
1813         break ;
1814     case TLV_ERROR_CODE:
1815     default:
1816         proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1817                             offset + 4, length, ENC_NA);
1818         break;
1819     }
1820     return length + 4;  /* Length of the Value field + Type Length */
1821 }
1822 
1823 #define MSGTYPE_MPLS_ECHO(msgtype)      ((msgtype == 1) || (msgtype == 2))
1824 #define MSGTYPE_DATAPLANE(msgtype)      ((msgtype == 3) || (msgtype == 4))
1825 
1826 /*
1827  * Dissector for MPLS Echo (LSP PING) packets
1828  */
1829 static int
dissect_mpls_echo(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1830 dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1831 {
1832     int         offset = 0, rem = 0, len;
1833     proto_item *ti = NULL;
1834     proto_tree *mpls_echo_tree = NULL;
1835     guint8      msgtype;
1836 
1837     /* If version != 1 we assume it's not an mpls ping packet */
1838     if (tvb_captured_length(tvb) < 5) {
1839         return 0; /* Not enough information to tell version and message type. */
1840     }
1841     if (tvb_get_ntohs(tvb, 0) != 1) {
1842         return 0; /* Not version 1. */
1843     }
1844 
1845     /* Make entries in Protocol column and Info column on summary display */
1846     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPLS ECHO");
1847 
1848     /* Clear the info column so it's sane if we crash. We fill it in later when
1849      * we've dissected more of the packet. */
1850     col_clear(pinfo->cinfo, COL_INFO);
1851 
1852     rem = tvb_reported_length_remaining(tvb, offset);
1853 
1854     /* Get the message type and fill in the Column info */
1855     msgtype = tvb_get_guint8(tvb, offset + 4);
1856 
1857     /* The minimum fixed part of the packet is 16 Bytes or 32 Bytes depending on Msg Type */
1858     if ( ((!MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 16)) ||
1859         ((MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 32)) ) {
1860         col_set_str(pinfo->cinfo, COL_INFO, "Malformed Message");
1861         ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, ENC_NA);
1862         expert_add_info_format(pinfo, ti, &ei_mpls_echo_malformed, "Error processing Message: length is %d, should be >= %u",
1863                             rem, (MSGTYPE_MPLS_ECHO(msgtype)) ? 32 : 16);
1864         return 0;
1865     }
1866 
1867     col_add_str(pinfo->cinfo, COL_INFO,
1868                 val_to_str(msgtype, mpls_echo_msgtype, "Unknown Message Type (0x%02X)"));
1869 
1870 
1871     if (tree) {
1872         /* Add subtree and dissect the fixed part of the message */
1873         ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, ENC_NA);
1874         mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
1875 
1876         proto_tree_add_item(mpls_echo_tree,
1877                             hf_mpls_echo_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1878 
1879         if (MSGTYPE_MPLS_ECHO(msgtype)) {
1880             proto_tree *mpls_echo_gflags;
1881             ti = proto_tree_add_item(mpls_echo_tree,
1882                                      hf_mpls_echo_gflags, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1883             mpls_echo_gflags = proto_item_add_subtree(ti, ett_mpls_echo_gflags);
1884             proto_tree_add_item(mpls_echo_gflags,
1885                                 hf_mpls_echo_flag_sbz, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1886             proto_tree_add_item(mpls_echo_gflags,
1887                                 hf_mpls_echo_flag_v, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1888             proto_tree_add_item(mpls_echo_gflags,
1889                                  hf_mpls_echo_flag_t, tvb, (offset + 2), 2, ENC_BIG_ENDIAN);
1890             proto_tree_add_item(mpls_echo_gflags,
1891                                  hf_mpls_echo_flag_r, tvb, (offset + 2), 2, ENC_BIG_ENDIAN);
1892         } else {
1893             proto_tree_add_item(mpls_echo_tree,
1894                                 hf_mpls_echo_mbz, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1895         }
1896 
1897         proto_tree_add_item(mpls_echo_tree,
1898                             hf_mpls_echo_msgtype, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
1899         proto_tree_add_item(mpls_echo_tree,
1900                             hf_mpls_echo_replymode, tvb, offset + 5, 1, ENC_BIG_ENDIAN);
1901         proto_tree_add_item(mpls_echo_tree,
1902                             hf_mpls_echo_returncode, tvb, offset + 6, 1, ENC_BIG_ENDIAN);
1903         proto_tree_add_item(mpls_echo_tree,
1904                             hf_mpls_echo_returnsubcode, tvb, offset + 7, 1, ENC_BIG_ENDIAN);
1905         proto_tree_add_item(mpls_echo_tree,
1906                             hf_mpls_echo_handle, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1907         proto_tree_add_item(mpls_echo_tree,
1908                             hf_mpls_echo_sequence, tvb, offset + 12, 4, ENC_BIG_ENDIAN);
1909 
1910         if (MSGTYPE_MPLS_ECHO(msgtype)) {
1911             proto_tree_add_item(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
1912                                 offset + 16, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
1913             proto_tree_add_item(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
1914                                 offset + 24, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
1915         }
1916     }
1917 
1918     if (MSGTYPE_MPLS_ECHO(msgtype)) {
1919         offset += 32;
1920         rem    -= 32;
1921     } else {
1922         offset += 16;
1923         rem    -= 16;
1924     }
1925 
1926     /* Dissect all TLVs */
1927     while (tvb_reported_length_remaining(tvb, offset) > 0 ) {
1928         len = dissect_mpls_echo_tlv(tvb, pinfo, offset, mpls_echo_tree, rem, FALSE);
1929         offset += len;
1930         rem    -= len;
1931     }
1932 
1933 
1934     return tvb_captured_length(tvb);
1935 }
1936 
1937 /* Register the protocol with Wireshark */
1938 
1939 void
proto_register_mpls_echo(void)1940 proto_register_mpls_echo(void)
1941 {
1942 
1943     static hf_register_info hf[] = {
1944         { &hf_mpls_echo_version,
1945           { "Version", "mpls_echo.version",
1946             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Version Number", HFILL}
1947         },
1948         { &hf_mpls_echo_mbz,
1949           { "MBZ", "mpls_echo.mbz",
1950             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Must be Zero", HFILL}
1951         },
1952         { &hf_mpls_echo_gflags,
1953           { "Global Flags", "mpls_echo.flags",
1954             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Global Flags", HFILL}
1955         },
1956         { &hf_mpls_echo_flag_sbz,
1957           { "Reserved", "mpls_echo.flag_sbz",
1958             FT_UINT16, BASE_HEX, NULL, 0xFFF8, "MPLS ECHO Reserved Flags", HFILL}
1959         },
1960         { &hf_mpls_echo_flag_v,
1961           { "Validate FEC Stack", "mpls_echo.flag_v",
1962             FT_BOOLEAN, 16, NULL, 0x0001, "MPLS ECHO Validate FEC Stack Flag", HFILL}
1963         },
1964         { &hf_mpls_echo_flag_t,
1965           { "Respond only if TTL expired", "mpls_echo.flag_t",
1966             FT_BOOLEAN, 16, NULL, 0x0002, "MPLS ECHO Respond only if TTL expired Flag", HFILL}
1967         },
1968         { &hf_mpls_echo_flag_r,
1969           { "Validate Reverse Path", "mpls_echo.flag_r",
1970             FT_BOOLEAN, 16, NULL, 0x0004, "MPLS ECHO Validate Reverse Path Flag", HFILL}
1971         },
1972         { &hf_mpls_echo_msgtype,
1973           { "Message Type", "mpls_echo.msg_type",
1974             FT_UINT8, BASE_DEC, VALS(mpls_echo_msgtype), 0x0, "MPLS ECHO Message Type", HFILL}
1975         },
1976         { &hf_mpls_echo_replymode,
1977           { "Reply Mode", "mpls_echo.reply_mode",
1978             FT_UINT8, BASE_DEC, VALS(mpls_echo_replymode), 0x0, "MPLS ECHO Reply Mode", HFILL}
1979         },
1980         { &hf_mpls_echo_returncode,
1981           { "Return Code", "mpls_echo.return_code",
1982             FT_UINT8, BASE_DEC | BASE_EXT_STRING, &mpls_echo_returncode_ext, 0x0, "MPLS ECHO Return Code", HFILL}
1983         },
1984         { &hf_mpls_echo_returnsubcode,
1985           { "Return Subcode", "mpls_echo.return_subcode",
1986             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO Return Subcode", HFILL}
1987         },
1988         { &hf_mpls_echo_handle,
1989           { "Sender's Handle", "mpls_echo.sender_handle",
1990             FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO Sender's Handle", HFILL}
1991         },
1992         { &hf_mpls_echo_sequence,
1993           { "Sequence Number", "mpls_echo.sequence",
1994             FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Sequence Number", HFILL}
1995         },
1996         { &hf_mpls_echo_ts_sent,
1997           { "Timestamp Sent", "mpls_echo.timestamp_sent",
1998             FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "MPLS ECHO Timestamp Sent", HFILL}
1999         },
2000         { &hf_mpls_echo_ts_rec,
2001           { "Timestamp Received", "mpls_echo.timestamp_rec",
2002             FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "MPLS ECHO Timestamp Received", HFILL}
2003         },
2004         { &hf_mpls_echo_tlv_type,
2005           { "Type", "mpls_echo.tlv.type",
2006             FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_type_names_ext, 0x0,
2007             "MPLS ECHO TLV Type", HFILL}
2008         },
2009         { &hf_mpls_echo_tlv_len,
2010           { "Length", "mpls_echo.tlv.len",
2011             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Length", HFILL}
2012         },
2013         { &hf_mpls_echo_tlv_value,
2014           { "Value", "mpls_echo.tlv.value",
2015             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Value", HFILL}
2016         },
2017         { &hf_mpls_echo_tlv_fec_type,
2018           { "Type", "mpls_echo.tlv.fec.type",
2019             FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_fec_names_ext, 0x0,
2020             "MPLS ECHO TLV FEC Stack Type", HFILL}
2021         },
2022         { &hf_mpls_echo_tlv_fec_len,
2023           { "Length", "mpls_echo.tlv.fec.len",
2024             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Length", HFILL}
2025         },
2026         { &hf_mpls_echo_tlv_fec_value,
2027           { "Value", "mpls_echo.tlv.fec.value",
2028             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Value", HFILL}
2029         },
2030         { &hf_mpls_echo_tlv_fec_ldp_ipv4,
2031           { "IPv4 Prefix", "mpls_echo.tlv.fec.ldp_ipv4",
2032             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4", HFILL}
2033         },
2034         { &hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
2035           { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv4_mask",
2036             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4 Prefix Length", HFILL}
2037         },
2038         { &hf_mpls_echo_tlv_fec_ldp_ipv6,
2039           { "IPv6 Prefix", "mpls_echo.tlv.fec.ldp_ipv6",
2040             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6", HFILL}
2041         },
2042         { &hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
2043           { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv6_mask",
2044             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6 Prefix Length", HFILL}
2045         },
2046         { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
2047           { "IPv4 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv4_ep",
2048             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Tunnel Endpoint Address", HFILL}
2049         },
2050         { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
2051           { "IPv6 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv6_ep",
2052             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Tunnel Endpoint Address", HFILL}
2053         },
2054         { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
2055           { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz1",
2056             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
2057         },
2058         { &hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
2059           { "Tunnel ID", "mpls_echo.tlv.fec.rsvp_ip_tun_id",
2060             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP Tunnel ID", HFILL}
2061         },
2062         { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
2063           { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv4_ext_tun_id",
2064             FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Extended Tunnel ID", HFILL}
2065         },
2066         { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
2067           { "IPv4 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv4_sender",
2068             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
2069         },
2070         { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
2071           { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv6_ext_tun_id",
2072             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Extended Tunnel ID", HFILL}
2073         },
2074         { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
2075           { "IPv6 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv6_sender",
2076             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
2077         },
2078         { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
2079           { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz2",
2080             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
2081         },
2082         { &hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
2083           { "LSP ID", "mpls_echo.tlv.fec.rsvp_ip_lsp_id",
2084             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP LSP ID", HFILL}
2085         },
2086         { &hf_mpls_echo_tlv_fec_vpn_route_dist,
2087           { "Route Distinguisher", "mpls_echo.tlv.fec.vpn_route_dist",
2088             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN Route Distinguisher", HFILL}
2089         },
2090         { &hf_mpls_echo_tlv_fec_vpn_ipv4,
2091           { "IPv4 Prefix", "mpls_echo.tlv.fec.vpn_ipv4",
2092             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN IPv4", HFILL}
2093         },
2094         { &hf_mpls_echo_tlv_fec_vpn_ipv6,
2095           { "IPv6 Prefix", "mpls_echo.tlv.fec.vpn_ipv6",
2096             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN IPv6", HFILL}
2097         },
2098         { &hf_mpls_echo_tlv_fec_vpn_len,
2099           { "Prefix Length", "mpls_echo.tlv.fec.vpn_len",
2100             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN Prefix Length", HFILL}
2101         },
2102         { &hf_mpls_echo_tlv_fec_l2_vpn_route_dist,
2103           { "Route Distinguisher", "mpls_echo.tlv.fec.l2vpn_route_dist",
2104             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Route Distinguisher", HFILL}
2105         },
2106         { &hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id,
2107           { "Sender's VE ID", "mpls_echo.tlv.fec.l2vpn_send_ve_id",
2108             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Sender's VE ID", HFILL}
2109         },
2110         { &hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id,
2111           { "Receiver's VE ID", "mpls_echo.tlv.fec.l2vpn_recv_ve_id",
2112             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Receiver's VE ID", HFILL}
2113         },
2114         { &hf_mpls_echo_tlv_fec_l2_vpn_encap_type,
2115           { "Encapsulation", "mpls_echo.tlv.fec.l2vpn_encap_type",
2116             FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2VPN Encapsulation", HFILL}
2117         },
2118         { &hf_mpls_echo_tlv_fec_l2cid_sender,
2119           { "Sender's PE Address", "mpls_echo.tlv.fec.l2cid_sender",
2120             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Sender", HFILL}
2121         },
2122         { &hf_mpls_echo_tlv_fec_l2cid_remote,
2123           { "Remote PE Address", "mpls_echo.tlv.fec.l2cid_remote",
2124             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Remote", HFILL}
2125         },
2126         { &hf_mpls_echo_tlv_fec_l2cid_vcid,
2127           { "VC ID", "mpls_echo.tlv.fec.l2cid_vcid",
2128             FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID VCID", HFILL}
2129         },
2130         { &hf_mpls_echo_tlv_fec_l2cid_encap,
2131           { "Encapsulation", "mpls_echo.tlv.fec.l2cid_encap",
2132             FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2CID Encapsulation", HFILL}
2133         },
2134         { &hf_mpls_echo_tlv_fec_l2cid_mbz,
2135           { "MBZ", "mpls_echo.tlv.fec.l2cid_mbz",
2136             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID MBZ", HFILL}
2137         },
2138         { &hf_mpls_echo_tlv_fec_bgp_ipv4,
2139           { "IPv4 Prefix", "mpls_echo.tlv.fec.bgp_ipv4",
2140             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv4", HFILL}
2141         },
2142         { &hf_mpls_echo_tlv_fec_bgp_ipv6,
2143           { "IPv6 Prefix", "mpls_echo.tlv.fec.bgp_ipv6",
2144             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv6", HFILL}
2145         },
2146         { &hf_mpls_echo_tlv_fec_bgp_len,
2147           { "Prefix Length", "mpls_echo.tlv.fec.bgp_len",
2148             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Prefix Length", HFILL}
2149         },
2150         { &hf_mpls_echo_tlv_fec_gen_ipv4,
2151           { "IPv4 Prefix", "mpls_echo.tlv.fec.gen_ipv4",
2152             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4", HFILL}
2153         },
2154         { &hf_mpls_echo_tlv_fec_gen_ipv4_mask,
2155           { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv4_mask",
2156             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4 Prefix Length", HFILL}
2157         },
2158         { &hf_mpls_echo_tlv_fec_gen_ipv6,
2159           { "IPv6 Prefix", "mpls_echo.tlv.fec.gen_ipv6",
2160             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6", HFILL}
2161         },
2162         { &hf_mpls_echo_tlv_fec_gen_ipv6_mask,
2163           { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv6_mask",
2164             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6 Prefix Length", HFILL}
2165         },
2166         { &hf_mpls_echo_tlv_fec_nil_label,
2167           { "Label", "mpls_echo.tlv.fec.nil_label",
2168             FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV FEC Stack NIL Label", HFILL}
2169         },
2170         { &hf_mpls_echo_tlv_fec_pw_ipv6_128_sender,
2171           { "Sender's PE Address", "mpls_echo.tlv.fec.pw_ipv6_128_sender",
2172             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC PW IPV6 FEC 128 SENDER", HFILL }
2173         },
2174         { &hf_mpls_echo_tlv_fec_pw_ipv6_128_remote,
2175           { "Remote's PE Address", "mpls_echo.tlv.fec.pw_ipv6_128_remote",
2176             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC PW IPV6 FEC 128 REMOTE", HFILL }
2177         },
2178         { &hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_id,
2179           { "PW ID", "mpls_echo.tlv.fec.fec.pw_ipv6_128_pwid",
2180             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC PW IPV6 FEC 128 PW ID", HFILL}
2181         },
2182         { &hf_mpls_echo_tlv_fec_pw_ipv6_128_pw_type,
2183           { "PW TYPE", "mpls_echo.tlv.fec.fec.pw_ipv6_128_pw_type",
2184             FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC PW IPV6 FEC 128 PW TYPE", HFILL}
2185         },
2186         { &hf_mpls_echo_tlv_fec_pw_ipv6_128_mbz,
2187           { "MBZ", "mpls_echo.tlv.fec.fec.pw_ipv6_128_mbz",
2188             FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC PW IPV6 FEC 128 MBZ", HFILL}
2189         },
2190         { &hf_mpls_echo_tlv_fec_igp_ipv4,
2191           { "IPv4 Prefix", "mpls_echo.tlv.fec.igp_ipv4",
2192             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP IPv4", HFILL}
2193         },
2194         { &hf_mpls_echo_tlv_fec_igp_ipv6,
2195           { "IPv6 Prefix", "mpls_echo.tlv.fec.igp_ipv6",
2196             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP IPv6", HFILL}
2197         },
2198         { &hf_mpls_echo_tlv_fec_igp_mask,
2199           { "Prefix Length", "mpls_echo.tlv.fec.igp_mask",
2200             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Prefix Length", HFILL}
2201         },
2202         { &hf_mpls_echo_tlv_fec_igp_protocol,
2203           { "Protocol", "mpls_echo.tlv.fec.igp_protocol",
2204             FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_sr_protocol_types), 0x0, "MPLS ECHO TLV FEC Stack IGP Protocol", HFILL}
2205         },
2206         { &hf_mpls_echo_tlv_fec_igp_reserved,
2207           { "Reserved", "mpls_echo.tlv.fec.igp_reserved",
2208             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Reserved", HFILL}
2209         },
2210         { &hf_mpls_echo_tlv_fec_igp_adj_type,
2211           { "Adjacency Type", "mpls_echo.tlv.fec.igp_adj_type",
2212             FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_igp_adjacency_types), 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Type", HFILL}
2213         },
2214         { &hf_mpls_echo_tlv_fec_igp_adj_local_ipv4,
2215           { "Local Interface ID", "mpls_echo.tlv.fec.igp_adj_local_id.ipv4",
2216             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Local Interface ID", HFILL}
2217         },
2218         { &hf_mpls_echo_tlv_fec_igp_adj_local_ipv6,
2219           { "Local Interface ID", "mpls_echo.tlv.fec.igp_adj_local_id.ipv6",
2220             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Local Interface ID", HFILL}
2221         },
2222         { &hf_mpls_echo_tlv_fec_igp_adj_local_ident,
2223           { "Local Interface ID", "mpls_echo.tlv.fec.igp_adj_local_id.ident",
2224             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Local Interface ID", HFILL}
2225         },
2226         { &hf_mpls_echo_tlv_fec_igp_adj_remote_ipv4,
2227           { "Remote Interface ID", "mpls_echo.tlv.fec.igp_adj_remote_id.ipv4",
2228             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Remote Interface ID", HFILL}
2229         },
2230         { &hf_mpls_echo_tlv_fec_igp_adj_remote_ipv6,
2231           { "Remote Interface ID", "mpls_echo.tlv.fec.igp_adj_remote_id.ipv6",
2232             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Remote Interface ID", HFILL}
2233         },
2234         { &hf_mpls_echo_tlv_fec_igp_adj_remote_ident,
2235           { "Remote Interface ID", "mpls_echo.tlv.fec.igp_adj_remote_id.ident",
2236             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Remote Interface ID", HFILL}
2237         },
2238         { &hf_mpls_echo_tlv_fec_igp_adj_adv_ident_ospf,
2239           { "Advertising Node Identifier Router ID", "mpls_echo.tlv.fec.igp_adj_adv_node_id.ospf",
2240             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Advertising Node Identifier OSPF Router ID", HFILL}
2241         },
2242         { &hf_mpls_echo_tlv_fec_igp_adj_adv_ident_isis,
2243           { "Advertising Node Identifier System ID", "mpls_echo.tlv.fec.igp_adj_adv_node_id.isis",
2244             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Advertising Node Identifier IS-IS System ID", HFILL}
2245         },
2246         { &hf_mpls_echo_tlv_fec_igp_adj_adv_ident,
2247           { "Advertising Node Identifier", "mpls_echo.tlv.fec.igp_adj_adv_node_id.ident",
2248             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Advertising Node Identifier", HFILL}
2249         },
2250         { &hf_mpls_echo_tlv_fec_igp_adj_rec_ident_ospf,
2251           { "Receiving Node Identifier Router ID", "mpls_echo.tlv.fec.igp_adj_rec_node_id.ospf",
2252             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Receiving Node Identifier OSPF Router ID", HFILL}
2253         },
2254         { &hf_mpls_echo_tlv_fec_igp_adj_rec_ident_isis,
2255           { "Receiving Node Identifier System ID", "mpls_echo.tlv.fec.igp_adj_rec_node_id.isis",
2256             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Receiving Node Identifier IS-IS System ID", HFILL}
2257         },
2258         { &hf_mpls_echo_tlv_fec_igp_adj_rec_ident,
2259           { "Receiving Node Identifier", "mpls_echo.tlv.fec.igp_adj_rec_node_id.ident",
2260             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IGP Adjacency Receiving Node Identifier", HFILL}
2261         },
2262         { &hf_mpls_echo_tlv_ds_map_mtu,
2263           { "MTU", "mpls_echo.tlv.ds_map.mtu",
2264             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map MTU", HFILL}
2265         },
2266         { &hf_mpls_echo_tlv_ds_map_addr_type,
2267           { "Address Type", "mpls_echo.tlv.ds_map.addr_type",
2268             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0,
2269             "MPLS ECHO TLV Downstream Map Address Type", HFILL}
2270         },
2271         { &hf_mpls_echo_tlv_ds_map_res,
2272           { "DS Flags", "mpls_echo.tlv.ds_map.res",
2273             FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map DS Flags", HFILL}
2274         },
2275         { &hf_mpls_echo_tlv_ds_map_flag_res,
2276           { "MBZ", "mpls_echo.tlv.ds_map.flag_res",
2277             FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Downstream Map Reserved Flags", HFILL}
2278         },
2279         { &hf_mpls_echo_tlv_ds_map_flag_i,
2280           { "Interface and Label Stack Request", "mpls_echo.tlv.ds_map.flag_i",
2281             FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Downstream Map I-Flag", HFILL}
2282         },
2283         { &hf_mpls_echo_tlv_ds_map_flag_n,
2284           { "Treat as Non-IP Packet", "mpls_echo.tlv.ds_map.flag_n",
2285             FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Downstream Map N-Flag", HFILL}
2286         },
2287         { &hf_mpls_echo_tlv_ds_map_ds_ip,
2288           { "Downstream IP Address", "mpls_echo.tlv.ds_map.ds_ip",
2289             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IP Address", HFILL}
2290         },
2291         { &hf_mpls_echo_tlv_ds_map_int_ip,
2292           { "Downstream Interface Address", "mpls_echo.tlv.ds_map.int_ip",
2293             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Address", HFILL}
2294         },
2295         { &hf_mpls_echo_tlv_ds_map_if_index,
2296           { "Upstream Interface Index", "mpls_echo.tlv.ds_map.if_index",
2297             FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Index", HFILL}
2298         },
2299         { &hf_mpls_echo_tlv_ds_map_ds_ipv6,
2300           { "Downstream IPv6 Address", "mpls_echo.tlv.ds_map.ds_ipv6",
2301             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IPv6 Address", HFILL}
2302         },
2303         { &hf_mpls_echo_tlv_ds_map_int_ipv6,
2304           { "Downstream Interface IPv6 Address", "mpls_echo.tlv.ds_map.int_ipv6",
2305             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface IPv6 Address", HFILL}
2306         },
2307         { &hf_mpls_echo_tlv_ds_map_hash_type,
2308           { "Multipath Type", "mpls_echo.tlv.ds_map.hash_type",
2309             FT_UINT8, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_ds_map_hash_type_ext, 0x0,
2310             "MPLS ECHO TLV Downstream Map Multipath Type", HFILL}
2311         },
2312         { &hf_mpls_echo_tlv_ds_map_depth,
2313           { "Depth Limit", "mpls_echo.tlv.ds_map.depth",
2314             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Depth Limit", HFILL}
2315         },
2316         { &hf_mpls_echo_tlv_ds_map_muti_len,
2317           { "Multipath Length", "mpls_echo.tlv.ds_map.multi_len",
2318             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Length", HFILL}
2319         },
2320         { &hf_mpls_echo_tlv_ds_map_mp_ip,
2321           { "IP Address", "mpls_echo.tlv.ds_map_mp.ip",
2322             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath IP Address", HFILL}
2323         },
2324         { &hf_mpls_echo_tlv_ds_map_mp_mask,
2325           { "Mask", "mpls_echo.tlv.ds_map_mp.mask",
2326             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Mask", HFILL}
2327         },
2328         { &hf_mpls_echo_tlv_ds_map_mp_ip_low,
2329           { "IP Address Low", "mpls_echo.tlv.ds_map_mp.ip_low",
2330             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Low IP Address", HFILL}
2331         },
2332         { &hf_mpls_echo_tlv_ds_map_mp_ip_high,
2333           { "IP Address High", "mpls_echo.tlv.ds_map_mp.ip_high",
2334             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath High IP Address", HFILL}
2335         },
2336         { &hf_mpls_echo_tlv_ds_map_mp_no_multipath_info,
2337           { "No Multipath Information", "mpls_echo.tlv.ds_map_mp.no_multipath_info",
2338             FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
2339         },
2340         { &hf_mpls_echo_tlv_ds_map_mp_value,
2341           { "Multipath Value", "mpls_echo.tlv.ds_map_mp.value",
2342             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Multipath Value", HFILL}
2343         },
2344         { &hf_mpls_echo_tlv_ds_map_mp_label,
2345           { "Downstream Label", "mpls_echo.tlv.ds_map.mp_label",
2346             FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Downstream Map Downstream Label", HFILL}
2347         },
2348         { &hf_mpls_echo_tlv_ds_map_mp_exp,
2349           { "Downstream Exp", "mpls_echo.tlv.ds_map.mp_exp",
2350             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream Experimental", HFILL}
2351         },
2352         { &hf_mpls_echo_tlv_ds_map_mp_bos,
2353           { "Downstream BOS", "mpls_echo.tlv.ds_map.mp_bos",
2354             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream BOS", HFILL}
2355         },
2356         { &hf_mpls_echo_tlv_ds_map_mp_proto,
2357           { "Downstream Protocol", "mpls_echo.tlv.ds_map.mp_proto",
2358             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
2359             "MPLS ECHO TLV Downstream Map Downstream Protocol", HFILL}
2360         },
2361         { &hf_mpls_echo_tlv_padaction,
2362           { "Pad Action", "mpls_echo.tlv.pad_action",
2363             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_pad), 0x0, "MPLS ECHO Pad TLV Action", HFILL}
2364         },
2365         { &hf_mpls_echo_tlv_padding,
2366           { "Padding", "mpls_echo.tlv.pad_padding",
2367             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Pad TLV Padding", HFILL}
2368         },
2369         { &hf_mpls_echo_tlv_vendor,
2370           { "Vendor Id", "mpls_echo.tlv.vendor_id",
2371             FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0x0, "MPLS ECHO Vendor Id", HFILL}
2372         },
2373         { &hf_mpls_echo_tlv_ilso_addr_type,
2374           { "Address Type", "mpls_echo.tlv.ilso.addr_type",
2375             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0,
2376             "MPLS ECHO TLV Interface and Label Stack Address Type", HFILL}
2377         },
2378         { &hf_mpls_echo_tlv_ilso_mbz,
2379           { "Must Be Zero", "mpls_echo.tlv.ilso.mbz",
2380             FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack MBZ", HFILL}
2381         },
2382         { &hf_mpls_echo_tlv_ilso_ipv4_addr,
2383           { "Downstream IPv4 Address", "mpls_echo.tlv.ilso_ipv4.addr",
2384             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
2385         },
2386         { &hf_mpls_echo_tlv_ilso_ipv4_int_addr,
2387           { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv4.int_addr",
2388             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Address", HFILL}
2389         },
2390         { &hf_mpls_echo_tlv_ilso_ipv6_addr,
2391           { "Downstream IPv6 Address", "mpls_echo.tlv.ilso_ipv6.addr",
2392             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
2393         },
2394         { &hf_mpls_echo_tlv_ilso_ipv6_int_addr,
2395           { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv6.int_addr",
2396             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Address", HFILL}
2397         },
2398         { &hf_mpls_echo_tlv_ilso_int_index,
2399           { "Downstream Interface Index", "mpls_echo.tlv.ilso.int_index",
2400             FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Index", HFILL}
2401         },
2402         { &hf_mpls_echo_tlv_ilso_label,
2403           { "Label", "mpls_echo.tlv.ilso_ipv4.label",
2404             FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Interface and Label Stack Label", HFILL}
2405         },
2406         { &hf_mpls_echo_tlv_ilso_exp,
2407           { "Exp", "mpls_echo.tlv.ilso_ipv4.exp",
2408             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Exp", HFILL}
2409         },
2410         { &hf_mpls_echo_tlv_ilso_bos,
2411           { "BOS", "mpls_echo.tlv.ilso_ipv4.bos",
2412             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack BOS", HFILL}
2413         },
2414         { &hf_mpls_echo_tlv_ilso_ttl,
2415           { "TTL", "mpls_echo.tlv.ilso_ipv4.ttl",
2416             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack TTL", HFILL}
2417         },
2418 #if 0
2419         { &hf_mpls_echo_tlv_rto_ipv4,
2420           { "Reply-to IPv4 Address", "mpls_echo.tlv.rto.ipv4",
2421             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv4 Reply-To Object", HFILL}
2422         },
2423         { &hf_mpls_echo_tlv_rto_ipv6,
2424           { "Reply-to IPv6 Address", "mpls_echo.tlv.rto.ipv6",
2425             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv6 Reply-To Object", HFILL}
2426         },
2427 #endif
2428         { &hf_mpls_echo_tlv_reply_tos,
2429           { "Reply-TOS Byte", "mpls_echo.tlv.reply.tos",
2430             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Reply-TOS Byte", HFILL}
2431         },
2432         { &hf_mpls_echo_tlv_reply_tos_mbz,
2433           { "MBZ", "mpls_echo.tlv.reply.tos.mbz",
2434             FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Reply-TOS MBZ", HFILL}
2435         },
2436         { &hf_mpls_echo_tlv_errored_type,
2437           { "Errored TLV Type", "mpls_echo.tlv.errored.type",
2438             FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_type_names_ext, 0x0,
2439             "MPLS ECHO TLV Errored TLV Type", HFILL}
2440         },
2441         { &hf_mpls_echo_tlv_ds_map_ingress_if_num,
2442           { "Ingress Interface Number", "mpls_echo.tlv.ds_map.ingress.if.num",
2443             FT_UINT32, BASE_DEC, NULL, 0x0,
2444             "MPLS ECHO TLV DownStream Map Ingress Interface Number", HFILL}
2445         },
2446         { &hf_mpls_echo_tlv_ds_map_egress_if_num,
2447           { "Egress Interface Number", "mpls_echo.tlv.ds_map.egress.if.num",
2448             FT_UINT32, BASE_DEC, NULL, 0x0,
2449             "MPLS ECHO TLV DownStream Map Egress Interface Number", HFILL}
2450         },
2451         { &hf_mpls_echo_lspping_tlv_src_gid,
2452           { "SRC GLOBAL ID", "mpls_echo.lspping.tlv.src.gid",
2453             FT_UINT32, BASE_DEC, NULL, 0x0, "LSP SRC  GID", HFILL}
2454         },
2455         { &hf_mpls_echo_lspping_tlv_src_nid,
2456           { "SRC NODE ID", "mpls_echo.lspping.tlv.src.nid",
2457             FT_IPv4, BASE_NONE, NULL, 0x0, "LSP SRC NID", HFILL}
2458         },
2459         { &hf_mpls_echo_lspping_tlv_src_tunnel_no,
2460           { "SRC Tunnel Number", "mpls_echo.lspping.tlv.tunnel.no",
2461             FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC Tunnel Number", HFILL}
2462         },
2463         { &hf_mpls_echo_lspping_tlv_lsp_no,
2464           { "SRC LSP Number", "mpls_echo.lspping.tlv.lsp.no",
2465             FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC LSP  Number", HFILL}
2466         },
2467         { &hf_mpls_echo_lspping_tlv_dst_gid,
2468           { "DST GLOBAL ID", "mpls_echo.lspping.tlv.dst.gid",
2469             FT_UINT32, BASE_DEC, NULL, 0x0, "LSP FEC DST  GID", HFILL}
2470         },
2471         { &hf_mpls_echo_lspping_tlv_dst_nid,
2472           { "DST NODE ID", "mpls_echo.lspping.tlv.dst.nid",
2473             FT_IPv4, BASE_NONE, NULL, 0x0, "LSP FEC DST NID", HFILL}
2474         },
2475         { &hf_mpls_echo_lspping_tlv_dst_tunnel_no,
2476           { "DST Tunnel Number", "mpls_echo.lspping.tlv.dst.tunnel.no",
2477             FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC DST Tunnel Number", HFILL}
2478         },
2479         { &hf_mpls_echo_lspping_tlv_resv,
2480           { "RESERVED", "mpls_echo.lspping.tlv.resv",
2481             FT_UINT16, BASE_DEC, NULL, 0x0, "RESERVED BITS", HFILL}
2482         },
2483         { &hf_mpls_echo_lspping_tlv_src_addr_gid,
2484           { "Global ID", "mpls_echo.lspping.tlv.src.addr.gid",
2485             FT_UINT32, BASE_DEC, NULL, 0x0, "SRC ADDR TLV GID", HFILL}
2486         },
2487         { &hf_mpls_echo_lspping_tlv_src_addr_nid,
2488           { "Node ID", "mpls_echo.lspping.tlv.src.addr.nid",
2489             FT_IPv4, BASE_NONE, NULL, 0x0, "SRC ADDR TLV NID", HFILL}
2490         },
2491         { &hf_mpls_echo_lspping_tlv_pw_serv_identifier,
2492           { "Service identifier", "mpls_echo.lspping.tlv.pw.serv.identifier",
2493             FT_UINT64, BASE_DEC, NULL, 0x0, "PW FEC Service identifier", HFILL}
2494         },
2495         { &hf_mpls_echo_lspping_tlv_pw_src_ac_id,
2496           { "SRC AC ID", "mpls_echo.lspping.tlv.pw.src.ac.id",
2497             FT_UINT32, BASE_DEC, NULL, 0x0, "PW FEC SRC AC ID", HFILL}
2498         },
2499         { &hf_mpls_echo_lspping_tlv_pw_dst_ac_id,
2500           { "DST AC ID", "mpls_echo.lspping.tlv.pw.dst.ac.id",
2501             FT_UINT32, BASE_DEC, NULL, 0x0, "PW FEC DST AC ID", HFILL}
2502         },
2503         { &hf_mpls_echo_padding,
2504           { "Padding", "mpls_echo.padding",
2505             FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
2506         },
2507 #if 0
2508         { &hf_mpls_echo_lspping_tlv_pw_agi_type,
2509           { "AGI TYPE", "mpls_echo.lspping.tlv.pw.agi.type",
2510             FT_UINT8, BASE_DEC, NULL, 0x0, "PW AGI TYPE", HFILL}
2511         },
2512 #endif
2513 #if 0
2514         { &hf_mpls_echo_lspping_tlv_pw_agi_len,
2515           { "AGI Length", "mpls_echo.lspping.tlv.pw.agi.len",
2516             FT_UINT8, BASE_DEC, NULL, 0x0, "PW AGI LENGTH", HFILL}
2517         },
2518 #endif
2519 #if 0
2520         { &hf_mpls_echo_lspping_tlv_pw_agi_val,
2521           { "AGI VALUE", "mpls_echo.lspping.tlv.pw.agi.val",
2522             FT_STRING, BASE_NONE, NULL, 0x0, "PW AGI VALUE", HFILL}
2523         },
2524 #endif
2525         { &hf_mpls_echo_tlv_dd_map_mtu,
2526           { "MTU", "mpls_echo.lspping.tlv.dd_map.mtu",
2527             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map MTU", HFILL}
2528         },
2529         { &hf_mpls_echo_tlv_dd_map_addr_type,
2530           { "Address Type", "mpls_echo.tlv.dd_map.addr_type",
2531             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0, "MPLS ECHO TLV Detailed Downstream Map Address Type", HFILL}
2532         },
2533         { &hf_mpls_echo_tlv_dd_map_res,
2534           { "DS Flags", "mpls_echo.tlv.dd_map.res",
2535             FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map DS Flags", HFILL}
2536         },
2537         { &hf_mpls_echo_tlv_dd_map_flag_res,
2538           { "MBZ", "mpls_echo.tlv.dd_map.flag_res",
2539             FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Detailed Downstream Map Reserved Flags", HFILL}
2540         },
2541         { &hf_mpls_echo_tlv_dd_map_flag_i,
2542           { "Interface and Label Stack Request", "mpls_echo.tlv.dd_map.flag_i",
2543             FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Detailed Downstream Map I-Flag", HFILL}
2544         },
2545         { &hf_mpls_echo_tlv_dd_map_flag_n,
2546           { "Treat as Non-IP Packet", "mpls_echo.tlv.dd_map.flag_n",
2547             FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Detailed Downstream Map N-Flag", HFILL}
2548         },
2549         { &hf_mpls_echo_tlv_dd_map_ds_ip,
2550           { "Downstream IP Address", "mpls_echo.tlv.dd_map.ds_ip",
2551             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map IP Address", HFILL}
2552         },
2553         { &hf_mpls_echo_tlv_dd_map_int_ip,
2554           { "Downstream Interface Address", "mpls_echo.tlv.dd_map.int_ip",
2555             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Interface Address", HFILL}
2556         },
2557         { &hf_mpls_echo_tlv_dd_map_ds_ipv6,
2558           { "Downstream IPv6 Address", "mpls_echo.tlv.dd_map.ds_ipv6",
2559             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map IPv6 Address", HFILL}
2560         },
2561         { &hf_mpls_echo_tlv_dd_map_int_ipv6,
2562           { "Downstream Interface IPv6 Address", "mpls_echo.tlv.dd_map.int_ipv6",
2563             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Interface IPv6 Address", HFILL}
2564         },
2565         { &hf_mpls_echo_tlv_dd_map_return_code,
2566           { "Return Code", "mpls_echo.tlv.dd_map.return_code",
2567             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Return Code", HFILL}
2568         },
2569         { &hf_mpls_echo_tlv_dd_map_return_subcode,
2570           { "Return Subcode", "mpls_echo.tlv.dd_map.return_subcode",
2571             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Return Subcode", HFILL}
2572         },
2573         { &hf_mpls_echo_tlv_dd_map_ingress_if_num,
2574           { "Ingress Interface Number", "mpls_echo.tlv.dd_map.ingress.if.num",
2575             FT_UINT32, BASE_DEC, NULL, 0x0,
2576             "MPLS ECHO TLV Detailed DownStream Map Ingress Interface Number", HFILL}
2577         },
2578         { &hf_mpls_echo_tlv_dd_map_egress_if_num,
2579           { "Egress Interface Number", "mpls_echo.tlv.dd_map.egress.if.num",
2580             FT_UINT32, BASE_DEC, NULL, 0x0,
2581             "MPLS ECHO TLV Detailed DownStream Map Egress Interface Number", HFILL}
2582         },
2583         { &hf_mpls_echo_tlv_dd_map_subtlv_len,
2584           { "Subtlv Length", "mpls_echo.tlv.dd_map.subtlv_len",
2585             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Subtlv Length", HFILL}
2586         },
2587         { &hf_mpls_echo_sub_tlv_multipath_type,
2588           { "Multipath Type",  "mpls_echo.subtlv.dd_map.multipath_type",
2589             FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Type", HFILL}
2590         },
2591         { &hf_mpls_echo_sub_tlv_multipath_length,
2592           { "Multipath Length", "mpls_echo.subtlv.dd_map.multipath_length",
2593             FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Length", HFILL}
2594         },
2595         { &hf_mpls_echo_sub_tlv_multipath_value,
2596           { "Multipath Value", "mpls_echo.subtlv.dd_map.multipath_value",
2597             FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Value", HFILL}
2598         },
2599         { &hf_mpls_echo_sub_tlv_resv,
2600           { "Reserved", "mpls_echo.subtlv.dd_map.reserved",
2601             FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Reserved Bits", HFILL}
2602         },
2603         { &hf_mpls_echo_sub_tlv_multipath_info,
2604           { "Multipath Information", "mpls_echo.subtlv.dd_map.multipath_info",
2605             FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Value", HFILL}
2606         },
2607 #if 0
2608         { &hf_mpls_echo_tlv_ddstlv_map_mp_label,
2609           { "Downstream Label", "mpls_echo.tlv.ddstlv_map.mp_label",
2610             FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream Label", HFILL}
2611         },
2612 #endif
2613         { &hf_mpls_echo_tlv_ddstlv_map_mp_proto,
2614           { "Downstream Protocol", "mpls_echo.tlv.ddstlv_map.mp_proto",
2615             FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
2616             "MPLS ECHO TLV Detailed Downstream Map Downstream Protocol", HFILL}
2617         },
2618 #if 0
2619         { &hf_mpls_echo_tlv_ddstlv_map_mp_exp,
2620           { "Downstream Experimental", "mpls_echo.tlv.ddstlv_map.mp_exp",
2621             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream Experimental", HFILL}
2622         },
2623 #endif
2624 #if 0
2625         { &hf_mpls_echo_tlv_ddstlv_map_mp_bos,
2626           { "Downstream BOS", "mpls_echo.tlv.ddstlv_map.mp_bos",
2627             FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream BOS", HFILL}
2628         },
2629 #endif
2630         { &hf_mpls_echo_sub_tlv_multipath_ip,
2631           { "IP Address", "mpls_echo.tlv.ddstlv_map_mp.ip",
2632             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath IP Address", HFILL}
2633         },
2634         { &hf_mpls_echo_sub_tlv_mp_ip_low,
2635           { "IP Address Low", "mpls_echo.tlv.ddstlv_map_mp.ip_low",
2636             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath Low IP Address", HFILL}
2637         },
2638         { &hf_mpls_echo_sub_tlv_mp_ip_high,
2639           { "IP Address High", "mpls_echo.tlv.ddstlv_map_mp.ip_high",
2640             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath High IP Address", HFILL}
2641         },
2642         { &hf_mpls_echo_sub_tlv_mp_mask,
2643           { "Mask", "mpls_echo.tlv.ddstlv_map_mp.mask",
2644             FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath Mask", HFILL}
2645         },
2646         { &hf_mpls_echo_sub_tlv_op_type,
2647           { "Operation Type", "mpls_echo.tlv.ddstlv_map.op_type",
2648             FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_op_types), 0x0,
2649             "MPLS ECHO TLV Detailed Downstream Map Stack Change Operation Type", HFILL}
2650         },
2651         { &hf_mpls_echo_sub_tlv_addr_type,
2652           { "Address Type", "mpls_echo.tlv.ddstlv_map.address_type",
2653             FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_addr_types), 0x0,
2654             "MPLS ECHO TLV Detailed Downstream Map Stack Change Address Type", HFILL}
2655         },
2656         { &hf_mpls_echo_sub_tlv_fec_tlv_value,
2657           { "FEC tlv Length", "mpls_echo.subtlv.dd_map.fec_tlv_type",
2658             FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Map FEC TLV Length", HFILL}
2659         },
2660         { &hf_mpls_echo_sub_tlv_label,
2661           { "Label", "mpls_echo.subtlv.label",
2662             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2663         },
2664         { &hf_mpls_echo_sub_tlv_traffic_class,
2665           { "Traffic Class", "mpls_echo.subtlv.traffic_class",
2666             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2667         },
2668         { &hf_mpls_echo_sub_tlv_s_bit,
2669           { "S bit", "mpls_echo.subtlv.s_bit",
2670             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2671         },
2672         { &hf_mpls_echo_sub_tlv_res,
2673           { "Reserved", "mpls_echo.subtlv.dd_map.reserved",
2674             FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Reserved Bits", HFILL}
2675         },
2676         { &hf_mpls_echo_sub_tlv_remote_peer_unspecified,
2677           { "Unspecified (Address Length = 0)", "mpls_echo.tlv.dd_map.unspecified",
2678             FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
2679         },
2680         { &hf_mpls_echo_sub_tlv_remote_peer_ip,
2681           { "Remote Peer IP Address", "mpls_echo.tlv.dd_map.remote_ip",
2682             FT_IPv4, BASE_NONE, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Remote Peer IP Address", HFILL}
2683         },
2684         { &hf_mpls_echo_sub_tlv_remore_peer_ipv6,
2685           { "Remote Peer IPv6 Address", "mpls_echo.tlv.dd_map.remote_ipv6",
2686             FT_IPv6, BASE_NONE, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Remote Peer IPv6 Address", HFILL}
2687         },
2688         { &hf_mpls_echo_tlv_dd_map_type,
2689           { "Sub-TLV Type",  "mpls_echo.subtlv.dd_map.type",
2690             FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Type", HFILL}
2691         },
2692         { &hf_mpls_echo_tlv_dd_map_length,
2693           { "Sub-TLV Length", "mpls_echo.subtlv.dd_map.length",
2694             FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Length", HFILL}
2695         },
2696         { &hf_mpls_echo_tlv_dd_map_value,
2697           { "Sub-TLV Value", "mpls_echo.subtlv.dd_map.value",
2698             FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Value", HFILL}
2699         },
2700         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id,
2701           { "P2MP ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_id",
2702             FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP ID", HFILL}
2703         },
2704         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
2705           { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_p2mp_ip_mbz1",
2706             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP MBZ", HFILL}
2707         },
2708         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
2709           { "Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ip_tun_id",
2710             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP Tunnel ID", HFILL}
2711         },
2712         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id,
2713           { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_ext_tun_id",
2714             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv4 Extended Tunnel ID", HFILL}
2715         },
2716         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender,
2717           { "IPv4 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_sender",
2718             FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv4 Sender", HFILL}
2719         },
2720         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2,
2721           { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_p2mp_ip_mbz2",
2722             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP MBZ", HFILL}
2723         },
2724         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
2725           { "LSP ID", "mpls_echo.tlv.fec.rsvp_p2mp_ip_lsp_id",
2726             FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP LSP ID", HFILL}
2727         },
2728         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id,
2729           { "P2MP IPv6 Tunnel ID address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_id",
2730             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 ID", HFILL}
2731         },
2732         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id,
2733           { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_ext_tun_id",
2734             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 Extended Tunnel ID", HFILL}
2735         },
2736         { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender,
2737           { "P2MP IPv6 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_sender",
2738             FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 Sender", HFILL}
2739         },
2740         { &hf_mpls_echo_tlv_responder_indent_type,
2741           { "Target Type", "mpls_echo.tlv.resp_id.type",
2742             FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_responder_ident_sub_tlv_type), 0x0, "P2MP Responder ID TLV", HFILL}
2743         },
2744         { &hf_mpls_echo_tlv_responder_indent_len,
2745           { "Length", "mpls_echo.tlv.resp_id.length",
2746             FT_UINT16, BASE_DEC, NULL, 0x0, "P2MP Responder ID TLV LENGTH", HFILL}
2747         },
2748         { &hf_mpls_echo_tlv_responder_indent_ipv4,
2749           { "Target IPv4 Address", "mpls_echo.tlv.resp_id.ipv4",
2750             FT_IPv4, BASE_NONE, NULL, 0x0, "P2MP Responder ID TLV IPv4 Address", HFILL}
2751         },
2752 #if 0
2753         { &hf_mpls_echo_tlv_responder_indent_ipv6,
2754           { "Target IPv6 Address", "mpls_echo.tlv.resp_id.ipv6",
2755             FT_IPv6, BASE_NONE, NULL, 0x0, "P2MP Responder ID TLV IPv6 Address", HFILL}
2756         },
2757 #endif
2758         { &hf_mpls_echo_tlv_echo_jitter,
2759           { "Echo Jitter time", "mpls_echo.tlv.echo_jitter",
2760             FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Jitter time", HFILL}
2761         },
2762         { &hf_mpls_echo_tlv_bfd,
2763           { "BFD Discriminator", "mpls_echo.bfd_discriminator",
2764             FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO BFD Discriminator", HFILL}
2765         },
2766     };
2767 
2768     static gint *ett[] = {
2769         &ett_mpls_echo,
2770         &ett_mpls_echo_gflags,
2771         &ett_mpls_echo_tlv,
2772         &ett_mpls_echo_tlv_fec,
2773         &ett_mpls_echo_tlv_ds_map,
2774         &ett_mpls_echo_tlv_ilso,
2775         &ett_mpls_echo_tlv_dd_map,
2776         &ett_mpls_echo_tlv_ddstlv_map
2777     };
2778 
2779     static ei_register_info ei[] = {
2780         { &ei_mpls_echo_tlv_fec_len, { "mpls_echo.tlv.fec.len.invalid", PI_MALFORMED, PI_ERROR, "Invalid FEC TLV length", EXPFILL }},
2781         { &ei_mpls_echo_tlv_dd_map_subtlv_len, { "mpls_echo.tlv.dd_map.subtlv_len.invalid", PI_MALFORMED, PI_ERROR, "Invalid Sub-TLV length", EXPFILL }},
2782         { &ei_mpls_echo_tlv_len, { "mpls_echo.tlv.len.invalid", PI_MALFORMED, PI_ERROR, "Invalid TLV length", EXPFILL }},
2783         { &ei_mpls_echo_tlv_ds_map_muti_len, { "mpls_echo.tlv.ds_map.multi_len.invalid", PI_MALFORMED, PI_ERROR, "Invalid Multipath TLV length", EXPFILL }},
2784         { &ei_mpls_echo_unknown_address_type, { "mpls_echo.address_type.unknown", PI_UNDECODED, PI_WARN, "Unknown Address Type", EXPFILL }},
2785         { &ei_mpls_echo_incorrect_address_type, { "mpls_echo.address_type.incorrect", PI_PROTOCOL, PI_WARN, "Incorrect address type for TLV?", EXPFILL }},
2786         { &ei_mpls_echo_malformed, { "mpls_echo.malformed", PI_MALFORMED, PI_ERROR, "Malformed MPLS message", EXPFILL }},
2787     };
2788 
2789     expert_module_t* expert_mpls_echo;
2790 
2791     proto_mpls_echo = proto_register_protocol("Multiprotocol Label Switching Echo", "MPLS Echo", "mpls-echo");
2792 
2793     proto_register_field_array(proto_mpls_echo, hf, array_length(hf));
2794     proto_register_subtree_array(ett, array_length(ett));
2795     expert_mpls_echo = expert_register_protocol(proto_mpls_echo);
2796     expert_register_field_array(expert_mpls_echo, ei, array_length(ei));
2797 }
2798 
2799 
2800 void
proto_reg_handoff_mpls_echo(void)2801 proto_reg_handoff_mpls_echo(void)
2802 {
2803     dissector_handle_t mpls_echo_handle;
2804 
2805     mpls_echo_handle = create_dissector_handle(dissect_mpls_echo, proto_mpls_echo);
2806     dissector_add_uint_with_preference("udp.port", UDP_PORT_MPLS_ECHO, mpls_echo_handle);
2807 
2808     dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_ONDEMAND_CV, mpls_echo_handle);
2809 }
2810 
2811 /*
2812  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2813  *
2814  * Local variables:
2815  * c-basic-offset: 4
2816  * tab-width: 8
2817  * indent-tabs-mode: nil
2818  * End:
2819  *
2820  * vi: set shiftwidth=4 tabstop=8 expandtab:
2821  * :indentSize=4:tabSize=8:noTabs=true:
2822  */
2823