2 * Routines for Multiprotocol Label Switching Echo dissection
3 * Copyright 2004, Carlos Pignataro <cpignata@cisco.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/packet.h>
35 #include <epan/prefs.h>
36 #include <epan/sminmpec.h>
37 #include "packet-ntp.h"
38 #include "packet-ldp.h"
39 #include "packet-mpls.h"
41 #define UDP_PORT_MPLS_ECHO 3503
43 void proto_reg_handoff_mpls_echo(void);
45 static int proto_mpls_echo = -1;
46 static int hf_mpls_echo_version = -1;
47 static int hf_mpls_echo_mbz = -1;
48 static int hf_mpls_echo_gflags = -1;
49 static int hf_mpls_echo_flag_sbz = -1;
50 static int hf_mpls_echo_flag_v = -1;
51 static int hf_mpls_echo_msgtype = -1;
52 static int hf_mpls_echo_replymode = -1;
53 static int hf_mpls_echo_returncode = -1;
54 static int hf_mpls_echo_returnsubcode = -1;
55 static int hf_mpls_echo_handle = -1;
56 static int hf_mpls_echo_sequence = -1;
57 static int hf_mpls_echo_ts_sent = -1;
58 static int hf_mpls_echo_ts_rec = -1;
59 static int hf_mpls_echo_tlv_type = -1;
60 static int hf_mpls_echo_tlv_len = -1;
61 static int hf_mpls_echo_tlv_value = -1;
62 static int hf_mpls_echo_tlv_fec_type = -1;
63 static int hf_mpls_echo_tlv_fec_len = -1;
64 static int hf_mpls_echo_tlv_fec_value = -1;
65 static int hf_mpls_echo_tlv_fec_ldp_ipv4 = -1;
66 static int hf_mpls_echo_tlv_fec_ldp_ipv4_mask = -1;
67 static int hf_mpls_echo_tlv_fec_ldp_ipv6 = -1;
68 static int hf_mpls_echo_tlv_fec_ldp_ipv6_mask = -1;
69 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint = -1;
70 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint = -1;
71 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz1 = -1;
72 static int hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id = -1;
73 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id = -1;
74 static int hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender = -1;
75 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id = -1;
76 static int hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender = -1;
77 static int hf_mpls_echo_tlv_fec_rsvp_ip_mbz2 = -1;
78 static int hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id = -1;
79 static int hf_mpls_echo_tlv_fec_l2cid_sender = -1;
80 static int hf_mpls_echo_tlv_fec_l2cid_remote = -1;
81 static int hf_mpls_echo_tlv_fec_l2cid_vcid = -1;
82 static int hf_mpls_echo_tlv_fec_l2cid_encap = -1;
83 static int hf_mpls_echo_tlv_fec_l2cid_mbz = -1;
84 static int hf_mpls_echo_tlv_fec_bgp_nh = -1;
85 static int hf_mpls_echo_tlv_fec_bgp_ipv4 = -1;
86 static int hf_mpls_echo_tlv_fec_bgp_len = -1;
87 static int hf_mpls_echo_tlv_fec_gen_ipv4 = -1;
88 static int hf_mpls_echo_tlv_fec_gen_ipv4_mask = -1;
89 static int hf_mpls_echo_tlv_fec_gen_ipv6 = -1;
90 static int hf_mpls_echo_tlv_fec_gen_ipv6_mask = -1;
91 static int hf_mpls_echo_tlv_fec_nil_label = -1;
92 static int hf_mpls_echo_tlv_ds_map_mtu = -1;
93 static int hf_mpls_echo_tlv_ds_map_addr_type = -1;
94 static int hf_mpls_echo_tlv_ds_map_res = -1;
95 static int hf_mpls_echo_tlv_ds_map_flag_res = -1;
96 static int hf_mpls_echo_tlv_ds_map_flag_i = -1;
97 static int hf_mpls_echo_tlv_ds_map_flag_n = -1;
98 static int hf_mpls_echo_tlv_ds_map_ds_ip = -1;
99 static int hf_mpls_echo_tlv_ds_map_int_ip = -1;
100 static int hf_mpls_echo_tlv_ds_map_if_index = -1;
101 static int hf_mpls_echo_tlv_ds_map_ds_ipv6 = -1;
102 static int hf_mpls_echo_tlv_ds_map_int_ipv6 = -1;
103 static int hf_mpls_echo_tlv_ds_map_hash_type = -1;
104 static int hf_mpls_echo_tlv_ds_map_depth = -1;
105 static int hf_mpls_echo_tlv_ds_map_muti_len = -1;
106 static int hf_mpls_echo_tlv_ds_map_mp_ip = -1;
107 static int hf_mpls_echo_tlv_ds_map_mp_mask = -1;
108 static int hf_mpls_echo_tlv_ds_map_mp_ip_low = -1;
109 static int hf_mpls_echo_tlv_ds_map_mp_ip_high = -1;
110 static int hf_mpls_echo_tlv_ds_map_mp_value = -1;
111 static int hf_mpls_echo_tlv_ds_map_mp_label = -1;
112 static int hf_mpls_echo_tlv_ds_map_mp_exp = -1;
113 static int hf_mpls_echo_tlv_ds_map_mp_bos = -1;
114 static int hf_mpls_echo_tlv_ds_map_mp_proto = -1;
115 static int hf_mpls_echo_tlv_padaction = -1;
116 static int hf_mpls_echo_tlv_padding = -1;
117 static int hf_mpls_echo_tlv_vendor = -1;
118 static int hf_mpls_echo_tlv_ilso_ipv4_addr = -1;
119 static int hf_mpls_echo_tlv_ilso_ipv4_int_addr = -1;
120 static int hf_mpls_echo_tlv_ilso_ipv6_addr = -1;
121 static int hf_mpls_echo_tlv_ilso_ipv6_int_addr = -1;
122 static int hf_mpls_echo_tlv_ilso_label = -1;
123 static int hf_mpls_echo_tlv_ilso_exp = -1;
124 static int hf_mpls_echo_tlv_ilso_bos = -1;
125 static int hf_mpls_echo_tlv_ilso_ttl = -1;
126 static int hf_mpls_echo_tlv_rto_ipv4 = -1;
127 static int hf_mpls_echo_tlv_rto_ipv6 = -1;
128 static int hf_mpls_echo_tlv_reply_tos = -1;
129 static int hf_mpls_echo_tlv_reply_tos_mbz = -1;
130 static int hf_mpls_echo_tlv_errored_type = -1;
132 static gint ett_mpls_echo = -1;
133 static gint ett_mpls_echo_gflags = -1;
134 static gint ett_mpls_echo_tlv = -1;
135 static gint ett_mpls_echo_tlv_fec = -1;
136 static gint ett_mpls_echo_tlv_ds_map = -1;
137 static gint ett_mpls_echo_tlv_ilso = -1;
139 static int mpls_echo_udp_port = 0;
141 static guint32 global_mpls_echo_udp_port = UDP_PORT_MPLS_ECHO;
143 static const value_string mpls_echo_msgtype[] = {
144 {1, "MPLS Echo Request"},
145 {2, "MPLS Echo Reply"},
146 {3, "MPLS Data Plane Verification Request"},
147 {4, "MPLS Data Plane Verification Reply"},
151 static const value_string mpls_echo_replymode[] = {
153 {2, "Reply via an IPv4/IPv6 UDP packet"},
154 {3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
155 {4, "Reply via application level control channel"},
159 static const value_string mpls_echo_returncode[] = {
160 {0, "No return code"},
161 {1, "Malformed echo request received"},
162 {2, "One or more of the TLVs was not understood"},
163 {3, "Replying router is an egress for the FEC at stack depth RSC"},
164 {4, "Replying router has no mapping for the FEC at stack depth RSC"},
168 {8, "Label switched at stack-depth RSC"},
169 {9, "Label switched but no MPLS forwarding at stack-depth RSC"},
170 {10, "Mapping for this FEC is not the given label at stack depth RSC"},
171 {11, "No label entry at stack-depth RSC"},
172 {12, "Protocol not associated with interface at FEC stack depth RSC"},
173 {13, "Premature termination, label stack shrinking to a single label"},
177 #define TLV_TARGET_FEC_STACK 0x0001
178 #define TLV_DOWNSTREAM_MAPPING 0x0002
179 #define TLV_PAD 0x0003
180 #define TLV_ERROR_CODE 0x0004
181 #define TLV_VENDOR_CODE 0x0005
182 #define TLV_TBD 0x0006
183 #define TLV_ILSO_IPv4 0x0007
184 #define TLV_ILSO_IPv6 0x0008
185 #define TLV_ERRORED_TLV 0x0009
186 #define TLV_REPLY_TOS 0x000A
187 #define TLV_RTO_IPv4 0x000B
188 #define TLV_RTO_IPv6 0x000C
189 #define TLV_VENDOR_PRIVATE_START 0xFC00
190 #define TLV_VENDOR_PRIVATE_END 0xFFFF
192 /* MPLS Echo TLV Type names */
193 static const value_string mpls_echo_tlv_type_names[] = {
194 { TLV_TARGET_FEC_STACK, "Target FEC Stack" },
195 { TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
197 { TLV_ERROR_CODE, "Error Code" },
198 { TLV_VENDOR_CODE, "Vendor Enterprise Code" },
200 { TLV_ILSO_IPv4, "IPv4 Interface and Label Stack Object" },
201 { TLV_ILSO_IPv6, "IPv6 Interface and Label Stack Object" },
202 { TLV_ERRORED_TLV, "Errored TLVs" },
203 { TLV_REPLY_TOS, "Reply TOS Byte" },
204 { TLV_RTO_IPv4, "IPv4 Reply-to Object" },
205 { TLV_RTO_IPv6, "IPv6 Reply-to Object" },
206 { TLV_VENDOR_PRIVATE_START, "Vendor Private" },
210 #define TLV_FEC_STACK_LDP_IPv4 1
211 #define TLV_FEC_STACK_LDP_IPv6 2
212 #define TLV_FEC_STACK_RSVP_IPv4 3
213 #define TLV_FEC_STACK_RSVP_IPv6 4
214 #define TLV_FEC_STACK_RES 5
215 #define TLV_FEC_STACK_VPN_IPv4 6
216 #define TLV_FEC_STACK_VPN_IPv6 7
217 #define TLV_FEC_STACK_L2_VPN 8
218 #define TLV_FEC_STACK_L2_CID_OLD 9
219 #define TLV_FEC_STACK_L2_CID_NEW 10
220 #define TLV_FEC_STACK_L2_FEC_129 11
221 #define TLV_FEC_STACK_BGP_LAB_v4 12
222 #define TLV_FEC_STACK_BGP_LAB_v6 13
223 #define TLV_FEC_STACK_GEN_IPv4 14
224 #define TLV_FEC_STACK_GEN_IPv6 15
225 #define TLV_FEC_STACK_NIL 16
226 #define TLV_FEC_VENDOR_PRIVATE_START 0xFC00
227 #define TLV_FEC_VENDOR_PRIVATE_END 0xFFFF
229 /* FEC sub-TLV Type names */
230 static const value_string mpls_echo_tlv_fec_names[] = {
231 { TLV_FEC_STACK_LDP_IPv4, "LDP IPv4 prefix"},
232 { TLV_FEC_STACK_LDP_IPv6, "LDP IPv6 prefix"},
233 { TLV_FEC_STACK_RSVP_IPv4, "RSVP IPv4 Session Query"},
234 { TLV_FEC_STACK_RSVP_IPv6, "RSVP IPv6 Session Query"},
235 { TLV_FEC_STACK_RES, "Reserved"},
236 { TLV_FEC_STACK_VPN_IPv4, "VPN IPv4 prefix"},
237 { TLV_FEC_STACK_VPN_IPv6, "VPN IPv6 prefix"},
238 { TLV_FEC_STACK_L2_VPN, "L2 VPN endpoint"},
239 { TLV_FEC_STACK_L2_CID_OLD, "FEC 128 Pseudowire (old)"},
240 { TLV_FEC_STACK_L2_CID_NEW, "FEC 128 Pseudowire (new)"},
241 { TLV_FEC_STACK_L2_FEC_129, "FEC 129 Pseudowire"},
242 { TLV_FEC_STACK_BGP_LAB_v4, "BGP labeled IPv4 prefix"},
243 { TLV_FEC_STACK_BGP_LAB_v6, "BGP labeled IPv6 prefix"},
244 { TLV_FEC_STACK_GEN_IPv4, "Generic IPv4 prefix"},
245 { TLV_FEC_STACK_GEN_IPv6, "Generic IPv6 prefix"},
246 { TLV_FEC_STACK_NIL, "Nil FEC"},
247 { TLV_FEC_VENDOR_PRIVATE_START, "Vendor Private"},
251 static const value_string mpls_echo_tlv_pad[] = {
252 { 1, "Drop Pad TLV from reply" },
253 { 2, "Copy Pad TLV to reply" },
257 #define TLV_DS_MAP_ADDR_IPv4 1
258 #define TLV_DS_MAP_ADDR_UNNUM_IPv4 2
259 #define TLV_DS_MAP_ADDR_IPv6 3
260 #define TLV_DS_MAP_ADDR_UNNUM_IPv6 4
262 static const value_string mpls_echo_tlv_ds_map_addr_type[] = {
263 {TLV_DS_MAP_ADDR_IPv4, "IPv4 Numbered"},
264 {TLV_DS_MAP_ADDR_UNNUM_IPv4, "IPv4 Unnumbered"},
265 {TLV_DS_MAP_ADDR_IPv6, "IPv6 Numbered"},
266 {TLV_DS_MAP_ADDR_UNNUM_IPv6, "IPv6 Unnumbered"},
270 #define TLV_DS_MAP_HASH_NO_MP 0
271 #define TLV_DS_MAP_HASH_LABEL 1
272 #define TLV_DS_MAP_HASH_IP 2
273 #define TLV_DS_MAP_HASH_LABEL_RANGE 3
274 #define TLV_DS_MAP_HASH_IP_RANGE 4
275 #define TLV_DS_MAP_HASH_NO_LABEL 5
276 #define TLV_DS_MAP_HASH_ALL_IP 6
277 #define TLV_DS_MAP_HASH_NO_MATCH 7
278 #define TLV_DS_MAP_HASH_BITMASK_IP 8
279 #define TLV_DS_MAP_HASH_BITMASK_LABEL 9
281 static const value_string mpls_echo_tlv_ds_map_hash_type[] = {
282 {TLV_DS_MAP_HASH_NO_MP, "no multipath"},
283 {TLV_DS_MAP_HASH_LABEL, "label"},
284 {TLV_DS_MAP_HASH_IP, "IP address"},
285 {TLV_DS_MAP_HASH_LABEL_RANGE, "label range"},
286 {TLV_DS_MAP_HASH_IP_RANGE, "IP address range"},
287 {TLV_DS_MAP_HASH_NO_LABEL, "no more labels"},
288 {TLV_DS_MAP_HASH_ALL_IP, "All IP addresses"},
289 {TLV_DS_MAP_HASH_NO_MATCH, "no match"},
290 {TLV_DS_MAP_HASH_BITMASK_IP, "Bit-masked IPv4 address set"},
291 {TLV_DS_MAP_HASH_BITMASK_LABEL, "Bit-masked label set"},
295 static const value_string mpls_echo_tlv_ds_map_mp_proto[] = {
306 * Dissector for FEC sub-TLVs
309 dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
311 proto_tree *ti = NULL, *tlv_fec_tree = NULL;
312 guint16 index = 1, nil_index = 1, type, saved_type;
313 int length, nil_length, pad;
315 guint8 exp, bos, ttl;
318 while (rem >= 4){ /* Type, Length */
319 type = tvb_get_ntohs(tvb, offset);
321 /* Check for Vendor Private sub-TLVs */
322 if(type >= TLV_FEC_VENDOR_PRIVATE_START) /* && <= TLV_FEC_VENDOR_PRIVATE_END always true */
323 type = TLV_FEC_VENDOR_PRIVATE_START;
325 length = tvb_get_ntohs(tvb, offset + 2);
326 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "FEC Element %u: %s",
327 index, val_to_str(type, mpls_echo_tlv_fec_names,
328 "Unknown FEC type (0x%04X)"));
329 tlv_fec_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_fec);
330 if(tlv_fec_tree == NULL) return;
332 /* FEC sub-TLV Type and Length */
333 proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb,
334 offset, 2, saved_type, "Type: %s (%u)",
335 val_to_str(type, mpls_echo_tlv_fec_names, "Unknown sub-TLV type"), saved_type);
337 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_len, tvb, offset + 2,
340 if (length + 4 > rem){
341 proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
342 "Error processing FEC sub-TLV: length is %u and reminder is %u",
347 /* FEC sub-TLV Value */
349 case TLV_FEC_STACK_LDP_IPv4:
350 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4,
351 tvb, offset + 4, 4, FALSE);
352 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
353 tvb, offset + 8, 1, FALSE);
355 proto_tree_add_text(tlv_fec_tree, tvb, offset + 9, 3, "Padding");
357 case TLV_FEC_STACK_LDP_IPv6:
358 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6,
359 tvb, offset + 4, 16, FALSE);
360 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
361 tvb, offset + 20, 1, FALSE);
363 proto_tree_add_text(tlv_fec_tree, tvb, offset + 21, 3, "Padding");
365 case TLV_FEC_STACK_RSVP_IPv4:
367 proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
368 "Error processing sub-TLV: length is %d, should be 20", length);
371 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
372 tvb, offset + 4, 4, FALSE);
373 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
374 tvb, offset + 8, 2, FALSE);
375 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
376 tvb, offset + 10, 2, FALSE);
377 proto_tree_add_text(tlv_fec_tree, tvb, offset + 12, 4,
378 "Extended Tunnel ID: 0x%08X (%s)", tvb_get_ntohl(tvb, offset + 12),
379 ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
380 proto_tree_add_item_hidden(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
381 tvb, offset + 12, 4, FALSE);
382 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
383 tvb, offset + 16, 4, FALSE);
384 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
385 tvb, offset + 20, 2, FALSE);
386 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
387 tvb, offset + 22, 2, FALSE);
389 case TLV_FEC_STACK_RSVP_IPv6:
391 proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
392 "Error processing sub-TLV: length is %d, should be 56", length);
395 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
396 tvb, offset + 4, 16, FALSE);
397 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
398 tvb, offset + 20, 2, FALSE);
399 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
400 tvb, offset + 22, 2, FALSE);
401 proto_tree_add_text(tlv_fec_tree, tvb, offset + 24, 16,
402 "Extended Tunnel ID: 0x%s (%s)",
403 tvb_bytes_to_str(tvb, offset + 24, 16),
404 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 24, 16)));
405 proto_tree_add_item_hidden(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
406 tvb, offset + 24, 16, FALSE);
407 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
408 tvb, offset + 40, 16, FALSE);
409 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
410 tvb, offset + 56, 2, FALSE);
411 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
412 tvb, offset + 58, 2, FALSE);
414 case TLV_FEC_STACK_L2_CID_OLD:
415 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
416 tvb, offset + 4, 4, FALSE);
417 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
418 tvb, offset + 8, 4, FALSE);
419 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
420 tvb, offset + 12, 2, FALSE);
421 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
422 tvb, offset + 14, 2, FALSE);
424 case TLV_FEC_STACK_L2_CID_NEW:
426 proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
427 "Error processing sub-TLV: length is %d, should be 14", length);
430 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_sender,
431 tvb, offset + 4, 4, FALSE);
432 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_remote,
433 tvb, offset + 8, 4, FALSE);
434 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_vcid,
435 tvb, offset + 12, 4, FALSE);
436 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_encap,
437 tvb, offset + 16, 2, FALSE);
438 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_l2cid_mbz,
439 tvb, offset + 18, 2, FALSE);
441 case TLV_FEC_VENDOR_PRIVATE_START:
442 if (length < 4) { /* SMI Enterprise code */
443 proto_tree_add_text(tlv_fec_tree, tvb, offset + 4, length,
444 "Error processing Vendor Private sub-TLV: length is %d, should be >= 4",
447 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_vendor, tvb,
448 offset + 4, 4, FALSE);
449 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_value, tvb,
450 offset + 8, length - 4, FALSE);
453 case TLV_FEC_STACK_BGP_LAB_v4:
454 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_nh,
455 tvb, offset + 4, 4, FALSE);
456 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv4,
457 tvb, offset + 8, 4, FALSE);
458 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
459 tvb, offset + 12, 1, FALSE);
461 proto_tree_add_text(tlv_fec_tree, tvb, offset + 13, 3, "Padding");
463 case TLV_FEC_STACK_GEN_IPv4:
464 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4,
465 tvb, offset + 4, 4, FALSE);
466 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4_mask,
467 tvb, offset + 8, 1, FALSE);
469 proto_tree_add_text(tlv_fec_tree, tvb, offset + 9, 3, "Padding");
471 case TLV_FEC_STACK_GEN_IPv6:
472 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6,
473 tvb, offset + 4, 16, FALSE);
474 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6_mask,
475 tvb, offset + 20, 1, FALSE);
477 proto_tree_add_text(tlv_fec_tree, tvb, offset + 21, 3, "Padding");
479 case TLV_FEC_STACK_NIL:
481 while (nil_length >= 4){
482 decode_mpls_label(tvb, offset + 4, &label, &exp, &bos, &ttl);
483 if (label <= LABEL_MAX_RESERVED){
484 proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
485 tvb, offset + 4, 3, label, "Label %u: %u (%s)", nil_index, label,
486 val_to_str(label, special_labels, "Reserved - Unknown"));
488 proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
489 tvb, offset + 4, 3, label, "Label %u: %u", nil_index, label);
497 case TLV_FEC_STACK_RES:
498 case TLV_FEC_STACK_VPN_IPv4:
499 case TLV_FEC_STACK_VPN_IPv6:
500 case TLV_FEC_STACK_L2_VPN:
503 proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value,
504 tvb, offset + 4, length, FALSE);
509 * Check for padding based on sub-TLV length alignment;
510 * FEC sub-TLVs is zero-padded to align to four-octet boundary.
513 pad = 4 - (length % 4);
514 if (length + 4 + pad > rem){
515 proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
516 "Error processing FEC sub-TLV: padded length is %u and reminder is %u",
517 length + pad, rem - 4);
520 proto_tree_add_text(tlv_fec_tree, tvb, offset + 4 + length, pad, "Padding");
526 offset += 4 + length;
533 * Dissector for Downstream Mapping TLV
536 dissect_mpls_echo_tlv_ds_map(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
538 proto_tree *ti = NULL, *tlv_ds_map_tree = NULL;
539 guint16 mplen, index = 1;
541 guint8 exp, bos, proto;
542 guint8 hash_type, addr_type;
544 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mtu, tvb,
546 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_addr_type, tvb,
547 offset + 2, 1, FALSE);
548 ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_res, tvb,
549 offset + 3, 1, FALSE);
550 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
552 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_res, tvb,
553 offset + 3, 1, FALSE);
554 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_i, tvb,
555 offset + 3, 1, FALSE);
556 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_n, tvb,
557 offset + 3, 1, FALSE);
559 addr_type = tvb_get_guint8(tvb, offset + 2);
561 case TLV_DS_MAP_ADDR_IPv4:
562 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
563 offset + 4, 4, FALSE);
564 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ip, tvb,
565 offset + 8, 4, FALSE);
567 case TLV_DS_MAP_ADDR_UNNUM_IPv4:
568 case TLV_DS_MAP_ADDR_UNNUM_IPv6:
569 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
570 offset + 4, 4, FALSE);
571 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_if_index, tvb,
572 offset + 8, 4, FALSE);
574 case TLV_DS_MAP_ADDR_IPv6:
575 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ipv6, tvb,
576 offset + 4, 16, FALSE);
577 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ipv6, tvb,
578 offset + 20, 16, FALSE);
583 proto_tree_add_text(tree, tvb, offset + 4, 8,
584 "Error processing TLV: Unknown Address Type of %u",
588 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_hash_type, tvb,
589 offset + 12, 1, FALSE);
590 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_depth, tvb,
591 offset + 13, 1, FALSE);
592 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_muti_len, tvb,
593 offset + 14, 2, FALSE);
595 /* Get the Multipath Length and Hash Type */
596 mplen = tvb_get_ntohs(tvb, offset + 14);
597 hash_type = tvb_get_guint8(tvb, offset + 12);
602 proto_tree_add_text(tree, tvb, offset, rem,
603 "Error processing TLV: Multi Path length is %d and reminder is %u",
610 case TLV_DS_MAP_HASH_IP:
612 proto_tree_add_text(tree, tvb, offset, mplen,
613 "Multi Path length is %u and should be 4", mplen);
616 ti = proto_tree_add_text(tree, tvb, offset, 4,
617 "Multipath Information");
618 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
619 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
622 case TLV_DS_MAP_HASH_IP_RANGE:
624 proto_tree_add_text(tree, tvb, offset, mplen,
625 "Multi Path length is %u and should be 8", mplen);
628 ti = proto_tree_add_text(tree, tvb, offset, 8,
629 "Multipath Information");
630 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
631 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_low, tvb,
633 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_high, tvb,
634 offset + 4, 4, FALSE);
636 case TLV_DS_MAP_HASH_NO_MP:
637 case TLV_DS_MAP_HASH_NO_LABEL:
638 case TLV_DS_MAP_HASH_ALL_IP:
639 case TLV_DS_MAP_HASH_NO_MATCH:
640 proto_tree_add_text(tree, tvb, offset, mplen,
641 "No Multipath Information");
643 case TLV_DS_MAP_HASH_BITMASK_IP:
645 proto_tree_add_text(tree, tvb, offset, mplen,
646 "Multi Path length is %u and should be >= 4", mplen);
649 ti = proto_tree_add_text(tree, tvb, offset, mplen,
650 "Multipath Information");
651 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
652 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
655 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_mask, tvb,
656 offset + 4, mplen - 4, FALSE);
659 proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mp_value, tvb,
660 offset, mplen, FALSE);
668 decode_mpls_label(tvb, offset, &label, &exp, &bos, &proto);
669 ti = proto_tree_add_text(tree, tvb, offset, 4, "Downstream Label Element %u",
671 tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
672 proto_item_append_text(ti, ", Label: %u", label);
673 if (label <= LABEL_MAX_RESERVED){
674 proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
675 tvb, offset, 3, label, "Downstream Label: %u (%s)", label,
676 val_to_str(label, special_labels, "Reserved - Unknown"));
677 proto_item_append_text(ti, " (%s)", val_to_str(label, special_labels,
678 "Reserved - Unknown"));
680 proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
681 tvb, offset, 3, label, "Downstream Label: %u", label);
683 proto_item_append_text(ti, ", Exp: %u, BOS: %u", exp, bos);
684 proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_exp,
685 tvb, offset + 2, 1, exp, "Downstream Exp: %u", exp);
686 proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_bos,
687 tvb, offset + 2, 1, bos, "Downstream BOS: %u", bos);
688 proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_proto,
689 tvb, offset + 3, 1, FALSE);
690 proto_item_append_text(ti, ", Protocol: %u (%s)", proto, val_to_str(proto,
691 mpls_echo_tlv_ds_map_mp_proto, "Unknown"));
699 * Dissector for IPv4 and IPv6 Interface and Label Stack Object
702 dissect_mpls_echo_tlv_ilso(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean is_ipv6)
704 proto_tree *ti = NULL, *tlv_ilso = NULL;
707 guint8 exp, bos, ttl;
710 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_addr, tvb,
712 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_int_addr, tvb,
713 offset + 16, 16, FALSE);
718 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_addr, tvb,
720 proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_int_addr, tvb,
721 offset + 4, 4, FALSE);
729 decode_mpls_label(tvb, offset, &label, &exp, &bos, &ttl);
730 ti = proto_tree_add_text(tree, tvb, offset, 4, "Label Stack Element %u",
732 tlv_ilso = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ilso);
733 proto_item_append_text(ti, ", Label: %u", label);
734 if (label <= LABEL_MAX_RESERVED){
735 proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
736 tvb, offset, 3, label, "Label: %u (%s)", label,
737 val_to_str(label, special_labels, "Reserved - Unknown"));
738 proto_item_append_text(ti, " (%s)", val_to_str(label, special_labels,
739 "Reserved - Unknown"));
741 proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
742 tvb, offset, 3, label, "Label: %u", label);
744 proto_item_append_text(ti, ", Exp: %u, BOS: %u, TTL: %u",
746 proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_exp,
747 tvb, offset + 2, 1, exp, "Exp: %u", exp);
748 proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_bos,
749 tvb, offset + 2, 1, bos, "BOS: %u", bos);
750 proto_tree_add_item(tlv_ilso, hf_mpls_echo_tlv_ilso_ttl,
751 tvb, offset + 3, 1, FALSE);
759 dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean in_errored);
762 * Dissector for Errored TLVs
765 dissect_mpls_echo_tlv_errored(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
767 int errored_tlv_length;
770 errored_tlv_length = dissect_mpls_echo_tlv(tvb, offset, tree, rem, TRUE);
771 rem -= errored_tlv_length;
772 offset += errored_tlv_length;
777 * Dissector for MPLS Echo TLVs and return bytes consumed
780 dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean in_errored)
782 guint16 type, saved_type;
784 proto_tree *ti = NULL, *mpls_echo_tlv_tree = NULL;
786 length = tvb_reported_length_remaining(tvb, offset);
787 rem = MIN(rem, length);
789 if( rem < 4 ) { /* Type Length */
791 proto_tree_add_text(tree, tvb, offset, rem,
792 "Error processing TLV: length is %d, should be >= 4",
796 type = tvb_get_ntohs(tvb, offset);
797 length = tvb_get_ntohs(tvb, offset + 2),
798 rem -= 4; /* do not count Type Length */
799 length = MIN(length, rem);
802 /* Check for Vendor Private TLVs */
804 if(type >= TLV_VENDOR_PRIVATE_START) /* && <= TLV_VENDOR_PRIVATE_END always true */
805 type = TLV_VENDOR_PRIVATE_START;
807 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s%s",
808 in_errored ? "Errored TLV Type: " : "",
809 val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type (0x%04X)"));
810 mpls_echo_tlv_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv);
811 if(mpls_echo_tlv_tree == NULL) return length+4;
813 /* MPLS Echo TLV Type and Length */
815 proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_errored_type, tvb,
816 offset, 2, saved_type, "Errored TLV Type: %s (%u)",
817 val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), saved_type);
819 proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
820 offset, 2, saved_type, "Type: %s (%u)",
821 val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), saved_type);
823 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_len, tvb, offset + 2, 2, FALSE);
825 /* MPLS Echo TLV Value */
827 return 4; /* Empty TLV, return Type and Length consumed. */
830 case TLV_TARGET_FEC_STACK:
831 dissect_mpls_echo_tlv_fec(tvb, offset + 4, mpls_echo_tlv_tree, length);
834 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padaction, tvb,
835 offset + 4, 1, FALSE);
837 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
838 offset + 5, length - 1, FALSE);
840 case TLV_VENDOR_CODE:
841 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
842 offset + 4, 4, FALSE);
846 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
847 "Error processing TLV: length is %d, should be >= 8",
851 dissect_mpls_echo_tlv_ilso(tvb, offset + 4, mpls_echo_tlv_tree, length, FALSE);
855 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
856 "Error processing TLV: length is %d, should be >= 32",
860 dissect_mpls_echo_tlv_ilso(tvb, offset + 4, mpls_echo_tlv_tree, length, TRUE);
864 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
865 "Error processing TLV: length is %d, should be 4",
869 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv4,
870 tvb, offset + 4, 4, FALSE);
874 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
875 "Error processing TLV: length is %d, should be 16",
879 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv6,
880 tvb, offset + 4, 16, FALSE);
882 case TLV_VENDOR_PRIVATE_START:
883 if (length < 4) { /* SMI Enterprise code */
884 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
885 "Error processing Vendor Private TLV: length is %d, should be >= 4",
888 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
889 offset + 4, 4, FALSE);
890 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
891 offset + 8, length - 4, FALSE);
894 case TLV_DOWNSTREAM_MAPPING:
896 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
897 "Error processing TLV: length is %d, should be >= 16",
901 dissect_mpls_echo_tlv_ds_map(tvb, offset + 4, mpls_echo_tlv_tree, length);
903 case TLV_ERRORED_TLV:
905 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
906 offset + 4, length, FALSE);
908 dissect_mpls_echo_tlv_errored(tvb, offset + 4, mpls_echo_tlv_tree, length);
912 proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
913 "Error processing TLV: length is %d, should be 4",
917 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos, tvb,
918 offset + 4, 1, FALSE);
919 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos_mbz, tvb,
920 offset + 5, 3, FALSE);
924 proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
925 offset + 4, length, FALSE);
929 return length + 4; /* Length of the Value field + Type Length */
932 #define MSGTYPE_MPLS_ECHO(msgtype) ((msgtype == 1) || (msgtype == 2))
933 #define MSGTYPE_DATAPLANE(msgtype) ((msgtype == 3) || (msgtype == 4))
936 * Dissector for MPLS Echo (LSP PING) packets
939 dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
941 int offset = 0, rem = 0, len;
942 proto_item *ti = NULL;
943 proto_tree *mpls_echo_tree = NULL, *mpls_echo_gflags = NULL;
945 const guint8 *ts_sent, *ts_rec;
947 /* If version != 1 we assume it's not an mpls ping packet */
948 if (!tvb_bytes_exist(tvb, 0, 5)) {
949 return; /* Not enough information to tell version and message type. */
951 if (tvb_get_ntohs(tvb, 0) != 1) {
952 return; /* Not version 1. */
955 if (check_col(pinfo->cinfo, COL_PROTOCOL))
956 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPLS ECHO");
958 rem = tvb_reported_length_remaining(tvb, offset);
960 /* Get the message type and fill in the Column info */
961 msgtype = tvb_get_guint8(tvb, offset + 4);
963 /* The minimum fixed part of the packet is 16 Bytes or 32 Bytes depending on Msg Type */
964 if( ((!MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 16)) ||
965 ((MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 32)) ) {
966 if( check_col(pinfo->cinfo, COL_INFO) )
967 col_set_str(pinfo->cinfo, COL_INFO, "Malformed Message");
969 ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, FALSE);
970 mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
971 proto_tree_add_text(mpls_echo_tree, tvb, offset, rem,
972 "Error processing Message: length is %d, should be >= %u",
973 rem, (MSGTYPE_MPLS_ECHO(msgtype)) ? 32 : 16);
978 if (check_col(pinfo->cinfo, COL_INFO))
979 col_set_str(pinfo->cinfo, COL_INFO,
980 val_to_str(msgtype, mpls_echo_msgtype, "Unknown Message Type (0x%02X)"));
985 /* Add subtree and dissect the fixed part of the message */
986 ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, FALSE);
987 mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
989 proto_tree_add_item(mpls_echo_tree,
990 hf_mpls_echo_version, tvb, offset, 2, FALSE);
992 if(MSGTYPE_MPLS_ECHO(msgtype)){
993 ti = proto_tree_add_item(mpls_echo_tree,
994 hf_mpls_echo_gflags, tvb, offset + 2, 2, FALSE);
995 mpls_echo_gflags = proto_item_add_subtree(ti, ett_mpls_echo_gflags);
996 proto_tree_add_item(mpls_echo_gflags,
997 hf_mpls_echo_flag_sbz, tvb, offset + 2, 2, FALSE);
998 proto_tree_add_item(mpls_echo_gflags,
999 hf_mpls_echo_flag_v, tvb, offset + 2, 2, FALSE);
1001 proto_tree_add_item(mpls_echo_tree,
1002 hf_mpls_echo_mbz, tvb, offset + 2, 2, FALSE);
1005 proto_tree_add_item(mpls_echo_tree,
1006 hf_mpls_echo_msgtype, tvb, offset + 4, 1, FALSE);
1007 proto_tree_add_item(mpls_echo_tree,
1008 hf_mpls_echo_replymode, tvb, offset + 5, 1, FALSE);
1009 proto_tree_add_item(mpls_echo_tree,
1010 hf_mpls_echo_returncode, tvb, offset + 6, 1, FALSE);
1011 proto_tree_add_item(mpls_echo_tree,
1012 hf_mpls_echo_returnsubcode, tvb, offset + 7, 1, FALSE);
1013 proto_tree_add_item(mpls_echo_tree,
1014 hf_mpls_echo_handle, tvb, offset + 8, 4, FALSE);
1015 proto_tree_add_item(mpls_echo_tree,
1016 hf_mpls_echo_sequence, tvb, offset + 12, 4, FALSE);
1018 if(MSGTYPE_MPLS_ECHO(msgtype)){
1019 /* Using NTP routine to calculate the timestamp */
1020 ts_sent = tvb_get_ptr(tvb, 16, 8);
1021 proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
1022 offset + 16, 8, ts_sent, "Timestamp Sent: %s", ntp_fmt_ts(ts_sent));
1023 ts_rec = tvb_get_ptr(tvb, 24, 8);
1024 proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
1025 offset + 24, 8, ts_rec, "Timestamp Received: %s", ntp_fmt_ts(ts_rec));
1030 if(MSGTYPE_MPLS_ECHO(msgtype)){
1038 /* Dissect all TLVs */
1039 while(tvb_reported_length_remaining(tvb, offset) > 0 ) {
1040 len = dissect_mpls_echo_tlv(tvb, offset, mpls_echo_tree, rem, FALSE);
1048 /* Register the protocol with Wireshark */
1051 proto_register_mpls_echo(void)
1054 static hf_register_info hf[] = {
1055 { &hf_mpls_echo_version,
1056 { "Version", "mpls_echo.version",
1057 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Version Number", HFILL}
1059 { &hf_mpls_echo_mbz,
1060 { "MBZ", "mpls_echo.mbz",
1061 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Must be Zero", HFILL}
1063 { &hf_mpls_echo_gflags,
1064 { "Global Flags", "mpls_echo.flags",
1065 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Global Flags", HFILL}
1067 { &hf_mpls_echo_flag_sbz,
1068 { "Reserved", "mpls_echo.flag_sbz",
1069 FT_UINT16, BASE_HEX, NULL, 0xFFFE, "MPLS ECHO Reserved Flags", HFILL}
1071 { &hf_mpls_echo_flag_v,
1072 { "Validate FEC Stack", "mpls_echo.flag_v",
1073 FT_BOOLEAN, 16, NULL, 0x0001, "MPLS ECHO Validate FEC Stack Flag", HFILL}
1075 { &hf_mpls_echo_msgtype,
1076 { "Message Type", "mpls_echo.msg_type",
1077 FT_UINT8, BASE_DEC, VALS(mpls_echo_msgtype), 0x0, "MPLS ECHO Message Type", HFILL}
1079 { &hf_mpls_echo_replymode,
1080 { "Reply Mode", "mpls_echo.reply_mode",
1081 FT_UINT8, BASE_DEC, VALS(mpls_echo_replymode), 0x0, "MPLS ECHO Reply Mode", HFILL}
1083 { &hf_mpls_echo_returncode,
1084 { "Return Code", "mpls_echo.return_code",
1085 FT_UINT8, BASE_DEC, VALS(mpls_echo_returncode), 0x0, "MPLS ECHO Return Code", HFILL}
1087 { &hf_mpls_echo_returnsubcode,
1088 { "Return Subcode", "mpls_echo.return_subcode",
1089 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO Return Subcode", HFILL}
1091 { &hf_mpls_echo_handle,
1092 { "Sender's Handle", "mpls_echo.sender_handle",
1093 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO Sender's Handle", HFILL}
1095 { &hf_mpls_echo_sequence,
1096 { "Sequence Number", "mpls_echo.sequence",
1097 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO Sequence Number", HFILL}
1099 { &hf_mpls_echo_ts_sent,
1100 { "Timestamp Sent", "mpls_echo.timestamp_sent",
1101 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Timestamp Sent", HFILL}
1103 { &hf_mpls_echo_ts_rec,
1104 { "Timestamp Received", "mpls_echo.timestamp_rec",
1105 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Timestamp Received", HFILL}
1107 { &hf_mpls_echo_tlv_type,
1108 { "Type", "mpls_echo.tlv.type",
1109 FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_type_names), 0x0,
1110 "MPLS ECHO TLV Type", HFILL}
1112 { &hf_mpls_echo_tlv_len,
1113 { "Length", "mpls_echo.tlv.len",
1114 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Length", HFILL}
1116 { &hf_mpls_echo_tlv_value,
1117 { "Value", "mpls_echo.tlv.value",
1118 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Value", HFILL}
1120 { &hf_mpls_echo_tlv_fec_type,
1121 { "Type", "mpls_echo.tlv.fec.type",
1122 FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_fec_names), 0x0,
1123 "MPLS ECHO TLV FEC Stack Type", HFILL}
1125 { &hf_mpls_echo_tlv_fec_len,
1126 { "Length", "mpls_echo.tlv.fec.len",
1127 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Length", HFILL}
1129 { &hf_mpls_echo_tlv_fec_value,
1130 { "Value", "mpls_echo.tlv.fec.value",
1131 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Value", HFILL}
1133 { &hf_mpls_echo_tlv_fec_ldp_ipv4,
1134 { "IPv4 Prefix", "mpls_echo.tlv.fec.ldp_ipv4",
1135 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4", HFILL}
1137 { &hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
1138 { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv4_mask",
1139 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4 Prefix Length", HFILL}
1141 { &hf_mpls_echo_tlv_fec_ldp_ipv6,
1142 { "IPv6 Prefix", "mpls_echo.tlv.fec.ldp_ipv6",
1143 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6", HFILL}
1145 { &hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
1146 { "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv6_mask",
1147 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6 Prefix Length", HFILL}
1149 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
1150 { "IPv4 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv4_ep",
1151 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Tunnel Endpoint Address", HFILL}
1153 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_endpoint,
1154 { "IPv6 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv6_ep",
1155 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Tunnel Endpoint Address", HFILL}
1157 { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz1,
1158 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz1",
1159 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
1161 { &hf_mpls_echo_tlv_fec_rsvp_ip_tunnel_id,
1162 { "Tunnel ID", "mpls_echo.tlv.fec.rsvp_ip_tun_id",
1163 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP Tunnel ID", HFILL}
1165 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ext_tunnel_id,
1166 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv4_ext_tun_id",
1167 FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Extended Tunnel ID", HFILL}
1169 { &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_sender,
1170 { "IPv4 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv4_sender",
1171 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
1173 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ext_tunnel_id,
1174 { "Extended Tunnel ID", "mpls_echo.tlv.fec.rsvp_ipv6_ext_tun_id",
1175 FT_BYTES, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv6 Extended Tunnel ID", HFILL}
1177 { &hf_mpls_echo_tlv_fec_rsvp_ipv6_ipv6_sender,
1178 { "IPv6 Tunnel sender address", "mpls_echo.tlv.fec.rsvp_ipv6_sender",
1179 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP IPv4 Sender", HFILL}
1181 { &hf_mpls_echo_tlv_fec_rsvp_ip_mbz2,
1182 { "Must Be Zero", "mpls_echo.tlv.fec.rsvp_ip_mbz2",
1183 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP MBZ", HFILL}
1185 { &hf_mpls_echo_tlv_fec_rsvp_ip_lsp_id,
1186 { "LSP ID", "mpls_echo.tlv.fec.rsvp_ip_lsp_id",
1187 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack RSVP LSP ID", HFILL}
1189 { &hf_mpls_echo_tlv_fec_l2cid_sender,
1190 { "Sender's PE Address", "mpls_echo.tlv.fec.l2cid_sender",
1191 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Sender", HFILL}
1193 { &hf_mpls_echo_tlv_fec_l2cid_remote,
1194 { "Remote PE Address", "mpls_echo.tlv.fec.l2cid_remote",
1195 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID Remote", HFILL}
1197 { &hf_mpls_echo_tlv_fec_l2cid_vcid,
1198 { "VC ID", "mpls_echo.tlv.fec.l2cid_vcid",
1199 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID VCID", HFILL}
1201 { &hf_mpls_echo_tlv_fec_l2cid_encap,
1202 { "Encapsulation", "mpls_echo.tlv.fec.l2cid_encap",
1203 FT_UINT16, BASE_DEC, VALS(fec_vc_types_vals), 0x0, "MPLS ECHO TLV FEC Stack L2CID Encapsulation", HFILL}
1205 { &hf_mpls_echo_tlv_fec_l2cid_mbz,
1206 { "MBZ", "mpls_echo.tlv.fec.l2cid_mbz",
1207 FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID MBZ", HFILL}
1209 { &hf_mpls_echo_tlv_fec_bgp_nh,
1210 { "BGP Next Hop", "mpls_echo.tlv.fec.bgp_nh",
1211 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Next Hop", HFILL}
1213 { &hf_mpls_echo_tlv_fec_bgp_ipv4,
1214 { "IPv4 Prefix", "mpls_echo.tlv.fec.bgp_ipv4",
1215 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv4", HFILL}
1217 { &hf_mpls_echo_tlv_fec_bgp_len,
1218 { "Prefix Length", "mpls_echo.tlv.fec.bgp_len",
1219 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Prefix Length", HFILL}
1221 { &hf_mpls_echo_tlv_fec_gen_ipv4,
1222 { "IPv4 Prefix", "mpls_echo.tlv.fec.gen_ipv4",
1223 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4", HFILL}
1225 { &hf_mpls_echo_tlv_fec_gen_ipv4_mask,
1226 { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv4_mask",
1227 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4 Prefix Length", HFILL}
1229 { &hf_mpls_echo_tlv_fec_gen_ipv6,
1230 { "IPv6 Prefix", "mpls_echo.tlv.fec.gen_ipv6",
1231 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6", HFILL}
1233 { &hf_mpls_echo_tlv_fec_gen_ipv6_mask,
1234 { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv6_mask",
1235 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6 Prefix Length", HFILL}
1237 { &hf_mpls_echo_tlv_fec_nil_label,
1238 { "Label", "mpls_echo.tlv.fec.nil_label",
1239 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV FEC Stack NIL Label", HFILL}
1241 { &hf_mpls_echo_tlv_ds_map_mtu,
1242 { "MTU", "mpls_echo.tlv.ds_map.mtu",
1243 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map MTU", HFILL}
1245 { &hf_mpls_echo_tlv_ds_map_addr_type,
1246 { "Address Type", "mpls_echo.tlv.ds_map.addr_type",
1247 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_addr_type), 0x0,
1248 "MPLS ECHO TLV Downstream Map Address Type", HFILL}
1250 { &hf_mpls_echo_tlv_ds_map_res,
1251 { "DS Flags", "mpls_echo.tlv.ds_map.res",
1252 FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map DS Flags", HFILL}
1254 { &hf_mpls_echo_tlv_ds_map_flag_res,
1255 { "MBZ", "mpls_echo.tlv.ds_map.flag_res",
1256 FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Downstream Map Reserved Flags", HFILL}
1258 { &hf_mpls_echo_tlv_ds_map_flag_i,
1259 { "Interface and Label Stack Request", "mpls_echo.tlv.ds_map.flag_i",
1260 FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Downstream Map I-Flag", HFILL}
1262 { &hf_mpls_echo_tlv_ds_map_flag_n,
1263 { "Treat as Non-IP Packet", "mpls_echo.tlv.ds_map.flag_n",
1264 FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Downstream Map N-Flag", HFILL}
1266 { &hf_mpls_echo_tlv_ds_map_ds_ip,
1267 { "Downstream IP Address", "mpls_echo.tlv.ds_map.ds_ip",
1268 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IP Address", HFILL}
1270 { &hf_mpls_echo_tlv_ds_map_int_ip,
1271 { "Downstream Interface Address", "mpls_echo.tlv.ds_map.int_ip",
1272 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Address", HFILL}
1274 { &hf_mpls_echo_tlv_ds_map_if_index,
1275 { "Upstream Interface Index", "mpls_echo.tlv.ds_map.if_index",
1276 FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Index", HFILL}
1278 { &hf_mpls_echo_tlv_ds_map_ds_ipv6,
1279 { "Downstream IPv6 Address", "mpls_echo.tlv.ds_map.ds_ipv6",
1280 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IPv6 Address", HFILL}
1282 { &hf_mpls_echo_tlv_ds_map_int_ipv6,
1283 { "Downstream Interface IPv6 Address", "mpls_echo.tlv.ds_map.int_ipv6",
1284 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface IPv6 Address", HFILL}
1286 { &hf_mpls_echo_tlv_ds_map_hash_type,
1287 { "Multipath Type", "mpls_echo.tlv.ds_map.hash_type",
1288 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_hash_type), 0x0,
1289 "MPLS ECHO TLV Downstream Map Multipath Type", HFILL}
1291 { &hf_mpls_echo_tlv_ds_map_depth,
1292 { "Depth Limit", "mpls_echo.tlv.ds_map.depth",
1293 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Depth Limit", HFILL}
1295 { &hf_mpls_echo_tlv_ds_map_muti_len,
1296 { "Multipath Length", "mpls_echo.tlv.ds_map.multi_len",
1297 FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Length", HFILL}
1299 { &hf_mpls_echo_tlv_ds_map_mp_ip,
1300 { "IP Address", "mpls_echo.tlv.ds_map_mp.ip",
1301 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath IP Address", HFILL}
1303 { &hf_mpls_echo_tlv_ds_map_mp_mask,
1304 { "Mask", "mpls_echo.tlv.ds_map_mp.mask",
1305 FT_BYTES, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Mask", HFILL}
1307 { &hf_mpls_echo_tlv_ds_map_mp_ip_low,
1308 { "IP Address Low", "mpls_echo.tlv.ds_map_mp.ip_low",
1309 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Low IP Address", HFILL}
1311 { &hf_mpls_echo_tlv_ds_map_mp_ip_high,
1312 { "IP Address High", "mpls_echo.tlv.ds_map_mp.ip_high",
1313 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath High IP Address", HFILL}
1315 { &hf_mpls_echo_tlv_ds_map_mp_value,
1316 { "Multipath Value", "mpls_echo.tlv.ds_map_mp.value",
1317 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Multipath Value", HFILL}
1319 { &hf_mpls_echo_tlv_ds_map_mp_label,
1320 { "Downstream Label", "mpls_echo.tlv.ds_map.mp_label",
1321 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Downstream Map Downstream Label", HFILL}
1323 { &hf_mpls_echo_tlv_ds_map_mp_exp,
1324 { "Downstream Experimental", "mpls_echo.tlv.ds_map.mp_exp",
1325 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream Experimental", HFILL}
1327 { &hf_mpls_echo_tlv_ds_map_mp_bos,
1328 { "Downstream BOS", "mpls_echo.tlv.ds_map.mp_bos",
1329 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream BOS", HFILL}
1331 { &hf_mpls_echo_tlv_ds_map_mp_proto,
1332 { "Downstream Protocol", "mpls_echo.tlv.ds_map.mp_proto",
1333 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
1334 "MPLS ECHO TLV Downstream Map Downstream Protocol", HFILL}
1336 { &hf_mpls_echo_tlv_padaction,
1337 { "Pad Action", "mpls_echo.tlv.pad_action",
1338 FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_pad), 0x0, "MPLS ECHO Pad TLV Action", HFILL}
1340 { &hf_mpls_echo_tlv_padding,
1341 { "Padding", "mpls_echo.tlv.pad_padding",
1342 FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO Pad TLV Padding", HFILL}
1344 { &hf_mpls_echo_tlv_vendor,
1345 { "Vendor Id", "mpls_echo.tlv.vendor_id",
1346 FT_UINT32, BASE_DEC, VALS(sminmpec_values), 0x0, "MPLS ECHO Vendor Id", HFILL}
1348 { &hf_mpls_echo_tlv_ilso_ipv4_addr,
1349 { "Downstream IPv4 Address", "mpls_echo.tlv.ilso_ipv4.addr",
1350 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
1352 { &hf_mpls_echo_tlv_ilso_ipv4_int_addr,
1353 { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv4.int_addr",
1354 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
1356 { &hf_mpls_echo_tlv_ilso_ipv6_addr,
1357 { "Downstream IPv6 Address", "mpls_echo.tlv.ilso_ipv6.addr",
1358 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
1360 { &hf_mpls_echo_tlv_ilso_ipv6_int_addr,
1361 { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv6.int_addr",
1362 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
1364 { &hf_mpls_echo_tlv_ilso_label,
1365 { "Label", "mpls_echo.tlv.ilso_ipv4.label",
1366 FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Interface and Label Stack Label", HFILL}
1368 { &hf_mpls_echo_tlv_ilso_exp,
1369 { "Exp", "mpls_echo.tlv.ilso_ipv4.exp",
1370 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Exp", HFILL}
1372 { &hf_mpls_echo_tlv_ilso_bos,
1373 { "BOS", "mpls_echo.tlv.ilso_ipv4.bos",
1374 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack BOS", HFILL}
1376 { &hf_mpls_echo_tlv_ilso_ttl,
1377 { "TTL", "mpls_echo.tlv.ilso_ipv4.ttl",
1378 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack TTL", HFILL}
1380 { &hf_mpls_echo_tlv_rto_ipv4,
1381 { "Reply-to IPv4 Address", "mpls_echo.tlv.rto.ipv4",
1382 FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv4 Reply-To Object", HFILL}
1384 { &hf_mpls_echo_tlv_rto_ipv6,
1385 { "Reply-to IPv6 Address", "mpls_echo.tlv.rto.ipv6",
1386 FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv6 Reply-To Object", HFILL}
1388 { &hf_mpls_echo_tlv_reply_tos,
1389 { "Reply-TOS Byte", "mpls_echo.tlv.reply.tos",
1390 FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Reply-TOS Byte", HFILL}
1392 { &hf_mpls_echo_tlv_reply_tos_mbz,
1393 { "MBZ", "mpls_echo.tlv.reply.tos.mbz",
1394 FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Reply-TOS MBZ", HFILL}
1396 { &hf_mpls_echo_tlv_errored_type,
1397 { "Errored TLV Type", "mpls_echo.tlv.errored.type",
1398 FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_type_names), 0x0,
1399 "MPLS ECHO TLV Errored TLV Type", HFILL}
1403 static gint *ett[] = {
1405 &ett_mpls_echo_gflags,
1407 &ett_mpls_echo_tlv_fec,
1408 &ett_mpls_echo_tlv_ds_map,
1409 &ett_mpls_echo_tlv_ilso,
1412 module_t *mpls_echo_module;
1414 proto_mpls_echo = proto_register_protocol("Multiprotocol Label Switching Echo",
1415 "MPLS Echo", "mpls-echo");
1417 proto_register_field_array(proto_mpls_echo, hf, array_length(hf));
1418 proto_register_subtree_array(ett, array_length(ett));
1420 mpls_echo_module = prefs_register_protocol(proto_mpls_echo, proto_reg_handoff_mpls_echo);
1421 prefs_register_uint_preference(mpls_echo_module, "udp.port", "MPLS Echo UDP Port",
1422 "Set the UDP port for messages (if other"
1423 " than the default of 3503)",
1424 10, &global_mpls_echo_udp_port);
1429 proto_reg_handoff_mpls_echo(void)
1431 static gboolean mpls_echo_prefs_initialized = FALSE;
1432 static dissector_handle_t mpls_echo_handle;
1434 if(!mpls_echo_prefs_initialized) {
1435 mpls_echo_handle = create_dissector_handle(dissect_mpls_echo,
1437 mpls_echo_prefs_initialized = TRUE;
1439 dissector_delete("udp.port", mpls_echo_udp_port, mpls_echo_handle);
1442 mpls_echo_udp_port = global_mpls_echo_udp_port;
1443 dissector_add("udp.port", global_mpls_echo_udp_port, mpls_echo_handle);