MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-mpls-echo.c
blob75abab63c121d015c66ba8cf0e04468e2179da7a
1 /* packet-mpls-echo.c
2 * Routines for Multiprotocol Label Switching Echo dissection
3 * Copyright 2004, Carlos Pignataro <cpignata@cisco.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * (c) Copyright 2011, Jaihari Kalijanakiraman <jaiharik@ipinfusion.com>
12 * Krishnamurthy Mayya <krishnamurthy.mayya@ipinfusion.com>
13 * Nikitha Malgi <malgi.nikitha@ipinfusion.com>
14 * - Support for LSP Ping extensions as per RFC 6426
15 * Mayuresh Raut <msraut@ncsu.edu>
16 * - Support for LSP ping over MPLS as per RFC 6424
17 * (c) Copyright 2012, Subramanian Ramachandran <sramach6@ncsu.edu>
18 * - Support for BFD for MPLS as per RFC 5884
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include "config.h"
37 #include <glib.h>
39 #include <epan/packet.h>
40 #include <epan/prefs.h>
41 #include <epan/sminmpec.h>
42 #include <epan/expert.h>
43 #include "packet-ldp.h"
44 #include "packet-mpls.h"
46 #define UDP_PORT_MPLS_ECHO 3503
48 void proto_reg_handoff_mpls_echo(void);
50 static int proto_mpls_echo = -1;
51 static int hf_mpls_echo_version = -1;
52 static int hf_mpls_echo_mbz = -1;
53 static int hf_mpls_echo_gflags = -1;
54 static int hf_mpls_echo_flag_sbz = -1;
55 static int hf_mpls_echo_flag_v = -1;
56 static int hf_mpls_echo_flag_t = -1;
57 static int hf_mpls_echo_flag_r = -1;
58 static int hf_mpls_echo_msgtype = -1;
59 static int hf_mpls_echo_replymode = -1;
60 static int hf_mpls_echo_returncode = -1;
61 static int hf_mpls_echo_returnsubcode = -1;
62 static int hf_mpls_echo_handle = -1;
63 static int hf_mpls_echo_sequence = -1;
64 static int hf_mpls_echo_ts_sent = -1;
65 static int hf_mpls_echo_ts_rec = -1;
66 static int hf_mpls_echo_tlv_type = -1;
67 static int hf_mpls_echo_tlv_len = -1;
68 static int hf_mpls_echo_tlv_value = -1;
69 static int hf_mpls_echo_tlv_fec_type = -1;
70 static int hf_mpls_echo_tlv_fec_len = -1;
71 static int hf_mpls_echo_tlv_fec_value = -1;
72 static int hf_mpls_echo_tlv_fec_ldp_ipv4 = -1;
73 static int hf_mpls_echo_tlv_fec_ldp_ipv4_mask = -1;
74 static int hf_mpls_echo_tlv_fec_ldp_ipv6 = -1;
75 static int hf_mpls_echo_tlv_fec_ldp_ipv6_mask = -1;
76 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint = -1;
77 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint = -1;
78 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz1 = -1;
79 static int hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id = -1;
80 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id = -1;
81 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender = -1;
82 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id = -1;
83 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender = -1;
84 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz2 = -1;
85 static int hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id = -1;
86 static int hf_mpls_echo_tlv_fec_vpn_route_dist = -1;
87 static int hf_mpls_echo_tlv_fec_vpn_ipv4 = -1;
88 static int hf_mpls_echo_tlv_fec_vpn_len = -1;
89 static int hf_mpls_echo_tlv_fec_vpn_ipv6 = -1;
90 static int hf_mpls_echo_tlv_fec_l2_vpn_route_dist = -1;
91 static int hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id = -1;
92 static int hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id = -1;
93 static int hf_mpls_echo_tlv_fec_l2_vpn_encap_type = -1;
94 static int hf_mpls_echo_tlv_fec_l2cid_sender = -1;
95 static int hf_mpls_echo_tlv_fec_l2cid_remote = -1;
96 static int hf_mpls_echo_tlv_fec_l2cid_vcid = -1;
97 static int hf_mpls_echo_tlv_fec_l2cid_encap = -1;
98 static int hf_mpls_echo_tlv_fec_l2cid_mbz = -1;
99 static int hf_mpls_echo_tlv_fec_bgp_ipv4 = -1;
100 static int hf_mpls_echo_tlv_fec_bgp_ipv6 = -1;
101 static int hf_mpls_echo_tlv_fec_bgp_len = -1;
102 static int hf_mpls_echo_tlv_fec_gen_ipv4 = -1;
103 static int hf_mpls_echo_tlv_fec_gen_ipv4_mask = -1;
104 static int hf_mpls_echo_tlv_fec_gen_ipv6 = -1;
105 static int hf_mpls_echo_tlv_fec_gen_ipv6_mask = -1;
106 static int hf_mpls_echo_tlv_fec_nil_label = -1;
107 static int hf_mpls_echo_tlv_ds_map_mtu = -1;
108 static int hf_mpls_echo_tlv_ds_map_addr_type = -1;
109 static int hf_mpls_echo_tlv_ds_map_res = -1;
110 static int hf_mpls_echo_tlv_ds_map_flag_res = -1;
111 static int hf_mpls_echo_tlv_ds_map_flag_i = -1;
112 static int hf_mpls_echo_tlv_ds_map_flag_n = -1;
113 static int hf_mpls_echo_tlv_ds_map_ds_ip = -1;
114 static int hf_mpls_echo_tlv_ds_map_int_ip = -1;
115 static int hf_mpls_echo_tlv_ds_map_if_index = -1;
116 static int hf_mpls_echo_tlv_ds_map_ds_ipv6 = -1;
117 static int hf_mpls_echo_tlv_ds_map_int_ipv6 = -1;
118 static int hf_mpls_echo_tlv_ds_map_hash_type = -1;
119 static int hf_mpls_echo_tlv_ds_map_depth = -1;
120 static int hf_mpls_echo_tlv_ds_map_muti_len = -1;
121 static int hf_mpls_echo_tlv_ds_map_mp_ip = -1;
122 static int hf_mpls_echo_tlv_ds_map_mp_mask = -1;
123 static int hf_mpls_echo_tlv_ds_map_mp_ip_low = -1;
124 static int hf_mpls_echo_tlv_ds_map_mp_ip_high = -1;
125 static int hf_mpls_echo_tlv_ds_map_mp_value = -1;
126 static int hf_mpls_echo_tlv_ds_map_mp_label = -1;
127 static int hf_mpls_echo_tlv_ds_map_mp_exp = -1;
128 static int hf_mpls_echo_tlv_ds_map_mp_bos = -1;
129 static int hf_mpls_echo_tlv_ds_map_mp_proto = -1;
130 static int hf_mpls_echo_tlv_dd_map_mtu = -1;
131 static int hf_mpls_echo_tlv_dd_map_addr_type = -1;
132 static int hf_mpls_echo_tlv_dd_map_res = -1;
133 static int hf_mpls_echo_tlv_dd_map_flag_res = -1;
134 static int hf_mpls_echo_tlv_dd_map_flag_i = -1;
135 static int hf_mpls_echo_tlv_dd_map_flag_n = -1;
136 static int hf_mpls_echo_tlv_dd_map_ds_ip = -1;
137 static int hf_mpls_echo_tlv_dd_map_int_ip = -1;
138 static int hf_mpls_echo_tlv_dd_map_ds_ipv6 = -1;
139 static int hf_mpls_echo_tlv_dd_map_int_ipv6 = -1;
140 static int hf_mpls_echo_tlv_dd_map_return_code = -1;
141 static int hf_mpls_echo_tlv_dd_map_return_subcode = -1;
142 static int hf_mpls_echo_tlv_dd_map_subtlv_len = -1;
143 static int hf_mpls_echo_tlv_dd_map_ingress_if_num = -1;
144 static int hf_mpls_echo_tlv_dd_map_egress_if_num = -1;
145 static int hf_mpls_echo_sub_tlv_multipath_type = -1;
146 static int hf_mpls_echo_sub_tlv_multipath_length = -1;
147 static int hf_mpls_echo_sub_tlv_multipath_value = -1;
148 static int hf_mpls_echo_sub_tlv_resv = -1;
149 static int hf_mpls_echo_sub_tlv_multipath_info = -1;
150 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_label = -1; */
151 static int hf_mpls_echo_tlv_ddstlv_map_mp_proto = -1;
152 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_exp = -1; */
153 /* static int hf_mpls_echo_tlv_ddstlv_map_mp_bos = -1; */
154 static int hf_mpls_echo_sub_tlv_multipath_ip = -1;
155 static int hf_mpls_echo_sub_tlv_mp_ip_low = -1;
156 static int hf_mpls_echo_sub_tlv_mp_ip_high = -1;
157 static int hf_mpls_echo_sub_tlv_mp_mask = -1;
158 static int hf_mpls_echo_sub_tlv_op_type = -1;
159 static int hf_mpls_echo_sub_tlv_addr_type = -1;
160 static int hf_mpls_echo_sub_tlv_fec_tlv_value = -1;
161 static int hf_mpls_echo_sub_tlv_res = -1;
162 static int hf_mpls_echo_sub_tlv_remote_peer_ip = -1;
163 static int hf_mpls_echo_sub_tlv_remore_peer_ipv6 = -1;
164 static int hf_mpls_echo_tlv_dd_map_type = -1;
165 static int hf_mpls_echo_tlv_dd_map_length = -1;
166 static int hf_mpls_echo_tlv_dd_map_value = -1;
167 static int hf_mpls_echo_tlv_padaction = -1;
168 static int hf_mpls_echo_tlv_padding = -1;
169 static int hf_mpls_echo_tlv_vendor = -1;
170 static int hf_mpls_echo_tlv_ilso_addr_type = -1;
171 static int hf_mpls_echo_tlv_ilso_mbz = -1;
172 static int hf_mpls_echo_tlv_ilso_ipv4_addr = -1;
173 static int hf_mpls_echo_tlv_ilso_ipv4_int_addr = -1;
174 static int hf_mpls_echo_tlv_ilso_ipv6_addr = -1;
175 static int hf_mpls_echo_tlv_ilso_ipv6_int_addr = -1;
176 static int hf_mpls_echo_tlv_ilso_int_index = -1;
177 static int hf_mpls_echo_tlv_ilso_label = -1;
178 static int hf_mpls_echo_tlv_ilso_exp = -1;
179 static int hf_mpls_echo_tlv_ilso_bos = -1;
180 static int hf_mpls_echo_tlv_ilso_ttl = -1;
181 #if 0
182 static int hf_mpls_echo_tlv_rto_ipv4 = -1;
183 static int hf_mpls_echo_tlv_rto_ipv6 = -1;
184 #endif
185 static int hf_mpls_echo_tlv_reply_tos = -1;
186 static int hf_mpls_echo_tlv_reply_tos_mbz = -1;
187 static int hf_mpls_echo_tlv_errored_type = -1;
188 static int hf_mpls_echo_tlv_ds_map_ingress_if_num = -1;
189 static int hf_mpls_echo_tlv_ds_map_egress_if_num = -1;
190 static int hf_mpls_echo_lspping_tlv_src_gid = -1;
191 static int hf_mpls_echo_lspping_tlv_src_nid = -1;
192 static int hf_mpls_echo_lspping_tlv_src_tunnel_no = -1;
193 static int hf_mpls_echo_lspping_tlv_lsp_no = -1;
194 static int hf_mpls_echo_lspping_tlv_dst_gid = -1;
195 static int hf_mpls_echo_lspping_tlv_dst_nid = -1;
196 static int hf_mpls_echo_lspping_tlv_dst_tunnel_no = -1;
197 static int hf_mpls_echo_lspping_tlv_resv = -1;
198 static int hf_mpls_echo_lspping_tlv_src_addr_gid = -1;
199 static int hf_mpls_echo_lspping_tlv_src_addr_nid=-1;
200 static int hf_mpls_echo_lspping_tlv_pw_serv_identifier = -1;
201 static int hf_mpls_echo_lspping_tlv_pw_src_ac_id = -1;
202 static int hf_mpls_echo_lspping_tlv_pw_dst_ac_id = -1;
203 /* static int hf_mpls_echo_lspping_tlv_pw_agi_type = -1; */
204 /* static int hf_mpls_echo_lspping_tlv_pw_agi_len = -1; */
205 /* static int hf_mpls_echo_lspping_tlv_pw_agi_val = -1; */
206 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id = -1;
207 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1 = -1;
208 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id = -1;
209 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id = -1;
210 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender = -1;
211 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2 = -1;
212 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id = -1;
213 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id = -1;
214 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id = -1;
215 static int hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender = -1;
216 static int hf_mpls_echo_tlv_echo_jitter = -1;
217 static int hf_mpls_echo_tlv_responder_indent_type = -1;
218 static int hf_mpls_echo_tlv_responder_indent_len = -1;
219 static int hf_mpls_echo_tlv_responder_indent_ipv4 = -1;
220 /* static int hf_mpls_echo_tlv_responder_indent_ipv6 = -1; */
221 static int hf_mpls_echo_tlv_bfd = -1;
223 static gint ett_mpls_echo = -1;
224 static gint ett_mpls_echo_gflags = -1;
225 static gint ett_mpls_echo_tlv = -1;
226 static gint ett_mpls_echo_tlv_fec = -1;
227 static gint ett_mpls_echo_tlv_ds_map = -1;
228 static gint ett_mpls_echo_tlv_ilso = -1;
229 static gint ett_mpls_echo_tlv_dd_map = -1;
230 static gint ett_mpls_echo_tlv_ddstlv_map = -1;
232 static expert_field ei_mpls_echo_tlv_fec_len = EI_INIT;
233 static expert_field ei_mpls_echo_tlv_dd_map_subtlv_len = EI_INIT;
234 static expert_field ei_mpls_echo_tlv_len = EI_INIT;
235 static expert_field ei_mpls_echo_tlv_ds_map_muti_len = EI_INIT;
236 static expert_field ei_mpls_echo_unknown_address_type = EI_INIT;
237 static expert_field ei_mpls_echo_incorrect_address_type = EI_INIT;
239 static guint global_mpls_echo_udp_port = UDP_PORT_MPLS_ECHO;
241 static const value_string mpls_echo_msgtype[] = {
242 {1, "MPLS Echo Request"},
243 {2, "MPLS Echo Reply"},
244 {3, "MPLS Data Plane Verification Request"},
245 {4, "MPLS Data Plane Verification Reply"},
246 {0, NULL}
249 static const value_string mpls_echo_replymode[] = {
250 {1, "Do not reply"},
251 {2, "Reply via an IPv4/IPv6 UDP packet"},
252 {3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
253 {4, "Reply via application level control channel"},
254 {0, NULL}
257 /* http://www.iana.org/assignments/mpls-lsp-ping-parameters/mpls-lsp-ping-parameters.xml */
258 static const value_string mpls_echo_returncode[] = {
259 { 0, "No return code"},
260 { 1, "Malformed echo request received"},
261 { 2, "One or more of the TLVs was not understood"},
262 { 3, "Replying router is an egress for the FEC at stack depth RSC"},
263 { 4, "Replying router has no mapping for the FEC at stack depth RSC"},
264 { 5, "Downstream Mapping Mismatch"}, /*[RFC4379] */
265 { 6, "Upstream Interface Index Unknown"}, /*[RFC4379]*/
266 { 7, "Reserved"},
267 { 8, "Label switched at stack-depth RSC"},
268 { 9, "Label switched but no MPLS forwarding at stack-depth RSC"},
269 {10, "Mapping for this FEC is not the given label at stack depth RSC"},
270 {11, "No label entry at stack-depth RSC"},
271 {12, "Protocol not associated with interface at FEC stack depth RSC"},
272 {13, "Premature termination, label stack shrinking to a single label"},
273 {14, "See DDM TLV for meaning of Return Code and Return SubCode"}, /* [RFC6424] */
274 {15, "Label switched with FEC change"}, /* [RFC6424] */
275 /* 16-251 Unassigned */
276 /* 252-255 Reserved for Vendor private use [RFC4379 */
277 {0, NULL}
279 static value_string_ext mpls_echo_returncode_ext = VALUE_STRING_EXT_INIT(mpls_echo_returncode);
281 #define TLV_TARGET_FEC_STACK 0x0001
282 #define TLV_DOWNSTREAM_MAPPING 0x0002
283 #define TLV_PAD 0x0003
284 #define TLV_ERROR_CODE 0x0004
285 #define TLV_VENDOR_CODE 0x0005
286 #define TLV_TBD 0x0006
287 #define TLV_ILSO_IPv4 0x0007
288 #define TLV_ILSO_IPv6 0x0008
289 #define TLV_ERRORED_TLV 0x0009
290 #define TLV_REPLY_TOS 0x000A
291 #if 0
292 #define TLV_RTO_IPv4 0x000B
293 #define TLV_RTO_IPv6 0x000C
294 #endif
295 #define TLV_P2MP_RESPONDER_IDENT 0x000B
296 #define TLV_P2MP_ECHO_JITTER 0x000C
297 /* As per RFC 6426 http://tools.ietf.org/html/rfc6426 Section: 2.2.1 */
298 #define TLV_SRC_IDENTIFIER 0x000D
299 #define TLV_DST_IDENTIFIER 0x000E
300 /* As per RFC 5884 http://tools.ietf.org/html/rfc5884 Section: 6.1 */
301 #define TLV_BFD_DISCRIMINATOR 0x000F
302 /* As per RFC 6426 http://tools.ietf.org/html/rfc6426 Section: 7.3 */
303 #define TLV_REVERSE_PATH_FEC_STACK 0x0010
304 #define TLV_DETAILED_DOWNSTREAM 0x0014 /* [RFC6424] */
305 #define TLV_VENDOR_PRIVATE_START 0xFC00
306 #define TLV_VENDOR_PRIVATE_END 0xFFFF
308 /* MPLS Echo TLV Type names */
309 static const value_string mpls_echo_tlv_type_names[] = {
310 { TLV_TARGET_FEC_STACK, "Target FEC Stack" },
311 { TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
312 { TLV_PAD, "Pad" },
313 { TLV_ERROR_CODE, "Error Code" },
314 { TLV_VENDOR_CODE, "Vendor Enterprise Code" },
315 { TLV_TBD, "TDB" },
316 { TLV_ILSO_IPv4, "IPv4 Interface and Label Stack Object" },
317 { TLV_ILSO_IPv6, "IPv6 Interface and Label Stack Object" },
318 { TLV_ERRORED_TLV, "Errored TLVs" },
319 { TLV_REPLY_TOS, "Reply TOS Byte" },
320 #if 0
321 { TLV_RTO_IPv4, "IPv4 Reply-to Object" },
322 { TLV_RTO_IPv6, "IPv6 Reply-to Object" },
323 #endif
324 { TLV_P2MP_RESPONDER_IDENT, "P2MP Responder Identifier" },
325 { TLV_P2MP_ECHO_JITTER, "P2MP Echo Jitter" },
326 { TLV_SRC_IDENTIFIER, "Source Identifier TLV" },
327 { TLV_DST_IDENTIFIER, "Destination Identifier TLV" },
328 { TLV_BFD_DISCRIMINATOR, "BFD Discriminator TLV" },
329 { TLV_REVERSE_PATH_FEC_STACK, "Reverse-path Target FEC Stack" },
330 { TLV_DETAILED_DOWNSTREAM, "Detailed Downstream Mapping"},
331 { TLV_VENDOR_PRIVATE_START, "Vendor Private" },
332 { 0, NULL}
334 static value_string_ext mpls_echo_tlv_type_names_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_type_names);
336 /*As per RFC 4379, http://tools.ietf.org/html/rfc4379 Section: 3.2 */
337 #define TLV_FEC_STACK_LDP_IPv4 1
338 #define TLV_FEC_STACK_LDP_IPv6 2
339 #define TLV_FEC_STACK_RSVP_IPv4 3
340 #define TLV_FEC_STACK_RSVP_IPv6 4
341 #define TLV_FEC_STACK_RES 5
342 #define TLV_FEC_STACK_VPN_IPv4 6
343 #define TLV_FEC_STACK_VPN_IPv6 7
344 #define TLV_FEC_STACK_L2_VPN 8
345 #define TLV_FEC_STACK_L2_CID_OLD 9
346 #define TLV_FEC_STACK_L2_CID_NEW 10
347 #define TLV_FEC_STACK_L2_FEC_129 11
348 #define TLV_FEC_STACK_BGP_LAB_v4 12
349 #define TLV_FEC_STACK_BGP_LAB_v6 13
350 #define TLV_FEC_STACK_GEN_IPv4 14
351 #define TLV_FEC_STACK_GEN_IPv6 15
352 #define TLV_FEC_STACK_NIL 16
353 /*As per RFC 6425, http://tools.ietf.org/html/rfc6425 Section: 3.1 */
354 #define TLV_FEC_STACK_P2MP_IPv4 17
355 #define TLV_FEC_STACK_P2MP_IPv6 18
356 /*As per RFC 6426, http://tools.ietf.org/html/rfc6426 Section: 2.3 */
357 #define TLV_FEC_STACK_STATIC_LSP 22
358 #define TLV_FEC_STACK_STATIC_PW 23
359 #define TLV_FEC_VENDOR_PRIVATE_START 0xFC00
360 #define TLV_FEC_VENDOR_PRIVATE_END 0xFFFF
362 /* FEC sub-TLV Type names */
363 static const value_string mpls_echo_tlv_fec_names[] = {
364 { TLV_FEC_STACK_LDP_IPv4, "LDP IPv4 prefix"},
365 { TLV_FEC_STACK_LDP_IPv6, "LDP IPv6 prefix"},
366 { TLV_FEC_STACK_RSVP_IPv4, "RSVP IPv4 Session Query"},
367 { TLV_FEC_STACK_RSVP_IPv6, "RSVP IPv6 Session Query"},
368 { TLV_FEC_STACK_RES, "Reserved"},
369 { TLV_FEC_STACK_VPN_IPv4, "VPN IPv4 prefix"},
370 { TLV_FEC_STACK_VPN_IPv6, "VPN IPv6 prefix"},
371 { TLV_FEC_STACK_L2_VPN, "L2 VPN endpoint"},
372 { TLV_FEC_STACK_L2_CID_OLD, "FEC 128 Pseudowire (old)"},
373 { TLV_FEC_STACK_L2_CID_NEW, "FEC 128 Pseudowire (new)"},
374 { TLV_FEC_STACK_L2_FEC_129, "FEC 129 Pseudowire"},
375 { TLV_FEC_STACK_BGP_LAB_v4, "BGP labeled IPv4 prefix"},
376 { TLV_FEC_STACK_BGP_LAB_v6, "BGP labeled IPv6 prefix"},
377 { TLV_FEC_STACK_GEN_IPv4, "Generic IPv4 prefix"},
378 { TLV_FEC_STACK_GEN_IPv6, "Generic IPv6 prefix"},
379 { TLV_FEC_STACK_NIL, "Nil FEC"},
380 { TLV_FEC_STACK_P2MP_IPv4, "RSVP P2MP IPv4 Session Query"},
381 { TLV_FEC_STACK_P2MP_IPv6, "RSVP P2MP IPv6 Session Query"},
382 { TLV_FEC_STACK_STATIC_LSP, "Static LSP"},
383 { TLV_FEC_STACK_STATIC_PW, "Static Pseudowire"},
384 { TLV_FEC_VENDOR_PRIVATE_START, "Vendor Private"},
385 { 0, NULL}
387 static value_string_ext mpls_echo_tlv_fec_names_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_fec_names);
389 /* [RFC 6424] */
390 #define TLV_FEC_MULTIPATH_DATA 1
391 #define TLV_FEC_LABEL_STACK 2
392 #define TLV_FEC_STACK_CHANGE 3
394 #if 0
395 static const value_string mpls_echo_subtlv_names[] = {
396 { TLV_FEC_MULTIPATH_DATA, "Multipath data"},
397 { TLV_FEC_LABEL_STACK, "Label stack"},
398 { TLV_FEC_STACK_CHANGE, "FEC stack change"},
399 { 0, NULL}
401 #endif
403 /* [RFC 6424] */
404 #define TLV_MULTIPATH_NO_MULTIPATH 0
405 #define TLV_MULTIPATH_IP_ADDRESS 2
406 #define TLV_MULTIPATH_IP_ADDRESS_RANGE 4
407 #define TLV_MULTIPATH_BIT_MASKED_IP 8
408 #define TLV_MULTIPATH_BIT_MASKED_LABEL_SET 9
410 #if 0
411 static const value_string mpls_echo_multipathtlv_type[] = {
412 { TLV_MULTIPATH_NO_MULTIPATH, "Empty (Multipath Length = 0)"},
413 { TLV_MULTIPATH_IP_ADDRESS, "IP addresses"},
414 { TLV_MULTIPATH_IP_ADDRESS_RANGE, "low/high address pairs"},
415 { TLV_MULTIPATH_BIT_MASKED_IP, "IP address prefix and bit mask"},
416 { TLV_MULTIPATH_BIT_MASKED_LABEL_SET, "Label prefix and bit mask"},
417 { 0, NULL}
419 #endif
421 /* [RFC 6424] */
422 #define SUB_TLV_FEC_PUSH 1
423 #define SUB_TLV_FEC_POP 2
425 const value_string mpls_echo_subtlv_op_types[] = {
426 { SUB_TLV_FEC_PUSH, "Push"},
427 { SUB_TLV_FEC_POP, "Pop"},
428 { 0, NULL}
431 /* [RFC 6424] */
432 #define SUB_TLV_FEC_UNSPECIFIED 0
433 #define SUB_TLV_FEC_IPV4 1
434 #define SUB_TLV_FEC_IPV6 2
436 const value_string mpls_echo_subtlv_addr_types[] = {
437 { SUB_TLV_FEC_UNSPECIFIED, "Unspecified"},
438 { SUB_TLV_FEC_IPV4, "IPv4"},
439 { SUB_TLV_FEC_IPV6, "IPv6"},
440 { 0, NULL}
443 static const value_string mpls_echo_tlv_pad[] = {
444 { 1, "Drop Pad TLV from reply" },
445 { 2, "Copy Pad TLV to reply" },
446 { 0, NULL}
449 /* [RFC 6425] */
450 #define TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR 1
451 #define TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR 2
452 #define TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR 3
453 #define TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR 4
454 static const value_string mpls_echo_tlv_responder_ident_sub_tlv_type[] = {
455 { TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR, "IPv4 Egress Address P2MP Responder Identifier"},
456 { TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR, "IPv6 Egress Address P2MP Responder Identifier"},
457 { TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR, "IPv4 Node Address P2MP Responder Identifier"},
458 { TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR, "IPv6 Node Address P2MP Responder Identifier"},
459 {0, NULL}
462 #define TLV_ADDR_IPv4 1
463 #define TLV_ADDR_UNNUM_IPv4 2
464 #define TLV_ADDR_IPv6 3
465 #define TLV_ADDR_UNNUM_IPv6 4
466 /* As per RFC 6426, http://tools.ietf.org/html/rfc6426 Section: 2.1 */
467 #define TLV_ADDR_NONIP 5
469 static const value_string mpls_echo_tlv_addr_type[] = {
470 {TLV_ADDR_IPv4, "IPv4 Numbered"},
471 {TLV_ADDR_UNNUM_IPv4, "IPv4 Unnumbered"},
472 {TLV_ADDR_IPv6, "IPv6 Numbered"},
473 {TLV_ADDR_UNNUM_IPv6, "IPv6 Unnumbered"},
474 {TLV_ADDR_NONIP, "Non IP"},
475 {0, NULL}
478 #define TLV_DS_MAP_HASH_NO_MP 0
479 #define TLV_DS_MAP_HASH_LABEL 1
480 #define TLV_DS_MAP_HASH_IP 2
481 #define TLV_DS_MAP_HASH_LABEL_RANGE 3
482 #define TLV_DS_MAP_HASH_IP_RANGE 4
483 #define TLV_DS_MAP_HASH_NO_LABEL 5
484 #define TLV_DS_MAP_HASH_ALL_IP 6
485 #define TLV_DS_MAP_HASH_NO_MATCH 7
486 #define TLV_DS_MAP_HASH_BITMASK_IP 8
487 #define TLV_DS_MAP_HASH_BITMASK_LABEL 9
489 static const value_string mpls_echo_tlv_ds_map_hash_type[] = {
490 {TLV_DS_MAP_HASH_NO_MP, "no multipath"},
491 {TLV_DS_MAP_HASH_LABEL, "label"},
492 {TLV_DS_MAP_HASH_IP, "IP address"},
493 {TLV_DS_MAP_HASH_LABEL_RANGE, "label range"},
494 {TLV_DS_MAP_HASH_IP_RANGE, "IP address range"},
495 {TLV_DS_MAP_HASH_NO_LABEL, "no more labels"},
496 {TLV_DS_MAP_HASH_ALL_IP, "All IP addresses"},
497 {TLV_DS_MAP_HASH_NO_MATCH, "no match"},
498 {TLV_DS_MAP_HASH_BITMASK_IP, "Bit-masked IPv4 address set"},
499 {TLV_DS_MAP_HASH_BITMASK_LABEL, "Bit-masked label set"},
500 {0, NULL}
502 static value_string_ext mpls_echo_tlv_ds_map_hash_type_ext = VALUE_STRING_EXT_INIT(mpls_echo_tlv_ds_map_hash_type);
504 static const value_string mpls_echo_tlv_ds_map_mp_proto[] = {
505 {0, "Unknown"},
506 {1, "Static"},
507 {2, "BGP"},
508 {3, "LDP"},
509 {4, "RSVP-TE"},
510 {5, "Reserved"},
511 {0, NULL}
515 * Dissector for FEC sub-TLVs
517 static void
518 dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
520 proto_tree *ti, *tlv_fec_tree;
521 proto_item *hidden_item;
522 guint16 idx = 1, nil_idx = 1, type, saved_type;
523 int length, nil_length, pad;
524 guint32 label;
525 guint8 exp, bos, ttl;
527 while (rem >= 4) { /* Type, Length */
528 type = tvb_get_ntohs(tvb, offset);
529 saved_type = type;
530 /* Check for Vendor Private sub-TLVs */
531 if (type >= TLV_FEC_VENDOR_PRIVATE_START) /* && <= TLV_FEC_VENDOR_PRIVATE_END always true */
532 type = TLV_FEC_VENDOR_PRIVATE_START;
534 length = tvb_get_ntohs(tvb, offset + 2);
536 ti = NULL;
537 tlv_fec_tree = NULL;
539 if (tree) {
540 ti = proto_tree_add_text(tree, tvb, offset, length + 4 + (4-(length%4)), "FEC Element %u: %s",
541 idx, val_to_str_ext(type, &mpls_echo_tlv_fec_names_ext,
542 "Unknown FEC type (0x%04X)"));
543 tlv_fec_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_fec);
545 /* FEC sub-TLV Type and Length */
546 proto_tree_add_uint_format_value(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb,
547 offset, 2, saved_type, "%s (%u)",
548 val_to_str_ext_const(type, &mpls_echo_tlv_fec_names_ext,
549 "Unknown sub-TLV type"), saved_type);
551 ti = proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_len, tvb, offset + 2,
552 2, ENC_BIG_ENDIAN);
555 if (length + 4 > rem) {
556 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
557 "Invalid FEC Sub-TLV Length (claimed %u, found %u)",
558 length, rem - 4);
559 return;
562 /* FEC sub-TLV Value */
563 switch (type) {
564 case TLV_FEC_STACK_LDP_IPv4:
565 if (tree) {
566 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4,
567 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
568 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
569 tvb, offset + 8, 1, ENC_BIG_ENDIAN);
571 break;
572 case TLV_FEC_STACK_LDP_IPv6:
573 if (tree) {
574 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6,
575 tvb, offset + 4, 16, ENC_NA);
576 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
577 tvb, offset + 20, 1, ENC_BIG_ENDIAN);
579 break;
580 case TLV_FEC_STACK_RSVP_IPv4:
581 if (length != 20) {
582 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
583 "Invalid FEC Sub-TLV Length "
584 "(claimed %u, should be %u)",
585 length, 20);
586 return;
588 if (tree) {
589 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
590 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
591 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
592 tvb, offset + 8, 2, ENC_BIG_ENDIAN);
593 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
594 tvb, offset + 10, 2, ENC_BIG_ENDIAN);
595 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
596 tvb, offset + 12, 4, ENC_BIG_ENDIAN);
597 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
598 tvb, offset + 16, 4, ENC_BIG_ENDIAN);
599 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
600 tvb, offset + 20, 2, ENC_BIG_ENDIAN);
601 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
602 tvb, offset + 22, 2, ENC_BIG_ENDIAN);
604 break;
605 case TLV_FEC_STACK_RSVP_IPv6:
606 if (length != 56) {
607 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
608 "Invalid FEC Sub-TLV Length "
609 "(claimed %u, should be %u)",
610 length, 56);
611 return;
613 if (tree) {
614 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
615 tvb, offset + 4, 16, ENC_NA);
616 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
617 tvb, offset + 20, 2, ENC_BIG_ENDIAN);
618 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
619 tvb, offset + 22, 2, ENC_BIG_ENDIAN);
620 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
621 tvb, offset + 24, 16, ENC_NA);
622 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
623 tvb, offset + 40, 16, ENC_NA);
624 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
625 tvb, offset + 56, 2, ENC_BIG_ENDIAN);
626 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
627 tvb, offset + 58, 2, ENC_BIG_ENDIAN);
629 break;
630 case TLV_FEC_STACK_VPN_IPv4:
631 if (tree) {
632 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_route_dist,
633 tvb, offset + 4, 8, ENC_NA);
634 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_ipv4,
635 tvb, offset + 12, 4, ENC_BIG_ENDIAN);
636 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_len,
637 tvb, offset + 16, 1, ENC_BIG_ENDIAN);
639 break;
640 case TLV_FEC_STACK_VPN_IPv6:
641 if (tree) {
642 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_route_dist,
643 tvb, offset + 4, 8, ENC_NA);
644 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_ipv6,
645 tvb, offset + 12, 16, ENC_NA);
646 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_vpn_len,
647 tvb, offset + 28, 1, ENC_BIG_ENDIAN);
649 break;
650 case TLV_FEC_STACK_L2_VPN:
651 if (tree) {
652 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_route_dist,
653 tvb, offset + 4, 8, ENC_NA);
654 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id,
655 tvb, offset + 12, 2, ENC_BIG_ENDIAN);
656 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id,
657 tvb, offset + 14, 2, ENC_BIG_ENDIAN);
658 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2_vpn_encap_type,
659 tvb, offset + 16, 2, ENC_BIG_ENDIAN);
661 break;
662 case TLV_FEC_STACK_L2_CID_OLD:
663 if (tree) {
664 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
665 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
666 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
667 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
668 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
669 tvb, offset + 12, 2, ENC_BIG_ENDIAN);
670 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
671 tvb, offset + 14, 2, ENC_BIG_ENDIAN);
673 break;
674 case TLV_FEC_STACK_L2_CID_NEW:
675 if (length < 14) {
676 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
677 "Invalid FEC Sub-TLV Length "
678 "(claimed %u, should be %u)",
679 length, 14);
680 return;
682 if (tree) {
683 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_sender,
684 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
685 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
686 tvb, offset + 8, 4, ENC_BIG_ENDIAN);
687 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
688 tvb, offset + 12, 4, ENC_BIG_ENDIAN);
689 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
690 tvb, offset + 16, 2, ENC_BIG_ENDIAN);
691 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
692 tvb, offset + 18, 2, ENC_BIG_ENDIAN);
694 break;
695 case TLV_FEC_VENDOR_PRIVATE_START:
696 if (length < 4) { /* SMI Enterprise code */
697 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
698 "Invalid FEC Sub-TLV Length "
699 "(claimed %u, should be >= %u)",
700 length, 4);
701 } else {
702 if (tree) {
703 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_vendor, tvb,
704 offset + 4, 4, ENC_BIG_ENDIAN);
705 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_value, tvb,
706 offset + 8, length - 4, ENC_NA);
709 break;
710 case TLV_FEC_STACK_BGP_LAB_v4:
711 if (tree) {
712 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv4,
713 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
714 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
715 tvb, offset + 8, 1, ENC_BIG_ENDIAN);
717 break;
718 case TLV_FEC_STACK_BGP_LAB_v6:
719 if (tree) {
720 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv6,
721 tvb, offset + 4, 16, ENC_NA);
722 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
723 tvb, offset + 20, 1, ENC_BIG_ENDIAN);
725 break;
726 case TLV_FEC_STACK_GEN_IPv4:
727 if (tree) {
728 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4,
729 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
730 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4_mask,
731 tvb, offset + 8, 1, ENC_BIG_ENDIAN);
733 break;
734 case TLV_FEC_STACK_GEN_IPv6:
735 if (tree) {
736 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6,
737 tvb, offset + 4, 16, ENC_NA);
738 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6_mask,
739 tvb, offset + 20, 1, ENC_BIG_ENDIAN);
741 break;
742 case TLV_FEC_STACK_NIL:
743 nil_length = length;
744 while (nil_length >= 4) {
745 decode_mpls_label(tvb, offset + 4, &label, &exp, &bos, &ttl);
746 if (label <= MPLS_LABEL_MAX_RESERVED) {
747 proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
748 tvb, offset + 4, 3, label, "Label %u: %u (%s)", nil_idx, label,
749 val_to_str_const(label, special_labels, "Reserved - Unknown"));
750 } else {
751 proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
752 tvb, offset + 4, 3, label, "Label %u: %u", nil_idx, label);
754 nil_length -= 4;
755 offset += 4;
756 nil_idx++;
758 break;
759 case TLV_FEC_STACK_P2MP_IPv4:
760 if (length != 20) {
761 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
762 "Invalid FEC Sub-TLV Length "
763 "(claimed %u, should be %u)",
764 length, 20);
765 return;
767 if (tree) {
768 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id,
769 tvb, offset + 4, 4, FALSE);
770 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
771 tvb, offset + 8, 2, FALSE);
772 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
773 tvb, offset + 10, 2, FALSE);
774 proto_tree_add_text(tlv_fec_tree, tvb, offset + 12, 4,
775 "Extended Tunnel ID: 0x%08X (%s)", tvb_get_ntohl(tvb, offset + 12),
776 tvb_ip_to_str(tvb, offset + 12));
777 hidden_item = proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id,
778 tvb, offset + 12, 4, FALSE);
779 PROTO_ITEM_SET_HIDDEN(hidden_item);
780 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender,
781 tvb, offset + 16, 4, FALSE);
782 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2,
783 tvb, offset + 20, 2, FALSE);
784 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
785 tvb, offset + 22, 2, FALSE);
787 break;
789 case TLV_FEC_STACK_P2MP_IPv6:
790 if (length != 56) {
791 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
792 "Invalid FEC Sub-TLV Length "
793 "(claimed %u, should be %u)",
794 length, 56);
795 return;
797 if (tree) {
798 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id,
799 tvb, offset + 4, 16, FALSE);
800 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
801 tvb, offset + 20, 2, FALSE);
802 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
803 tvb, offset + 22, 2, FALSE);
804 proto_tree_add_text(tlv_fec_tree, tvb, offset + 24, 16, "Extended Tunnel ID: 0x%s (%s)",
805 tvb_bytes_to_str(tvb, offset + 24, 16),
806 tvb_ip6_to_str(tvb, offset + 24));
807 hidden_item = proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id,
808 tvb, offset + 24, 16, FALSE);
809 PROTO_ITEM_SET_HIDDEN(hidden_item);
810 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender,
811 tvb, offset + 40, 16, FALSE);
812 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
813 tvb, offset + 56, 2, FALSE);
814 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
815 tvb, offset + 58, 2, FALSE);
817 break;
818 case TLV_FEC_STACK_STATIC_LSP:
819 if (tree) {
820 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_gid,
821 tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
822 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_nid,
823 tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
824 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_tunnel_no,
825 tvb, (offset + 12), 2, ENC_BIG_ENDIAN);
826 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_lsp_no,
827 tvb, (offset + 14), 2, ENC_BIG_ENDIAN);
828 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_gid,
829 tvb, (offset + 16), 4, ENC_BIG_ENDIAN);
830 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_nid,
831 tvb, (offset + 20), 4, ENC_BIG_ENDIAN);
832 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_tunnel_no,
833 tvb, (offset + 24), 2, ENC_BIG_ENDIAN);
834 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_resv,
835 tvb, (offset + 26), 2, ENC_BIG_ENDIAN);
837 break;
838 case TLV_FEC_STACK_STATIC_PW:
839 if (tree) {
840 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_serv_identifier,
841 tvb, (offset + 4), 8, ENC_BIG_ENDIAN);
842 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_gid,
843 tvb, (offset + 12), 4, ENC_BIG_ENDIAN);
844 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_src_nid,
845 tvb, (offset + 16), 4, ENC_BIG_ENDIAN);
846 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_src_ac_id,
847 tvb, (offset + 20), 4, ENC_BIG_ENDIAN);
848 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_gid,
849 tvb, (offset + 24), 4, ENC_BIG_ENDIAN);
850 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_dst_nid,
851 tvb, (offset + 28), 4, ENC_BIG_ENDIAN);
852 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_lspping_tlv_pw_dst_ac_id,
853 tvb, (offset + 32), 4, ENC_BIG_ENDIAN);
855 break;
856 case TLV_FEC_STACK_RES:
857 default:
858 if (length)
859 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value,
860 tvb, offset + 4, length, ENC_NA);
861 break;
865 * Check for padding based on sub-TLV length alignment;
866 * FEC sub-TLVs is zero-padded to align to four-octet boundary.
868 if (length % 4) {
869 pad = 4 - (length % 4);
870 if (length + 4 + pad > rem) {
871 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_fec_len,
872 "Invalid FEC Sub-TLV Padded Length (claimed %u, found %u)",
873 length + pad, rem - 4);
874 return;
875 } else {
876 proto_tree_add_text(tlv_fec_tree, tvb, offset + 4 + length, pad, "Padding");
878 length += pad;
881 rem -= 4 + length;
882 offset += 4 + length;
883 idx++;
889 * Dissector for Downstream Mapping TLV
891 static void
892 dissect_mpls_echo_tlv_ds_map(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
894 proto_tree *ti, *tlv_ds_map_tree;
895 proto_tree *addr_ti;
896 guint16 mplen, idx = 1;
897 guint32 label;
898 guint8 exp, bos, proto;
899 guint8 hash_type, addr_type;
901 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mtu, tvb,
902 offset, 2, ENC_BIG_ENDIAN);
903 addr_ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_addr_type, tvb,
904 offset + 2, 1, ENC_BIG_ENDIAN);
905 ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_res, tvb,
906 offset + 3, 1, ENC_BIG_ENDIAN);
907 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
909 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_res, tvb,
910 offset + 3, 1, ENC_BIG_ENDIAN);
911 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_i, tvb,
912 offset + 3, 1, ENC_BIG_ENDIAN);
913 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_n, tvb,
914 offset + 3, 1, ENC_BIG_ENDIAN);
916 addr_type = tvb_get_guint8(tvb, offset + 2);
917 switch (addr_type) {
918 case TLV_ADDR_IPv4:
919 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
920 offset + 4, 4, ENC_BIG_ENDIAN);
921 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ip, tvb,
922 offset + 8, 4, ENC_BIG_ENDIAN);
923 break;
924 case TLV_ADDR_UNNUM_IPv4:
925 case TLV_ADDR_UNNUM_IPv6:
926 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
927 offset + 4, 4, ENC_BIG_ENDIAN);
928 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_if_index, tvb,
929 offset + 8, 4, ENC_BIG_ENDIAN);
930 break;
931 case TLV_ADDR_IPv6:
932 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ipv6, tvb,
933 offset + 4, 16, ENC_NA);
934 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ipv6, tvb,
935 offset + 20, 16, ENC_NA);
936 rem -= 24;
937 offset += 24;
938 break;
939 case TLV_ADDR_NONIP :
940 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ingress_if_num, tvb,
941 (offset + 4), 4, ENC_BIG_ENDIAN);
942 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_egress_if_num, tvb,
943 (offset + 8), 4, ENC_BIG_ENDIAN);
944 break;
945 default:
946 expert_add_info_format(pinfo, addr_ti, &ei_mpls_echo_unknown_address_type,
947 "Unknown Address Type (%u)", addr_type);
948 break;
950 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_hash_type, tvb,
951 offset + 12, 1, ENC_BIG_ENDIAN);
952 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_depth, tvb,
953 offset + 13, 1, ENC_BIG_ENDIAN);
954 ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_muti_len, tvb,
955 offset + 14, 2, ENC_BIG_ENDIAN);
957 /* Get the Multipath Length and Hash Type */
958 mplen = tvb_get_ntohs(tvb, offset + 14);
959 hash_type = tvb_get_guint8(tvb, offset + 12);
961 rem -= 16;
962 offset += 16;
963 if (rem < mplen) {
964 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
965 "Invalid FEC Multipath (claimed %u, found %u)",
966 mplen, rem);
967 return;
969 rem -= mplen;
970 if (mplen) {
971 switch (hash_type) {
972 case TLV_DS_MAP_HASH_IP:
973 if (mplen != 4) {
974 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
975 "Invalid FEC Multipath (claimed %u, should be 4)",
976 mplen);
977 break;
979 ti = proto_tree_add_text(tree, tvb, offset, 4,
980 "Multipath Information");
981 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
982 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
983 offset, 4, ENC_BIG_ENDIAN);
984 break;
985 case TLV_DS_MAP_HASH_IP_RANGE:
986 if (mplen != 8) {
987 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
988 "Invalid FEC Multipath (claimed %u, should be 8)",
989 mplen);
990 break;
992 ti = proto_tree_add_text(tree, tvb, offset, 8,
993 "Multipath Information");
994 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
995 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_low, tvb,
996 offset, 4, ENC_BIG_ENDIAN);
997 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_high, tvb,
998 offset + 4, 4, ENC_BIG_ENDIAN);
999 break;
1000 case TLV_DS_MAP_HASH_NO_MP:
1001 case TLV_DS_MAP_HASH_NO_LABEL:
1002 case TLV_DS_MAP_HASH_ALL_IP:
1003 case TLV_DS_MAP_HASH_NO_MATCH:
1004 proto_tree_add_text(tree, tvb, offset, mplen,
1005 "No Multipath Information");
1006 break;
1007 case TLV_DS_MAP_HASH_BITMASK_IP:
1008 if (mplen < 4) {
1009 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_ds_map_muti_len,
1010 "Invalid FEC Multipath (claimed %u, should be 4)",
1011 mplen);
1012 break;
1014 ti = proto_tree_add_text(tree, tvb, offset, mplen,
1015 "Multipath Information");
1016 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
1017 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
1018 offset, 4, ENC_BIG_ENDIAN);
1019 if (mplen > 4)
1020 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_mask, tvb,
1021 offset + 4, mplen - 4, ENC_NA);
1022 break;
1023 default:
1024 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mp_value, tvb,
1025 offset, mplen, ENC_NA);
1026 break;
1030 offset += mplen;
1032 if (tree) {
1033 while (rem >= 4) {
1034 decode_mpls_label(tvb, offset, &label, &exp, &bos, &proto);
1035 ti = proto_tree_add_text(tree, tvb, offset, 4, "Downstream Label Element %u", idx);
1036 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
1037 proto_item_append_text(ti, ", Label: %u", label);
1038 if (label <= MPLS_LABEL_MAX_RESERVED) {
1039 proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
1040 tvb, offset, 3, label);
1041 proto_item_append_text(ti, " (%s)", val_to_str_const(label, special_labels,
1042 "Reserved - Unknown"));
1043 } else {
1044 proto_tree_add_uint_format_value(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
1045 tvb, offset, 3, label, "%u", label);
1047 proto_item_append_text(ti, ", Exp: %u, BOS: %u", exp, bos);
1048 proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_exp,
1049 tvb, offset + 2, 1, exp);
1050 proto_tree_add_uint(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_bos,
1051 tvb, offset + 2, 1, bos);
1052 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_proto,
1053 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1054 proto_item_append_text(ti, ", Protocol: %u (%s)", proto,
1055 val_to_str_const(proto, mpls_echo_tlv_ds_map_mp_proto, "Unknown"));
1056 rem -= 4;
1057 offset += 4;
1058 idx++;
1063 /* Dissector for Detailed Downstream Mapping TLV - RFC [6424] */
1064 static void
1065 dissect_mpls_echo_tlv_dd_map(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
1067 proto_tree *ddti = NULL, *tlv_dd_map_tree, *tlv_ddstlv_map_tree;
1068 proto_tree *ddsti, *ddsti2;
1069 guint16 subtlv_length, subtlv_type, multipath_length;
1070 guint8 addr_type, multipath_type, fec_tlv_length;
1071 guint16 idx = 1;
1072 guint32 label;
1073 guint8 tc, s_bit, proto;
1075 if (tree) {
1076 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_mtu, tvb,
1077 offset, 2, ENC_BIG_ENDIAN);
1078 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_addr_type, tvb,
1079 offset + 2, 1, ENC_BIG_ENDIAN);
1080 ddti = proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_res, tvb,
1081 offset + 3, 1, ENC_BIG_ENDIAN);
1082 tlv_dd_map_tree = proto_item_add_subtree(ddti, ett_mpls_echo_tlv_dd_map);
1084 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_res, tvb,
1085 offset + 3, 1, ENC_BIG_ENDIAN);
1086 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_i, tvb,
1087 offset + 3, 1, ENC_BIG_ENDIAN);
1088 ddti = proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_flag_n, tvb,
1089 offset + 3, 1, ENC_BIG_ENDIAN);
1091 addr_type = tvb_get_guint8(tvb, offset + 2);
1092 switch (addr_type) {
1093 case TLV_ADDR_IPv4:
1094 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_ds_ip, tvb,
1095 offset + 4, 4, ENC_BIG_ENDIAN);
1096 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_int_ip, tvb,
1097 offset + 8, 4, ENC_BIG_ENDIAN);
1098 break;
1099 case TLV_ADDR_IPv6:
1100 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_ds_ipv6, tvb,
1101 offset + 4, 16, ENC_NA);
1102 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_int_ipv6, tvb,
1103 offset + 20, 16, ENC_NA);
1104 rem -= 24;
1105 offset += 24;
1106 break;
1107 case TLV_ADDR_NONIP :
1108 proto_tree_add_item (tree, hf_mpls_echo_tlv_dd_map_ingress_if_num, tvb,
1109 (offset + 4), 4, ENC_BIG_ENDIAN);
1110 proto_tree_add_item (tree, hf_mpls_echo_tlv_dd_map_egress_if_num, tvb,
1111 (offset + 8), 4, ENC_BIG_ENDIAN);
1112 break;
1113 default:
1114 expert_add_info_format(pinfo, ddti, &ei_mpls_echo_unknown_address_type,
1115 "Unknown Address Type (%u)", addr_type);
1116 break;
1119 if (tree) {
1120 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_return_code, tvb,
1121 offset + 12, 1, ENC_BIG_ENDIAN);
1122 proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_return_subcode, tvb,
1123 offset + 13, 1, ENC_BIG_ENDIAN);
1124 ddti = proto_tree_add_item(tree, hf_mpls_echo_tlv_dd_map_subtlv_len, tvb,
1125 offset + 14, 2, ENC_BIG_ENDIAN);
1128 rem -= 16;
1129 offset += 16;
1131 while (rem > 4) {
1132 /* Get the Sub-tlv Type and Length */
1133 subtlv_type = tvb_get_ntohs(tvb, offset);
1134 subtlv_length = tvb_get_ntohs(tvb, offset+2);
1135 rem -= 4;
1136 offset += 4;
1138 if (rem<subtlv_length){
1139 expert_add_info_format(pinfo, ddti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1140 "Invalid Sub-tlv Length (claimed %u, found %u)",
1141 subtlv_length, rem);
1142 return;
1145 switch (subtlv_type) {
1146 case TLV_FEC_MULTIPATH_DATA:
1147 multipath_type = tvb_get_guint8(tvb, offset);
1148 multipath_length = tvb_get_ntohs(tvb, offset + 1);
1149 ddsti = proto_tree_add_text(tree, tvb, offset - 4, multipath_length + 8,
1150 "Multipath sub-TLV");
1151 tlv_dd_map_tree = proto_item_add_subtree(ddsti, ett_mpls_echo_tlv_dd_map);
1153 switch (multipath_type) {
1154 case TLV_MULTIPATH_NO_MULTIPATH:
1155 if (!tree)
1156 break;
1157 proto_tree_add_item(tlv_dd_map_tree,
1158 hf_mpls_echo_sub_tlv_multipath_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1159 proto_tree_add_item(tlv_dd_map_tree,
1160 hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1161 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1162 offset + 3, 1, ENC_BIG_ENDIAN);
1163 ddsti2 = proto_tree_add_text(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1164 "Empty (Multipath Length = 0)");
1165 tlv_ddstlv_map_tree = proto_item_add_subtree(ddsti2, ett_mpls_echo_tlv_ddstlv_map);
1166 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_info,
1167 tvb, offset + 4, multipath_length, ENC_BIG_ENDIAN);
1168 break;
1170 case TLV_MULTIPATH_IP_ADDRESS:
1171 if (multipath_length != 4) {
1172 expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1173 "Invalid Sub-tlv Length (claimed %u, should be 4)",
1174 multipath_length);
1175 break;
1177 if (!tree)
1178 break;
1179 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1180 offset, 1, ENC_BIG_ENDIAN);
1181 proto_tree_add_item(tlv_dd_map_tree,
1182 hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1183 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1184 offset + 3, 1, ENC_BIG_ENDIAN);
1186 ddsti2 = proto_tree_add_text(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1187 "Multipath Information (IP addresses)");
1188 tlv_ddstlv_map_tree = proto_item_add_subtree(ddsti2, ett_mpls_echo_tlv_ddstlv_map);
1190 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_ip, tvb,
1191 offset + 4, 4, ENC_BIG_ENDIAN);
1192 break;
1194 case TLV_MULTIPATH_IP_ADDRESS_RANGE:
1195 if (multipath_length != 8) {
1196 expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1197 "Invalid Sub-tlv Length (claimed %u, should be 8)",
1198 multipath_length);
1199 break;
1201 if (!tree)
1202 break;
1203 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1204 offset, 1, ENC_BIG_ENDIAN);
1205 proto_tree_add_item(tlv_dd_map_tree,
1206 hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1207 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1208 offset + 3, 1, ENC_BIG_ENDIAN);
1210 ddsti2 = proto_tree_add_text(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1211 "Multipath Information (low/high address pairs)");
1212 tlv_ddstlv_map_tree = proto_item_add_subtree(ddsti2, ett_mpls_echo_tlv_ddstlv_map);
1214 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_ip_low, tvb,
1215 offset + 4, 4, ENC_BIG_ENDIAN);
1216 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_ip_high, tvb,
1217 offset + 8, 4, ENC_BIG_ENDIAN);
1218 break;
1220 case TLV_MULTIPATH_BIT_MASKED_IP:
1221 if (multipath_length < 4) {
1222 expert_add_info_format(pinfo, ddsti, &ei_mpls_echo_tlv_dd_map_subtlv_len,
1223 "Invalid Sub-tlv Length (claimed %u, should be >= 4)",
1224 multipath_length);
1225 break;
1227 if (!tree)
1228 break;
1229 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1230 offset, 1, ENC_BIG_ENDIAN);
1231 proto_tree_add_item(tlv_dd_map_tree,
1232 hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1233 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_resv, tvb,
1234 offset + 3, 1, ENC_BIG_ENDIAN);
1236 ddsti2 = proto_tree_add_text(tlv_dd_map_tree, tvb, offset + 4, multipath_length,
1237 "Multipath Information (IP address prefix and bit mask)");
1238 tlv_ddstlv_map_tree = proto_item_add_subtree(ddsti2, ett_mpls_echo_tlv_ddstlv_map);
1240 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_multipath_ip, tvb,
1241 offset + 4, 4, ENC_BIG_ENDIAN);
1242 if (multipath_length > 4)
1243 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_sub_tlv_mp_mask,
1244 tvb, offset + 8, multipath_length - 4, ENC_NA);
1245 break;
1247 case TLV_MULTIPATH_BIT_MASKED_LABEL_SET:
1248 proto_tree_add_text(tlv_dd_map_tree, tvb, offset, 1,
1249 "Multipath Information (Label prefix and bit mask)");
1250 break;
1252 default:
1253 if (!tree)
1254 break;
1255 proto_tree_add_text(tlv_dd_map_tree, tvb, offset, 1,
1256 "Multipath Type not identified (%u)", multipath_type);
1257 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_type, tvb,
1258 offset, 1, ENC_BIG_ENDIAN);
1259 proto_tree_add_item(tlv_dd_map_tree,
1260 hf_mpls_echo_sub_tlv_multipath_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
1261 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_multipath_value, tvb,
1262 offset + 3, rem, ENC_BIG_ENDIAN);
1263 break;
1266 rem -= (multipath_length + 4);
1267 break;
1269 case TLV_FEC_LABEL_STACK:
1270 ddsti = proto_tree_add_text(tree, tvb, offset - 4, subtlv_length + 4, "Label stack sub-TLV");
1271 tlv_dd_map_tree = proto_item_add_subtree(ddsti, ett_mpls_echo_tlv_dd_map);
1273 while (rem >= 4) {
1274 if (tree) {
1275 decode_mpls_label(tvb, offset, &label, &tc, &s_bit, &proto);
1277 ddsti2 = proto_tree_add_text(tlv_dd_map_tree,
1278 tvb, offset, 4, "Downstream Label Element %u", idx);
1279 tlv_ddstlv_map_tree = proto_item_add_subtree(ddsti2, ett_mpls_echo_tlv_ddstlv_map);
1280 proto_item_append_text(ddsti2, ", Label: %u , Protocol: %u", label, proto);
1281 proto_tree_add_text(tlv_ddstlv_map_tree, tvb, offset, 3, "Label: %u", label);
1282 proto_tree_add_text(tlv_ddstlv_map_tree, tvb, offset + 2, 1, "Traffic Class: %u", tc);
1283 proto_tree_add_text(tlv_ddstlv_map_tree, tvb, offset + 2, 1, "S bit: %u", s_bit);
1284 proto_tree_add_item(tlv_ddstlv_map_tree, hf_mpls_echo_tlv_ddstlv_map_mp_proto,
1285 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1287 rem -= 4;
1288 offset += 4;
1289 idx++;
1291 break;
1293 case TLV_FEC_STACK_CHANGE: {
1294 addr_type = tvb_get_guint8(tvb, offset + 1);
1295 fec_tlv_length = tvb_get_guint8(tvb, offset + 2);
1296 ddsti = proto_tree_add_text(tree, tvb, offset - 4, fec_tlv_length + 12, "Stack change sub-TLV");
1297 tlv_dd_map_tree = proto_item_add_subtree(ddsti, ett_mpls_echo_tlv_dd_map);
1299 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_op_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1300 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_addr_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
1301 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_fec_tlv_value, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
1302 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_res, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1303 switch (addr_type) {
1304 case SUB_TLV_FEC_UNSPECIFIED:
1305 proto_tree_add_text(tlv_dd_map_tree, tvb, offset + 4, 0, "Unspecified (Address Length = 0)");
1306 rem += 4;
1307 offset -= 4;
1308 break;
1309 case SUB_TLV_FEC_IPV4:
1310 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_remote_peer_ip, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1311 break;
1312 case SUB_TLV_FEC_IPV6:
1313 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_sub_tlv_remore_peer_ipv6, tvb, offset + 4, 16, ENC_NA);
1314 rem -= 12;
1315 offset += 12;
1316 break;
1319 offset -= 8;
1320 dissect_mpls_echo_tlv_fec(tvb, pinfo, offset, tlv_dd_map_tree, fec_tlv_length);
1322 rem -= (fec_tlv_length + 8);
1323 break;
1326 default:
1327 ddsti = proto_tree_add_text(tree, tvb, offset, subtlv_length, "Error processing sub-TLV");
1328 tlv_dd_map_tree = proto_item_add_subtree(ddsti, ett_mpls_echo_tlv_dd_map);
1329 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_type, tvb, offset - 4, 2, ENC_BIG_ENDIAN);
1330 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_length, tvb, offset - 2, 2, ENC_BIG_ENDIAN);
1331 proto_tree_add_item(tlv_dd_map_tree, hf_mpls_echo_tlv_dd_map_value, tvb, offset, subtlv_length, ENC_BIG_ENDIAN);
1332 rem -= subtlv_length;
1333 break;
1339 * Dissector for IPv4 and IPv6 Interface and Label Stack Object
1341 static void
1342 dissect_mpls_echo_tlv_ilso(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean is_ipv6)
1344 proto_tree *ti;
1345 guint8 type;
1346 guint16 idx = 1;
1347 guint32 label;
1348 guint8 exp, bos, ttl;
1350 ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_addr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1351 type = tvb_get_guint8(tvb, offset);
1352 offset += 1;
1353 rem -= 1;
1355 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_mbz, tvb, offset, 3, ENC_BIG_ENDIAN);
1356 offset += 3;
1357 rem -= 3;
1359 if ((type == TLV_ADDR_IPv4) || (type == TLV_ADDR_UNNUM_IPv4)) {
1360 if (is_ipv6) {
1361 expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1363 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_addr, tvb,
1364 offset, 4, ENC_BIG_ENDIAN);
1365 if (type == TLV_ADDR_IPv4) {
1366 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_int_addr, tvb,
1367 offset + 4, 4, ENC_BIG_ENDIAN);
1368 } else {
1369 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_int_index, tvb,
1370 offset + 4, 4, ENC_BIG_ENDIAN);
1372 offset += 8;
1373 rem -= 8;
1374 } else if ((type == TLV_ADDR_IPv6) || (type == TLV_ADDR_UNNUM_IPv6)) {
1375 if (!is_ipv6) {
1376 expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1379 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_addr, tvb,
1380 offset, 16, ENC_NA);
1381 if (type == TLV_ADDR_IPv6) {
1382 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_int_addr, tvb,
1383 offset + 16, 16, ENC_NA);
1384 offset += 32;
1385 rem -= 32;
1386 } else {
1387 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_int_index, tvb,
1388 offset + 16, 4, ENC_BIG_ENDIAN);
1389 offset += 20;
1390 rem -= 20;
1392 } else {
1393 expert_add_info(pinfo, ti, &ei_mpls_echo_incorrect_address_type);
1394 return;
1397 if (tree) {
1398 while (rem >= 4) {
1399 proto_tree *tlv_ilso;
1401 decode_mpls_label(tvb, offset, &label, &exp, &bos, &ttl);
1402 ti = proto_tree_add_text(tree, tvb, offset, 4, "Label Stack Element %u", idx);
1403 tlv_ilso = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ilso);
1404 proto_item_append_text(ti, ", Label: %u", label);
1405 if (label <= MPLS_LABEL_MAX_RESERVED) {
1406 proto_tree_add_uint_format_value(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
1407 tvb, offset, 3, label, "%u (%s)", label,
1408 val_to_str_const(label, special_labels, "Reserved - Unknown"));
1409 proto_item_append_text(ti, " (%s)", val_to_str_const(label, special_labels,
1410 "Reserved - Unknown"));
1411 } else {
1412 proto_tree_add_uint_format_value(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
1413 tvb, offset, 3, label, "%u", label);
1415 proto_item_append_text(ti, ", Exp: %u, BOS: %u, TTL: %u",
1416 exp, bos, ttl);
1417 proto_tree_add_uint(tlv_ilso, hf_mpls_echo_tlv_ilso_exp,
1418 tvb, offset + 2, 1, exp);
1419 proto_tree_add_uint(tlv_ilso, hf_mpls_echo_tlv_ilso_bos,
1420 tvb, offset + 2, 1, bos);
1421 proto_tree_add_item(tlv_ilso, hf_mpls_echo_tlv_ilso_ttl,
1422 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1423 rem -= 4;
1424 offset += 4;
1425 idx++;
1430 static int
1431 dissect_mpls_echo_tlv(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean in_errored);
1434 * Dissector for Errored TLVs
1436 static void
1437 dissect_mpls_echo_tlv_errored(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem)
1439 int errored_tlv_length;
1441 while (rem >= 4) {
1442 errored_tlv_length = dissect_mpls_echo_tlv(tvb, pinfo, offset, tree, rem, TRUE);
1443 rem -= errored_tlv_length;
1444 offset += errored_tlv_length;
1449 * Dissector for MPLS Echo TLVs and return bytes consumed
1451 static int
1452 dissect_mpls_echo_tlv(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree, int rem, gboolean in_errored)
1454 proto_tree *ti = NULL, *mpls_echo_tlv_tree = NULL;
1455 guint16 type, saved_type;
1456 int length;
1458 length = tvb_reported_length_remaining(tvb, offset);
1459 rem = MIN(rem, length);
1461 if ( rem < 4 ) { /* Type Length */
1462 if (tree)
1463 proto_tree_add_text(tree, tvb, offset, rem,
1464 "Error processing TLV: length is %d, should be >= 4",
1465 rem);
1466 return rem;
1469 type = tvb_get_ntohs(tvb, offset);
1470 length = tvb_get_ntohs(tvb, offset + 2);
1471 rem -= 4; /* do not count Type Length */
1472 length = MIN(length, rem);
1474 /* Check for Vendor Private TLVs */
1475 saved_type = type;
1476 if (type >= TLV_VENDOR_PRIVATE_START) /* && <= TLV_VENDOR_PRIVATE_END always true */
1477 type = TLV_VENDOR_PRIVATE_START;
1479 if (tree) {
1480 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s%s",
1481 in_errored ? "Errored TLV Type: " : "",
1482 val_to_str_ext(type, &mpls_echo_tlv_type_names_ext, "Unknown TLV type (0x%04X)"));
1483 mpls_echo_tlv_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv);
1485 /* MPLS Echo TLV Type and Length */
1486 if (in_errored) {
1487 proto_tree_add_uint_format_value(mpls_echo_tlv_tree, hf_mpls_echo_tlv_errored_type, tvb,
1488 offset, 2, saved_type, "%s (%u)",
1489 val_to_str_ext_const(type, &mpls_echo_tlv_type_names_ext,
1490 "Unknown TLV type"), saved_type);
1491 } else {
1492 proto_tree_add_uint_format_value(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
1493 offset, 2, saved_type, "%s (%u)",
1494 val_to_str_ext_const(type, &mpls_echo_tlv_type_names_ext,
1495 "Unknown TLV type"), saved_type);
1497 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1500 /* MPLS Echo TLV Value */
1501 if (length == 0)
1502 return 4; /* Empty TLV, return Type and Length consumed. */
1504 switch (type) {
1505 case TLV_TARGET_FEC_STACK:
1506 dissect_mpls_echo_tlv_fec(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1507 break;
1508 case TLV_PAD:
1509 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padaction, tvb,
1510 offset + 4, 1, ENC_BIG_ENDIAN);
1511 if (length > 1)
1512 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
1513 offset + 5, length - 1, ENC_NA);
1514 break;
1515 case TLV_VENDOR_CODE:
1516 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
1517 offset + 4, 4, ENC_BIG_ENDIAN);
1518 break;
1519 case TLV_ILSO_IPv4:
1520 if (length < 12) {
1521 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1522 "Invalid TLV Length (claimed %u, should be >= 12)",
1523 length);
1524 break;
1526 dissect_mpls_echo_tlv_ilso(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length, FALSE);
1527 break;
1528 case TLV_ILSO_IPv6:
1529 if (length < 24) {
1530 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1531 "Invalid TLV Length (claimed %u, should be >= 24)",
1532 length);
1533 break;
1535 dissect_mpls_echo_tlv_ilso(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length, TRUE);
1536 break;
1537 #if 0
1538 case TLV_RTO_IPv4:
1539 if (length != 4) {
1540 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
1541 "Error processing TLV: length is %d, should be 4",
1542 length);
1543 break;
1545 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv4,
1546 tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1547 break;
1548 case TLV_RTO_IPv6:
1549 if (length != 16) {
1550 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
1551 "Error processing TLV: length is %d, should be 16",
1552 length);
1553 break;
1555 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv6,
1556 tvb, offset + 4, 16, ENC_NA);
1557 break;
1558 #endif
1559 case TLV_P2MP_ECHO_JITTER:
1560 if (length != 4) {
1561 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1562 "Invalid TLV Length (claimed %u, should be 4)",
1563 length);
1564 break;
1566 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_echo_jitter,
1567 tvb, offset + 4, 4, FALSE);
1568 break;
1569 case TLV_P2MP_RESPONDER_IDENT: {
1570 guint16 resp_ident_type, resp_ident_len;
1571 proto_item *hidden_item;
1573 resp_ident_type = tvb_get_ntohs(tvb, offset + 4);
1574 resp_ident_len = tvb_get_ntohs(tvb, offset + 6);
1575 /* Check addr length */
1576 switch (resp_ident_type) {
1577 case TLV_P2MP_RESPONDER_IDENT_IPV4_EGRESS_ADDR:
1578 case TLV_P2MP_RESPONDER_IDENT_IPV4_NODE_ADDR:
1579 if (resp_ident_len != 4) {
1580 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1581 "Invalid TLV Length (claimed %u, should be 4)",
1582 length);
1583 break;
1585 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_type,
1586 tvb, offset + 4, 2, FALSE);
1587 hidden_item = proto_tree_add_item(mpls_echo_tlv_tree,
1588 hf_mpls_echo_tlv_responder_indent_len, tvb,
1589 offset + 6, 2, FALSE);
1590 PROTO_ITEM_SET_HIDDEN(hidden_item);
1591 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_ipv4,
1592 tvb, offset + 8, 4, FALSE);
1593 break;
1594 case TLV_P2MP_RESPONDER_IDENT_IPV6_EGRESS_ADDR:
1595 case TLV_P2MP_RESPONDER_IDENT_IPV6_NODE_ADDR:
1596 if (resp_ident_len != 16) {
1597 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1598 "Invalid TLV Length (claimed %u, should be 16)",
1599 length);
1600 break;
1602 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_type,
1603 tvb, offset + 4, 2, FALSE);
1604 hidden_item = proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_len,
1605 tvb, offset + 6, 2, FALSE);
1606 PROTO_ITEM_SET_HIDDEN(hidden_item);
1607 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_responder_indent_ipv4,
1608 tvb, offset + 8, 16, FALSE);
1609 break;
1611 break;
1613 case TLV_VENDOR_PRIVATE_START:
1614 if (length < 4) { /* SMI Enterprise code */
1615 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1616 "Invalid TLV Length (claimed %u, should be >= 4)",
1617 length);
1618 } else {
1619 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
1620 offset + 4, 4, ENC_BIG_ENDIAN);
1621 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1622 offset + 8, length - 4, ENC_NA);
1624 break;
1625 case TLV_DOWNSTREAM_MAPPING:
1626 if (length < 16) {
1627 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1628 "Invalid TLV Length (claimed %u, should be >= 16)",
1629 length);
1630 break;
1632 dissect_mpls_echo_tlv_ds_map(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1633 break;
1634 case TLV_DETAILED_DOWNSTREAM: /* [RFC 6424] */
1635 if (length < 16) {
1636 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1637 "Invalid TLV Length (claimed %u, should be >= 16)",
1638 length);
1639 break;
1641 dissect_mpls_echo_tlv_dd_map(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1642 break;
1643 case TLV_ERRORED_TLV:
1644 if (in_errored)
1645 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1646 offset + 4, length, ENC_NA);
1647 else
1648 dissect_mpls_echo_tlv_errored(tvb, pinfo, offset + 4, mpls_echo_tlv_tree, length);
1649 break;
1650 case TLV_REPLY_TOS:
1651 if (length != 4) {
1652 expert_add_info_format(pinfo, ti, &ei_mpls_echo_tlv_len,
1653 "Invalid TLV Length (claimed %u, should be 4)",
1654 length);
1655 break;
1657 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos, tvb,
1658 offset + 4, 1, ENC_BIG_ENDIAN);
1659 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos_mbz, tvb,
1660 offset + 5, 3, ENC_BIG_ENDIAN);
1661 break;
1662 case TLV_SRC_IDENTIFIER:
1663 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_gid,
1664 tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1665 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_nid,
1666 tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
1667 break;
1668 case TLV_DST_IDENTIFIER:
1669 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_gid,
1670 tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1671 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_lspping_tlv_src_addr_nid,
1672 tvb, (offset + 8), 4, ENC_BIG_ENDIAN);
1673 break;
1674 case TLV_BFD_DISCRIMINATOR:
1675 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_bfd,
1676 tvb, (offset + 4), 4, ENC_BIG_ENDIAN);
1677 break;
1678 case TLV_REVERSE_PATH_FEC_STACK:
1679 dissect_mpls_echo_tlv_fec (tvb, pinfo, (offset + 4), mpls_echo_tlv_tree, length);
1680 break ;
1681 case TLV_ERROR_CODE:
1682 default:
1683 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
1684 offset + 4, length, ENC_NA);
1685 break;
1687 return length + 4; /* Length of the Value field + Type Length */
1690 #define MSGTYPE_MPLS_ECHO(msgtype) ((msgtype == 1) || (msgtype == 2))
1691 #define MSGTYPE_DATAPLANE(msgtype) ((msgtype == 3) || (msgtype == 4))
1694 * Dissector for MPLS Echo (LSP PING) packets
1697 dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1699 int offset = 0, rem = 0, len;
1700 proto_item *ti = NULL;
1701 proto_tree *mpls_echo_tree = NULL;
1702 guint8 msgtype;
1704 /* If version != 1 we assume it's not an mpls ping packet */
1705 if (tvb_length(tvb) < 5) {
1706 return 0; /* Not enough information to tell version and message type. */
1708 if (tvb_get_ntohs(tvb, 0) != 1) {
1709 return 0; /* Not version 1. */
1712 /* Make entries in Protocol column and Info column on summary display */
1713 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPLS ECHO");
1715 /* Clear the info column so it's sane if we crash. We fill it in later when
1716 * we've dissected more of the packet. */
1717 col_clear(pinfo->cinfo, COL_INFO);
1719 rem = tvb_reported_length_remaining(tvb, offset);
1721 /* Get the message type and fill in the Column info */
1722 msgtype = tvb_get_guint8(tvb, offset + 4);
1724 /* The minimum fixed part of the packet is 16 Bytes or 32 Bytes depending on Msg Type */
1725 if ( ((!MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 16)) ||
1726 ((MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 32)) ) {
1727 col_set_str(pinfo->cinfo, COL_INFO, "Malformed Message");
1728 if (tree) {
1729 ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, ENC_NA);
1730 mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
1731 proto_tree_add_text(mpls_echo_tree, tvb, offset, rem,
1732 "Error processing Message: length is %d, should be >= %u",
1733 rem, (MSGTYPE_MPLS_ECHO(msgtype)) ? 32 : 16);
1735 return 0;
1738 col_add_str(pinfo->cinfo, COL_INFO,
1739 val_to_str(msgtype, mpls_echo_msgtype, "Unknown Message Type (0x%02X)"));
1742 if (tree) {
1743 /* Add subtree and dissect the fixed part of the message */
1744 ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, ENC_NA);
1745 mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
1747 proto_tree_add_item(mpls_echo_tree,
1748 hf_mpls_echo_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1750 if (MSGTYPE_MPLS_ECHO(msgtype)) {
1751 proto_tree *mpls_echo_gflags;
1752 ti = proto_tree_add_item(mpls_echo_tree,
1753 hf_mpls_echo_gflags, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1754 mpls_echo_gflags = proto_item_add_subtree(ti, ett_mpls_echo_gflags);
1755 proto_tree_add_item(mpls_echo_gflags,
1756 hf_mpls_echo_flag_sbz, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1757 proto_tree_add_item(mpls_echo_gflags,
1758 hf_mpls_echo_flag_v, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1759 proto_tree_add_item(mpls_echo_gflags,
1760 hf_mpls_echo_flag_t, tvb, (offset + 2), 2, ENC_BIG_ENDIAN);
1761 proto_tree_add_item(mpls_echo_gflags,
1762 hf_mpls_echo_flag_r, tvb, (offset + 2), 2, ENC_BIG_ENDIAN);
1763 } else {
1764 proto_tree_add_item(mpls_echo_tree,
1765 hf_mpls_echo_mbz, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1768 proto_tree_add_item(mpls_echo_tree,
1769 hf_mpls_echo_msgtype, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
1770 proto_tree_add_item(mpls_echo_tree,
1771 hf_mpls_echo_replymode, tvb, offset + 5, 1, ENC_BIG_ENDIAN);
1772 proto_tree_add_item(mpls_echo_tree,
1773 hf_mpls_echo_returncode, tvb, offset + 6, 1, ENC_BIG_ENDIAN);
1774 proto_tree_add_item(mpls_echo_tree,
1775 hf_mpls_echo_returnsubcode, tvb, offset + 7, 1, ENC_BIG_ENDIAN);
1776 proto_tree_add_item(mpls_echo_tree,
1777 hf_mpls_echo_handle, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1778 proto_tree_add_item(mpls_echo_tree,
1779 hf_mpls_echo_sequence, tvb, offset + 12, 4, ENC_BIG_ENDIAN);
1781 if (MSGTYPE_MPLS_ECHO(msgtype)) {
1782 proto_tree_add_item(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
1783 offset + 16, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
1784 proto_tree_add_item(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
1785 offset + 24, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
1789 if (MSGTYPE_MPLS_ECHO(msgtype)) {
1790 offset += 32;
1791 rem -= 32;
1792 } else {
1793 offset += 16;
1794 rem -= 16;
1797 /* Dissect all TLVs */
1798 while (tvb_reported_length_remaining(tvb, offset) > 0 ) {
1799 len = dissect_mpls_echo_tlv(tvb, pinfo, offset, mpls_echo_tree, rem, FALSE);
1800 offset += len;
1801 rem -= len;
1804 return tvb_length(tvb);
1807 /* Register the protocol with Wireshark */
1809 void
1810 proto_register_mpls_echo(void)
1813 static hf_register_info hf[] = {
1814 { &hf_mpls_echo_version,
1815 { "Version", "mpls_echo.version",
1816 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Version Number", HFILL}
1818 { &hf_mpls_echo_mbz,
1819 { "MBZ", "mpls_echo.mbz",
1820 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Must be Zero", HFILL}
1822 { &hf_mpls_echo_gflags,
1823 { "Global Flags", "mpls_echo.flags",
1824 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Global Flags", HFILL}
1826 { &hf_mpls_echo_flag_sbz,
1827 { "Reserved", "mpls_echo.flag_sbz",
1828 FT_UINT16, BASE_HEX, NULL, 0xFFF8, "MPLS ECHO Reserved Flags", HFILL}
1830 { &hf_mpls_echo_flag_v,
1831 { "Validate FEC Stack", "mpls_echo.flag_v",
1832 FT_BOOLEAN, 16, NULL, 0x0001, "MPLS ECHO Validate FEC Stack Flag", HFILL}
1834 { &hf_mpls_echo_flag_t,
1835 { "Respond only if TTL expired", "mpls_echo.flag_t",
1836 FT_BOOLEAN, 16, NULL, 0x0002, "MPLS ECHO Respond only if TTL expired Flag", HFILL}
1838 { &hf_mpls_echo_flag_r,
1839 { "Validate Reverse Path", "mpls_echo.flag_r",
1840 FT_BOOLEAN, 16, NULL, 0x0004, "MPLS ECHO Validate Reverse Path Flag", HFILL}
1842 { &hf_mpls_echo_msgtype,
1843 { "Message Type", "mpls_echo.msg_type",
1844 FT_UINT8, BASE_DEC, VALS(mpls_echo_msgtype), 0x0, "MPLS ECHO Message Type", HFILL}
1846 { &hf_mpls_echo_replymode,
1847 { "Reply Mode", "mpls_echo.reply_mode",
1848 FT_UINT8, BASE_DEC, VALS(mpls_echo_replymode), 0x0, "MPLS ECHO Reply Mode", HFILL}
1850 { &hf_mpls_echo_returncode,
1851 { "Return Code", "mpls_echo.return_code",
1852 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &mpls_echo_returncode_ext, 0x0, "MPLS ECHO Return Code", HFILL}
1854 { &hf_mpls_echo_returnsubcode,
1855 { "Return Subcode", "mpls_echo.return_subcode",
1856 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO Return Subcode", HFILL}
1858 { &hf_mpls_echo_handle,
1859 { "Sender's Handle", "mpls_echo.sender_handle",
1860 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO Sender's Handle", HFILL}
1862 { &hf_mpls_echo_sequence,
1863 { "Sequence Number", "mpls_echo.sequence",
1864 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Sequence Number", HFILL}
1866 { &hf_mpls_echo_ts_sent,
1867 { "Timestamp Sent", "mpls_echo.timestamp_sent",
1868 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "MPLS ECHO Timestamp Sent", HFILL}
1870 { &hf_mpls_echo_ts_rec,
1871 { "Timestamp Received", "mpls_echo.timestamp_rec",
1872 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "MPLS ECHO Timestamp Received", HFILL}
1874 { &hf_mpls_echo_tlv_type,
1875 { "Type", "mpls_echo.tlv.type",
1876 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_type_names_ext, 0x0,
1877 "MPLS ECHO TLV Type", HFILL}
1879 { &hf_mpls_echo_tlv_len,
1880 { "Length", "mpls_echo.tlv.len",
1881 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Length", HFILL}
1883 { &hf_mpls_echo_tlv_value,
1884 { "Value", "mpls_echo.tlv.value",
1885 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Value", HFILL}
1887 { &hf_mpls_echo_tlv_fec_type,
1888 { "Type", "mpls_echo.tlv.fec.type",
1889 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_fec_names_ext, 0x0,
1890 "MPLS ECHO TLV FEC Stack Type", HFILL}
1892 { &hf_mpls_echo_tlv_fec_len,
1893 { "Length", "mpls_echo.tlv.fec.len",
1894 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Length", HFILL}
1896 { &hf_mpls_echo_tlv_fec_value,
1897 { "Value", "mpls_echo.tlv.fec.value",
1898 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Value", HFILL}
1900 { &hf_mpls_echo_tlv_fec_ldp_ipv4,
1901 { "IPv4 Prefix", "mpls_echo.tlv.fec.ldp_ipv4",
1902 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4", HFILL}
1904 { &hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
1905 { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv4_mask",
1906 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4 Prefix Length", HFILL}
1908 { &hf_mpls_echo_tlv_fec_ldp_ipv6,
1909 { "IPv6 Prefix", "mpls_echo.tlv.fec.ldp_ipv6",
1910 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6", HFILL}
1912 { &hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
1913 { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv6_mask",
1914 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6 Prefix Length", HFILL}
1916 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
1917 { "IPv4 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv4_ep",
1918 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Tunnel Endpoint Address", HFILL}
1920 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
1921 { "IPv6 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv6_ep",
1922 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Tunnel Endpoint Address", HFILL}
1924 { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
1925 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz1",
1926 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
1928 { &hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
1929 { "Tunnel ID", "mpls_echo.tlv.fec.rsvp_ip_tun_id",
1930 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP Tunnel ID", HFILL}
1932 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
1933 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv4_ext_tun_id",
1934 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Extended Tunnel ID", HFILL}
1936 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
1937 { "IPv4 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv4_sender",
1938 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
1940 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
1941 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv6_ext_tun_id",
1942 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Extended Tunnel ID", HFILL}
1944 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
1945 { "IPv6 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv6_sender",
1946 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
1948 { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
1949 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz2",
1950 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
1952 { &hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
1953 { "LSP ID", "mpls_echo.tlv.fec.rsvp_ip_lsp_id",
1954 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP LSP ID", HFILL}
1956 { &hf_mpls_echo_tlv_fec_vpn_route_dist,
1957 { "Route Distinguisher", "mpls_echo.tlv.fec.vpn_route_dist",
1958 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN Route Distinguisher", HFILL}
1960 { &hf_mpls_echo_tlv_fec_vpn_ipv4,
1961 { "IPv4 Prefix", "mpls_echo.tlv.fec.vpn_ipv4",
1962 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN IPv4", HFILL}
1964 { &hf_mpls_echo_tlv_fec_vpn_ipv6,
1965 { "IPv6 Prefix", "mpls_echo.tlv.fec.vpn_ipv6",
1966 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN IPv6", HFILL}
1968 { &hf_mpls_echo_tlv_fec_vpn_len,
1969 { "Prefix Length", "mpls_echo.tlv.fec.vpn_len",
1970 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack VPN Prefix Length", HFILL}
1972 { &hf_mpls_echo_tlv_fec_l2_vpn_route_dist,
1973 { "Route Distinguisher", "mpls_echo.tlv.fec.l2vpn_route_dist",
1974 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Route Distinguisher", HFILL}
1976 { &hf_mpls_echo_tlv_fec_l2_vpn_send_ve_id,
1977 { "Sender's VE ID", "mpls_echo.tlv.fec.l2vpn_send_ve_id",
1978 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Sender's VE ID", HFILL}
1980 { &hf_mpls_echo_tlv_fec_l2_vpn_recv_ve_id,
1981 { "Receiver's VE ID", "mpls_echo.tlv.fec.l2vpn_recv_ve_id",
1982 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2VPN Receiver's VE ID", HFILL}
1984 { &hf_mpls_echo_tlv_fec_l2_vpn_encap_type,
1985 { "Encapsulation", "mpls_echo.tlv.fec.l2vpn_encap_type",
1986 FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2VPN Encapsulation", HFILL}
1988 { &hf_mpls_echo_tlv_fec_l2cid_sender,
1989 { "Sender's PE Address", "mpls_echo.tlv.fec.l2cid_sender",
1990 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Sender", HFILL}
1992 { &hf_mpls_echo_tlv_fec_l2cid_remote,
1993 { "Remote PE Address", "mpls_echo.tlv.fec.l2cid_remote",
1994 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Remote", HFILL}
1996 { &hf_mpls_echo_tlv_fec_l2cid_vcid,
1997 { "VC ID", "mpls_echo.tlv.fec.l2cid_vcid",
1998 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID VCID", HFILL}
2000 { &hf_mpls_echo_tlv_fec_l2cid_encap,
2001 { "Encapsulation", "mpls_echo.tlv.fec.l2cid_encap",
2002 FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2CID Encapsulation", HFILL}
2004 { &hf_mpls_echo_tlv_fec_l2cid_mbz,
2005 { "MBZ", "mpls_echo.tlv.fec.l2cid_mbz",
2006 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID MBZ", HFILL}
2008 { &hf_mpls_echo_tlv_fec_bgp_ipv4,
2009 { "IPv4 Prefix", "mpls_echo.tlv.fec.bgp_ipv4",
2010 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv4", HFILL}
2012 { &hf_mpls_echo_tlv_fec_bgp_ipv6,
2013 { "IPv6 Prefix", "mpls_echo.tlv.fec.bgp_ipv6",
2014 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv6", HFILL}
2016 { &hf_mpls_echo_tlv_fec_bgp_len,
2017 { "Prefix Length", "mpls_echo.tlv.fec.bgp_len",
2018 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Prefix Length", HFILL}
2020 { &hf_mpls_echo_tlv_fec_gen_ipv4,
2021 { "IPv4 Prefix", "mpls_echo.tlv.fec.gen_ipv4",
2022 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4", HFILL}
2024 { &hf_mpls_echo_tlv_fec_gen_ipv4_mask,
2025 { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv4_mask",
2026 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4 Prefix Length", HFILL}
2028 { &hf_mpls_echo_tlv_fec_gen_ipv6,
2029 { "IPv6 Prefix", "mpls_echo.tlv.fec.gen_ipv6",
2030 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6", HFILL}
2032 { &hf_mpls_echo_tlv_fec_gen_ipv6_mask,
2033 { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv6_mask",
2034 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6 Prefix Length", HFILL}
2036 { &hf_mpls_echo_tlv_fec_nil_label,
2037 { "Label", "mpls_echo.tlv.fec.nil_label",
2038 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV FEC Stack NIL Label", HFILL}
2040 { &hf_mpls_echo_tlv_ds_map_mtu,
2041 { "MTU", "mpls_echo.tlv.ds_map.mtu",
2042 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map MTU", HFILL}
2044 { &hf_mpls_echo_tlv_ds_map_addr_type,
2045 { "Address Type", "mpls_echo.tlv.ds_map.addr_type",
2046 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0,
2047 "MPLS ECHO TLV Downstream Map Address Type", HFILL}
2049 { &hf_mpls_echo_tlv_ds_map_res,
2050 { "DS Flags", "mpls_echo.tlv.ds_map.res",
2051 FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map DS Flags", HFILL}
2053 { &hf_mpls_echo_tlv_ds_map_flag_res,
2054 { "MBZ", "mpls_echo.tlv.ds_map.flag_res",
2055 FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Downstream Map Reserved Flags", HFILL}
2057 { &hf_mpls_echo_tlv_ds_map_flag_i,
2058 { "Interface and Label Stack Request", "mpls_echo.tlv.ds_map.flag_i",
2059 FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Downstream Map I-Flag", HFILL}
2061 { &hf_mpls_echo_tlv_ds_map_flag_n,
2062 { "Treat as Non-IP Packet", "mpls_echo.tlv.ds_map.flag_n",
2063 FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Downstream Map N-Flag", HFILL}
2065 { &hf_mpls_echo_tlv_ds_map_ds_ip,
2066 { "Downstream IP Address", "mpls_echo.tlv.ds_map.ds_ip",
2067 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IP Address", HFILL}
2069 { &hf_mpls_echo_tlv_ds_map_int_ip,
2070 { "Downstream Interface Address", "mpls_echo.tlv.ds_map.int_ip",
2071 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Address", HFILL}
2073 { &hf_mpls_echo_tlv_ds_map_if_index,
2074 { "Upstream Interface Index", "mpls_echo.tlv.ds_map.if_index",
2075 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Index", HFILL}
2077 { &hf_mpls_echo_tlv_ds_map_ds_ipv6,
2078 { "Downstream IPv6 Address", "mpls_echo.tlv.ds_map.ds_ipv6",
2079 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IPv6 Address", HFILL}
2081 { &hf_mpls_echo_tlv_ds_map_int_ipv6,
2082 { "Downstream Interface IPv6 Address", "mpls_echo.tlv.ds_map.int_ipv6",
2083 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface IPv6 Address", HFILL}
2085 { &hf_mpls_echo_tlv_ds_map_hash_type,
2086 { "Multipath Type", "mpls_echo.tlv.ds_map.hash_type",
2087 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_ds_map_hash_type_ext, 0x0,
2088 "MPLS ECHO TLV Downstream Map Multipath Type", HFILL}
2090 { &hf_mpls_echo_tlv_ds_map_depth,
2091 { "Depth Limit", "mpls_echo.tlv.ds_map.depth",
2092 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Depth Limit", HFILL}
2094 { &hf_mpls_echo_tlv_ds_map_muti_len,
2095 { "Multipath Length", "mpls_echo.tlv.ds_map.multi_len",
2096 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Length", HFILL}
2098 { &hf_mpls_echo_tlv_ds_map_mp_ip,
2099 { "IP Address", "mpls_echo.tlv.ds_map_mp.ip",
2100 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath IP Address", HFILL}
2102 { &hf_mpls_echo_tlv_ds_map_mp_mask,
2103 { "Mask", "mpls_echo.tlv.ds_map_mp.mask",
2104 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Mask", HFILL}
2106 { &hf_mpls_echo_tlv_ds_map_mp_ip_low,
2107 { "IP Address Low", "mpls_echo.tlv.ds_map_mp.ip_low",
2108 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Low IP Address", HFILL}
2110 { &hf_mpls_echo_tlv_ds_map_mp_ip_high,
2111 { "IP Address High", "mpls_echo.tlv.ds_map_mp.ip_high",
2112 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath High IP Address", HFILL}
2114 { &hf_mpls_echo_tlv_ds_map_mp_value,
2115 { "Multipath Value", "mpls_echo.tlv.ds_map_mp.value",
2116 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Multipath Value", HFILL}
2118 { &hf_mpls_echo_tlv_ds_map_mp_label,
2119 { "Downstream Label", "mpls_echo.tlv.ds_map.mp_label",
2120 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Downstream Map Downstream Label", HFILL}
2122 { &hf_mpls_echo_tlv_ds_map_mp_exp,
2123 { "Downstream Exp", "mpls_echo.tlv.ds_map.mp_exp",
2124 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream Experimental", HFILL}
2126 { &hf_mpls_echo_tlv_ds_map_mp_bos,
2127 { "Downstream BOS", "mpls_echo.tlv.ds_map.mp_bos",
2128 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream BOS", HFILL}
2130 { &hf_mpls_echo_tlv_ds_map_mp_proto,
2131 { "Downstream Protocol", "mpls_echo.tlv.ds_map.mp_proto",
2132 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
2133 "MPLS ECHO TLV Downstream Map Downstream Protocol", HFILL}
2135 { &hf_mpls_echo_tlv_padaction,
2136 { "Pad Action", "mpls_echo.tlv.pad_action",
2137 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_pad), 0x0, "MPLS ECHO Pad TLV Action", HFILL}
2139 { &hf_mpls_echo_tlv_padding,
2140 { "Padding", "mpls_echo.tlv.pad_padding",
2141 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Pad TLV Padding", HFILL}
2143 { &hf_mpls_echo_tlv_vendor,
2144 { "Vendor Id", "mpls_echo.tlv.vendor_id",
2145 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0x0, "MPLS ECHO Vendor Id", HFILL}
2147 { &hf_mpls_echo_tlv_ilso_addr_type,
2148 { "Address Type", "mpls_echo.tlv.ilso.addr_type",
2149 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0,
2150 "MPLS ECHO TLV Interface and Label Stack Address Type", HFILL}
2152 { &hf_mpls_echo_tlv_ilso_mbz,
2153 { "Must Be Zero", "mpls_echo.tlv.ilso.mbz",
2154 FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack MBZ", HFILL}
2156 { &hf_mpls_echo_tlv_ilso_ipv4_addr,
2157 { "Downstream IPv4 Address", "mpls_echo.tlv.ilso_ipv4.addr",
2158 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
2160 { &hf_mpls_echo_tlv_ilso_ipv4_int_addr,
2161 { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv4.int_addr",
2162 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Address", HFILL}
2164 { &hf_mpls_echo_tlv_ilso_ipv6_addr,
2165 { "Downstream IPv6 Address", "mpls_echo.tlv.ilso_ipv6.addr",
2166 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
2168 { &hf_mpls_echo_tlv_ilso_ipv6_int_addr,
2169 { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv6.int_addr",
2170 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Address", HFILL}
2172 { &hf_mpls_echo_tlv_ilso_int_index,
2173 { "Downstream Interface Index", "mpls_echo.tlv.ilso.int_index",
2174 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Interface Index", HFILL}
2176 { &hf_mpls_echo_tlv_ilso_label,
2177 { "Label", "mpls_echo.tlv.ilso_ipv4.label",
2178 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Interface and Label Stack Label", HFILL}
2180 { &hf_mpls_echo_tlv_ilso_exp,
2181 { "Exp", "mpls_echo.tlv.ilso_ipv4.exp",
2182 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Exp", HFILL}
2184 { &hf_mpls_echo_tlv_ilso_bos,
2185 { "BOS", "mpls_echo.tlv.ilso_ipv4.bos",
2186 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack BOS", HFILL}
2188 { &hf_mpls_echo_tlv_ilso_ttl,
2189 { "TTL", "mpls_echo.tlv.ilso_ipv4.ttl",
2190 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack TTL", HFILL}
2192 #if 0
2193 { &hf_mpls_echo_tlv_rto_ipv4,
2194 { "Reply-to IPv4 Address", "mpls_echo.tlv.rto.ipv4",
2195 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv4 Reply-To Object", HFILL}
2197 { &hf_mpls_echo_tlv_rto_ipv6,
2198 { "Reply-to IPv6 Address", "mpls_echo.tlv.rto.ipv6",
2199 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv6 Reply-To Object", HFILL}
2201 #endif
2202 { &hf_mpls_echo_tlv_reply_tos,
2203 { "Reply-TOS Byte", "mpls_echo.tlv.reply.tos",
2204 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Reply-TOS Byte", HFILL}
2206 { &hf_mpls_echo_tlv_reply_tos_mbz,
2207 { "MBZ", "mpls_echo.tlv.reply.tos.mbz",
2208 FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Reply-TOS MBZ", HFILL}
2210 { &hf_mpls_echo_tlv_errored_type,
2211 { "Errored TLV Type", "mpls_echo.tlv.errored.type",
2212 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &mpls_echo_tlv_type_names_ext, 0x0,
2213 "MPLS ECHO TLV Errored TLV Type", HFILL}
2215 { &hf_mpls_echo_tlv_ds_map_ingress_if_num,
2216 { "Ingress Interface Number", "mpls_echo.tlv.ds_map.ingress.if.num",
2217 FT_UINT32, BASE_DEC, NULL, 0x0,
2218 "MPLS ECHO TLV DownStream Map Ingress Interface Number", HFILL}
2220 { &hf_mpls_echo_tlv_ds_map_egress_if_num,
2221 { "Egress Interface Number", "mpls_echo.tlv.ds_map.egress.if.num",
2222 FT_UINT32, BASE_DEC, NULL, 0x0,
2223 "MPLS ECHO TLV DownStream Map Egress Interface Number", HFILL}
2225 { &hf_mpls_echo_lspping_tlv_src_gid,
2226 { "SRC GLOBAL ID", "mpls_echo.lspping.tlv.src.gid",
2227 FT_UINT32, BASE_DEC, NULL, 0x0, "LSP SRC GID", HFILL}
2229 { &hf_mpls_echo_lspping_tlv_src_nid,
2230 { "SRC NODE ID", "mpls_echo.lspping.tlv.src.nid",
2231 FT_IPv4, BASE_NONE, NULL, 0x0, "LSP SRC NID", HFILL}
2233 { &hf_mpls_echo_lspping_tlv_src_tunnel_no,
2234 { "SRC Tunnel Number", "mpls_echo.lspping.tlv.tunnel.no",
2235 FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC Tunnel Number", HFILL}
2237 { &hf_mpls_echo_lspping_tlv_lsp_no,
2238 { "SRC LSP Number", "mpls_echo.lspping.tlv.lsp.no",
2239 FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC LSP Number", HFILL}
2241 { &hf_mpls_echo_lspping_tlv_dst_gid,
2242 { "DST GLOBAL ID", "mpls_echo.lspping.tlv.dst.gid",
2243 FT_UINT32, BASE_DEC, NULL, 0x0, "LSP FEC DST GID", HFILL}
2245 { &hf_mpls_echo_lspping_tlv_dst_nid,
2246 { "DST NODE ID", "mpls_echo.lspping.tlv.dst.nid",
2247 FT_IPv4, BASE_NONE, NULL, 0x0, "LSP FEC DST NID", HFILL}
2249 { &hf_mpls_echo_lspping_tlv_dst_tunnel_no,
2250 { "DST Tunnel Number", "mpls_echo.lspping.tlv.dst.tunnel.no",
2251 FT_UINT16, BASE_DEC, NULL, 0x0, "LSP FEC DST Tunnel Number", HFILL}
2253 { &hf_mpls_echo_lspping_tlv_resv,
2254 { "RESERVED", "mpls_echo.lspping.tlv.resv",
2255 FT_UINT16, BASE_DEC, NULL, 0x0, "RESERVED BITS", HFILL}
2257 { &hf_mpls_echo_lspping_tlv_src_addr_gid,
2258 { "Global ID", "mpls_echo.lspping.tlv.src.addr.gid",
2259 FT_UINT32, BASE_DEC, NULL, 0x0, "SRC ADDR TLV GID", HFILL}
2261 { &hf_mpls_echo_lspping_tlv_src_addr_nid,
2262 { "Node ID", "mpls_echo.lspping.tlv.src.addr.nid",
2263 FT_IPv4, BASE_NONE, NULL, 0x0, "SRC ADDR TLV NID", HFILL}
2265 { &hf_mpls_echo_lspping_tlv_pw_serv_identifier,
2266 { "Service identifier", "mpls_echo.lspping.tlv.pw.serv.identifier",
2267 FT_UINT64, BASE_DEC, NULL, 0x0, "PW FEC Service identifier", HFILL}
2269 { &hf_mpls_echo_lspping_tlv_pw_src_ac_id,
2270 { "SRC AC ID", "mpls_echo.lspping.tlv.pw.src.ac.id",
2271 FT_UINT32, BASE_DEC, NULL, 0x0, "PW FEC SRC AC ID", HFILL}
2273 { &hf_mpls_echo_lspping_tlv_pw_dst_ac_id,
2274 { "DST AC ID", "mpls_echo.lspping.tlv.pw.dst.ac.id",
2275 FT_UINT32, BASE_DEC, NULL, 0x0, "PW FEC DST AC ID", HFILL}
2277 #if 0
2278 { &hf_mpls_echo_lspping_tlv_pw_agi_type,
2279 { "AGI TYPE", "mpls_echo.lspping.tlv.pw.agi.type",
2280 FT_UINT8, BASE_DEC, NULL, 0x0, "PW AGI TYPE", HFILL}
2282 #endif
2283 #if 0
2284 { &hf_mpls_echo_lspping_tlv_pw_agi_len,
2285 { "AGI Length", "mpls_echo.lspping.tlv.pw.agi.len",
2286 FT_UINT8, BASE_DEC, NULL, 0x0, "PW AGI LENGTH", HFILL}
2288 #endif
2289 #if 0
2290 { &hf_mpls_echo_lspping_tlv_pw_agi_val,
2291 { "AGI VALUE", "mpls_echo.lspping.tlv.pw.agi.val",
2292 FT_STRING, BASE_NONE, NULL, 0x0, "PW AGI VALUE", HFILL}
2294 #endif
2295 { &hf_mpls_echo_tlv_dd_map_mtu,
2296 { "MTU", "mpls_echo.lspping.tlv.dd_map.mtu",
2297 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map MTU", HFILL}
2299 { &hf_mpls_echo_tlv_dd_map_addr_type,
2300 { "Address Type", "mpls_echo.tlv.dd_map.addr_type",
2301 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_addr_type), 0x0, "MPLS ECHO TLV Detailed Downstream Map Address Type", HFILL}
2303 { &hf_mpls_echo_tlv_dd_map_res,
2304 { "DS Flags", "mpls_echo.tlv.dd_map.res",
2305 FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map DS Flags", HFILL}
2307 { &hf_mpls_echo_tlv_dd_map_flag_res,
2308 { "MBZ", "mpls_echo.tlv.dd_map.flag_res",
2309 FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Detailed Downstream Map Reserved Flags", HFILL}
2311 { &hf_mpls_echo_tlv_dd_map_flag_i,
2312 { "Interface and Label Stack Request", "mpls_echo.tlv.dd_map.flag_i",
2313 FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Detailed Downstream Map I-Flag", HFILL}
2315 { &hf_mpls_echo_tlv_dd_map_flag_n,
2316 { "Treat as Non-IP Packet", "mpls_echo.tlv.dd_map.flag_n",
2317 FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Detailed Downstream Map N-Flag", HFILL}
2319 { &hf_mpls_echo_tlv_dd_map_ds_ip,
2320 { "Downstream IP Address", "mpls_echo.tlv.dd_map.ds_ip",
2321 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map IP Address", HFILL}
2323 { &hf_mpls_echo_tlv_dd_map_int_ip,
2324 { "Downstream Interface Address", "mpls_echo.tlv.dd_map.int_ip",
2325 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Interface Address", HFILL}
2327 { &hf_mpls_echo_tlv_dd_map_ds_ipv6,
2328 { "Downstream IPv6 Address", "mpls_echo.tlv.dd_map.ds_ipv6",
2329 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map IPv6 Address", HFILL}
2331 { &hf_mpls_echo_tlv_dd_map_int_ipv6,
2332 { "Downstream Interface IPv6 Address", "mpls_echo.tlv.dd_map.int_ipv6",
2333 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Interface IPv6 Address", HFILL}
2335 { &hf_mpls_echo_tlv_dd_map_return_code,
2336 { "Return Code", "mpls_echo.tlv.dd_map.return_code",
2337 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Return Code", HFILL}
2339 { &hf_mpls_echo_tlv_dd_map_return_subcode,
2340 { "Return Subcode", "mpls_echo.tlv.dd_map.return_subcode",
2341 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Return Subcode", HFILL}
2343 { &hf_mpls_echo_tlv_dd_map_ingress_if_num,
2344 { "Ingress Interface Number", "mpls_echo.tlv.dd_map.ingress.if.num",
2345 FT_UINT32, BASE_DEC, NULL, 0x0,
2346 "MPLS ECHO TLV Detailed DownStream Map Ingress Interface Number", HFILL}
2348 { &hf_mpls_echo_tlv_dd_map_egress_if_num,
2349 { "Egress Interface Number", "mpls_echo.tlv.dd_map.egress.if.num",
2350 FT_UINT32, BASE_DEC, NULL, 0x0,
2351 "MPLS ECHO TLV Detailed DownStream Map Egress Interface Number", HFILL}
2353 { &hf_mpls_echo_tlv_dd_map_subtlv_len,
2354 { "Subtlv Length", "mpls_echo.tlv.dd_map.subtlv_len",
2355 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Subtlv Length", HFILL}
2357 { &hf_mpls_echo_sub_tlv_multipath_type,
2358 { "Multipath Type", "mpls_echo.subtlv.dd_map.multipath_type",
2359 FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Type", HFILL}
2361 { &hf_mpls_echo_sub_tlv_multipath_length,
2362 { "Multipath Length", "mpls_echo.subtlv.dd_map.multipath_length",
2363 FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Length", HFILL}
2365 { &hf_mpls_echo_sub_tlv_multipath_value,
2366 { "Multipath Value", "mpls_echo.subtlv.dd_map.multipath_value",
2367 FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Multipath Value", HFILL}
2369 { &hf_mpls_echo_sub_tlv_resv,
2370 { "Reserved", "mpls_echo.subtlv.dd_map.reserved",
2371 FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Reserved Bits", HFILL}
2373 { &hf_mpls_echo_sub_tlv_multipath_info,
2374 { "Multipath Information", "mpls_echo.subtlv.dd_map.multipath_info",
2375 FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Multipath Data Sub-TLV Value", HFILL}
2377 #if 0
2378 { &hf_mpls_echo_tlv_ddstlv_map_mp_label,
2379 { "Downstream Label", "mpls_echo.tlv.ddstlv_map.mp_label",
2380 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream Label", HFILL}
2382 #endif
2383 { &hf_mpls_echo_tlv_ddstlv_map_mp_proto,
2384 { "Downstream Protocol", "mpls_echo.tlv.ddstlv_map.mp_proto",
2385 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
2386 "MPLS ECHO TLV Detailed Downstream Map Downstream Protocol", HFILL}
2388 #if 0
2389 { &hf_mpls_echo_tlv_ddstlv_map_mp_exp,
2390 { "Downstream Experimental", "mpls_echo.tlv.ddstlv_map.mp_exp",
2391 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream Experimental", HFILL}
2393 #endif
2394 #if 0
2395 { &hf_mpls_echo_tlv_ddstlv_map_mp_bos,
2396 { "Downstream BOS", "mpls_echo.tlv.ddstlv_map.mp_bos",
2397 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Downstream BOS", HFILL}
2399 #endif
2400 { &hf_mpls_echo_sub_tlv_multipath_ip,
2401 { "IP Address", "mpls_echo.tlv.ddstlv_map_mp.ip",
2402 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath IP Address", HFILL}
2404 { &hf_mpls_echo_sub_tlv_mp_ip_low,
2405 { "IP Address Low", "mpls_echo.tlv.ddstlv_map_mp.ip_low",
2406 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath Low IP Address", HFILL}
2408 { &hf_mpls_echo_sub_tlv_mp_ip_high,
2409 { "IP Address High", "mpls_echo.tlv.ddstlv_map_mp.ip_high",
2410 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath High IP Address", HFILL}
2412 { &hf_mpls_echo_sub_tlv_mp_mask,
2413 { "Mask", "mpls_echo.tlv.ddstlv_map_mp.mask",
2414 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Detailed Downstream Map Multipath Mask", HFILL}
2416 { &hf_mpls_echo_sub_tlv_op_type,
2417 { "Operation Type", "mpls_echo.tlv.ddstlv_map.op_type",
2418 FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_op_types), 0x0,
2419 "MPLS ECHO TLV Detailed Downstream Map Stack Change Operation Type", HFILL}
2421 { &hf_mpls_echo_sub_tlv_addr_type,
2422 { "Address Type", "mpls_echo.tlv.ddstlv_map.address_type",
2423 FT_UINT8, BASE_DEC, VALS(mpls_echo_subtlv_addr_types), 0x0,
2424 "MPLS ECHO TLV Detailed Downstream Map Stack Change Address Type", HFILL}
2426 { &hf_mpls_echo_sub_tlv_fec_tlv_value,
2427 { "FEC tlv Length", "mpls_echo.subtlv.dd_map.fec_tlv_type",
2428 FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Map FEC TLV Length", HFILL}
2430 { &hf_mpls_echo_sub_tlv_res,
2431 { "Reserved", "mpls_echo.subtlv.dd_map.reserved",
2432 FT_UINT8, BASE_DEC, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Reserved Bits", HFILL}
2434 { &hf_mpls_echo_sub_tlv_remote_peer_ip,
2435 { "Remote Peer IP Address", "mpls_echo.tlv.dd_map.remote_ip",
2436 FT_IPv4, BASE_NONE, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Remote Peer IP Address", HFILL}
2438 { &hf_mpls_echo_sub_tlv_remore_peer_ipv6,
2439 { "Remote Peer IPv6 Address", "mpls_echo.tlv.dd_map.remote_ipv6",
2440 FT_IPv6, BASE_NONE, NULL, 0x0, "Detailed Downstream Map FEC Stack Change Remote Peer IPv6 Address", HFILL}
2442 { &hf_mpls_echo_tlv_dd_map_type,
2443 { "Sub-TLV Type", "mpls_echo.subtlv.dd_map.type",
2444 FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Type", HFILL}
2446 { &hf_mpls_echo_tlv_dd_map_length,
2447 { "Sub-TLV Length", "mpls_echo.subtlv.dd_map.length",
2448 FT_UINT16, BASE_DEC, NULL, 0x0, "Detailed Downstream Mapping TLV Length", HFILL}
2450 { &hf_mpls_echo_tlv_dd_map_value,
2451 { "Sub-TLV Value", "mpls_echo.subtlv.dd_map.value",
2452 FT_BYTES, BASE_NONE, NULL, 0x0, "Detailed Downstream Mapping TLV Value", HFILL}
2454 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_p2mp_id,
2455 { "P2MP ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_id",
2456 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP ID", HFILL}
2458 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz1,
2459 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_p2mp_ip_mbz1",
2460 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP MBZ", HFILL}
2462 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_tunnel_id,
2463 { "Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ip_tun_id",
2464 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP Tunnel ID", HFILL}
2466 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ext_tunnel_id,
2467 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_ext_tun_id",
2468 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv4 Extended Tunnel ID", HFILL}
2470 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv4_ipv4_sender,
2471 { "IPv4 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv4_sender",
2472 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv4 Sender", HFILL}
2474 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_mbz2,
2475 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_p2mp_ip_mbz2",
2476 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP MBZ", HFILL}
2478 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ip_lsp_id,
2479 { "LSP ID", "mpls_echo.tlv.fec.rsvp_p2mp_ip_lsp_id",
2480 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP LSP ID", HFILL}
2482 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_p2mp_id,
2483 { "P2MP IPv6 Tunnel ID address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_id",
2484 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 ID", HFILL}
2486 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ext_tunnel_id,
2487 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_ext_tun_id",
2488 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 Extended Tunnel ID", HFILL}
2490 { &hf_mpls_echo_tlv_fec_rsvp_p2mp_ipv6_ipv6_sender,
2491 { "P2MP IPv6 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_p2mp_ipv6_sender",
2492 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP P2MP IPv6 Sender", HFILL}
2494 { &hf_mpls_echo_tlv_responder_indent_type,
2495 { "Target Type", "mpls_echo.tlv.resp_id.type",
2496 FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_responder_ident_sub_tlv_type), 0x0, "P2MP Responder ID TLV", HFILL}
2498 { &hf_mpls_echo_tlv_responder_indent_len,
2499 { "Length", "mpls_echo.tlv.resp_id.length",
2500 FT_UINT16, BASE_DEC, NULL, 0x0, "P2MP Responder ID TLV LENGTH", HFILL}
2502 { &hf_mpls_echo_tlv_responder_indent_ipv4,
2503 { "Target IPv4 Address", "mpls_echo.tlv.resp_id.ipv4",
2504 FT_IPv4, BASE_NONE, NULL, 0x0, "P2MP Responder ID TLV IPv4 Address", HFILL}
2506 #if 0
2507 { &hf_mpls_echo_tlv_responder_indent_ipv6,
2508 { "Target IPv6 Address", "mpls_echo.tlv.resp_id.ipv6",
2509 FT_IPv6, BASE_NONE, NULL, 0x0, "P2MP Responder ID TLV IPv6 Address", HFILL}
2511 #endif
2512 { &hf_mpls_echo_tlv_echo_jitter,
2513 { "Echo Jitter time", "mpls_echo.tlv.echo_jitter",
2514 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Jitter time", HFILL}
2516 { &hf_mpls_echo_tlv_bfd,
2517 { "BFD Discriminator", "mpls_echo.bfd_discriminator",
2518 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO BFD Discriminator", HFILL}
2522 static gint *ett[] = {
2523 &ett_mpls_echo,
2524 &ett_mpls_echo_gflags,
2525 &ett_mpls_echo_tlv,
2526 &ett_mpls_echo_tlv_fec,
2527 &ett_mpls_echo_tlv_ds_map,
2528 &ett_mpls_echo_tlv_ilso,
2529 &ett_mpls_echo_tlv_dd_map,
2530 &ett_mpls_echo_tlv_ddstlv_map
2533 static ei_register_info ei[] = {
2534 { &ei_mpls_echo_tlv_fec_len, { "mpls_echo.tlv.fec.len.invalid", PI_MALFORMED, PI_ERROR, "Invalid FEC TLV length", EXPFILL }},
2535 { &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 }},
2536 { &ei_mpls_echo_tlv_len, { "mpls_echo.tlv.len.invalid", PI_MALFORMED, PI_ERROR, "Invalid TLV length", EXPFILL }},
2537 { &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 }},
2538 { &ei_mpls_echo_unknown_address_type, { "mpls_echo.address_type.unknown", PI_UNDECODED, PI_WARN, "Unknown Address Type", EXPFILL }},
2539 { &ei_mpls_echo_incorrect_address_type, { "mpls_echo.address_type.incorrect", PI_PROTOCOL, PI_WARN, "Incorrect address type for TLV?", EXPFILL }},
2542 module_t *mpls_echo_module;
2543 expert_module_t* expert_mpls_echo;
2545 proto_mpls_echo = proto_register_protocol("Multiprotocol Label Switching Echo",
2546 "MPLS Echo", "mpls-echo");
2548 proto_register_field_array(proto_mpls_echo, hf, array_length(hf));
2549 proto_register_subtree_array(ett, array_length(ett));
2550 expert_mpls_echo = expert_register_protocol(proto_mpls_echo);
2551 expert_register_field_array(expert_mpls_echo, ei, array_length(ei));
2553 mpls_echo_module = prefs_register_protocol(proto_mpls_echo, proto_reg_handoff_mpls_echo);
2554 prefs_register_uint_preference(mpls_echo_module, "udp.port", "MPLS Echo UDP Port",
2555 "Set the UDP port for messages (if other"
2556 " than the default of 3503)",
2557 10, &global_mpls_echo_udp_port);
2561 void
2562 proto_reg_handoff_mpls_echo(void)
2564 static gboolean mpls_echo_prefs_initialized = FALSE;
2565 static dissector_handle_t mpls_echo_handle;
2566 static guint mpls_echo_udp_port;
2568 if (!mpls_echo_prefs_initialized) {
2569 mpls_echo_handle = new_create_dissector_handle(dissect_mpls_echo,
2570 proto_mpls_echo);
2571 mpls_echo_prefs_initialized = TRUE;
2572 } else {
2573 dissector_delete_uint("udp.port", mpls_echo_udp_port, mpls_echo_handle);
2576 mpls_echo_udp_port = global_mpls_echo_udp_port;
2577 dissector_add_uint("udp.port", global_mpls_echo_udp_port, mpls_echo_handle);