aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mpls-echo.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-mpls-echo.c')
-rw-r--r--epan/dissectors/packet-mpls-echo.c832
1 files changed, 788 insertions, 44 deletions
diff --git a/epan/dissectors/packet-mpls-echo.c b/epan/dissectors/packet-mpls-echo.c
index ec2b2b99f8..9f0df19381 100644
--- a/epan/dissectors/packet-mpls-echo.c
+++ b/epan/dissectors/packet-mpls-echo.c
@@ -36,6 +36,7 @@
#include <epan/sminmpec.h>
#include "packet-ntp.h"
#include "packet-ldp.h"
+#include "packet-mpls.h"
#define UDP_PORT_MPLS_ECHO 3503
@@ -44,6 +45,9 @@ void proto_reg_handoff_mpls_echo(void);
static int proto_mpls_echo = -1;
static int hf_mpls_echo_version = -1;
static int hf_mpls_echo_mbz = -1;
+static int hf_mpls_echo_gflags = -1;
+static int hf_mpls_echo_flag_sbz = -1;
+static int hf_mpls_echo_flag_v = -1;
static int hf_mpls_echo_msgtype = -1;
static int hf_mpls_echo_replymode = -1;
static int hf_mpls_echo_returncode = -1;
@@ -77,13 +81,60 @@ static int hf_mpls_echo_tlv_fec_l2cid_remote = -1;
static int hf_mpls_echo_tlv_fec_l2cid_vcid = -1;
static int hf_mpls_echo_tlv_fec_l2cid_encap = -1;
static int hf_mpls_echo_tlv_fec_l2cid_mbz = -1;
+static int hf_mpls_echo_tlv_fec_bgp_nh = -1;
+static int hf_mpls_echo_tlv_fec_bgp_ipv4 = -1;
+static int hf_mpls_echo_tlv_fec_bgp_len = -1;
+static int hf_mpls_echo_tlv_fec_gen_ipv4 = -1;
+static int hf_mpls_echo_tlv_fec_gen_ipv4_mask = -1;
+static int hf_mpls_echo_tlv_fec_gen_ipv6 = -1;
+static int hf_mpls_echo_tlv_fec_gen_ipv6_mask = -1;
+static int hf_mpls_echo_tlv_fec_nil_label = -1;
+static int hf_mpls_echo_tlv_ds_map_mtu = -1;
+static int hf_mpls_echo_tlv_ds_map_addr_type = -1;
+static int hf_mpls_echo_tlv_ds_map_res = -1;
+static int hf_mpls_echo_tlv_ds_map_flag_res = -1;
+static int hf_mpls_echo_tlv_ds_map_flag_i = -1;
+static int hf_mpls_echo_tlv_ds_map_flag_n = -1;
+static int hf_mpls_echo_tlv_ds_map_ds_ip = -1;
+static int hf_mpls_echo_tlv_ds_map_int_ip = -1;
+static int hf_mpls_echo_tlv_ds_map_if_index = -1;
+static int hf_mpls_echo_tlv_ds_map_ds_ipv6 = -1;
+static int hf_mpls_echo_tlv_ds_map_int_ipv6 = -1;
+static int hf_mpls_echo_tlv_ds_map_hash_type = -1;
+static int hf_mpls_echo_tlv_ds_map_depth = -1;
+static int hf_mpls_echo_tlv_ds_map_muti_len = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_ip = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_mask = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_ip_low = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_ip_high = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_value = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_label = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_exp = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_bos = -1;
+static int hf_mpls_echo_tlv_ds_map_mp_proto = -1;
static int hf_mpls_echo_tlv_padaction = -1;
static int hf_mpls_echo_tlv_padding = -1;
static int hf_mpls_echo_tlv_vendor = -1;
+static int hf_mpls_echo_tlv_ilso_ipv4_addr = -1;
+static int hf_mpls_echo_tlv_ilso_ipv4_int_addr = -1;
+static int hf_mpls_echo_tlv_ilso_ipv6_addr = -1;
+static int hf_mpls_echo_tlv_ilso_ipv6_int_addr = -1;
+static int hf_mpls_echo_tlv_ilso_label = -1;
+static int hf_mpls_echo_tlv_ilso_exp = -1;
+static int hf_mpls_echo_tlv_ilso_bos = -1;
+static int hf_mpls_echo_tlv_ilso_ttl = -1;
+static int hf_mpls_echo_tlv_rto_ipv4 = -1;
+static int hf_mpls_echo_tlv_rto_ipv6 = -1;
+static int hf_mpls_echo_tlv_reply_tos = -1;
+static int hf_mpls_echo_tlv_reply_tos_mbz = -1;
+static int hf_mpls_echo_tlv_errored_type = -1;
static gint ett_mpls_echo = -1;
+static gint ett_mpls_echo_gflags = -1;
static gint ett_mpls_echo_tlv = -1;
static gint ett_mpls_echo_tlv_fec = -1;
+static gint ett_mpls_echo_tlv_ds_map = -1;
+static gint ett_mpls_echo_tlv_ilso = -1;
static int mpls_echo_udp_port = 0;
@@ -92,6 +143,8 @@ static guint32 global_mpls_echo_udp_port = UDP_PORT_MPLS_ECHO;
static const value_string mpls_echo_msgtype[] = {
{1, "MPLS Echo Request"},
{2, "MPLS Echo Reply"},
+ {3, "MPLS Data Plane Verification Request"},
+ {4, "MPLS Data Plane Verification Reply"},
{0, NULL}
};
@@ -117,6 +170,7 @@ static const value_string mpls_echo_returncode[] = {
{10, "Mapping for this FEC is not the given label at stack depth RSC"},
{11, "No label entry at stack-depth RSC"},
{12, "Protocol not associated with interface at FEC stack depth RSC"},
+ {13, "Premature termination, label stack shrinking to a single label"},
{0, NULL}
};
@@ -125,6 +179,13 @@ static const value_string mpls_echo_returncode[] = {
#define TLV_PAD 0x0003
#define TLV_ERROR_CODE 0x0004
#define TLV_VENDOR_CODE 0x0005
+#define TLV_TBD 0x0006
+#define TLV_ILSO_IPv4 0x0007
+#define TLV_ILSO_IPv6 0x0008
+#define TLV_ERRORED_TLV 0x0009
+#define TLV_REPLY_TOS 0x000A
+#define TLV_RTO_IPv4 0x000B
+#define TLV_RTO_IPv6 0x000C
#define TLV_VENDOR_PRIVATE_START 0xFC00
#define TLV_VENDOR_PRIVATE_END 0xFFFF
@@ -135,6 +196,13 @@ static const value_string mpls_echo_tlv_type_names[] = {
{ TLV_PAD, "Pad" },
{ TLV_ERROR_CODE, "Error Code" },
{ TLV_VENDOR_CODE, "Vendor Enterprise Code" },
+ { TLV_TBD, "TDB" },
+ { TLV_ILSO_IPv4, "IPv4 Interface and Label Stack Object" },
+ { TLV_ILSO_IPv6, "IPv6 Interface and Label Stack Object" },
+ { TLV_ERRORED_TLV, "Errored TLVs" },
+ { TLV_REPLY_TOS, "Reply TOS Byte" },
+ { TLV_RTO_IPv4, "IPv4 Reply-to Object" },
+ { TLV_RTO_IPv6, "IPv6 Reply-to Object" },
{ TLV_VENDOR_PRIVATE_START, "Vendor Private" },
{ 0, NULL}
};
@@ -149,6 +217,12 @@ static const value_string mpls_echo_tlv_type_names[] = {
#define TLV_FEC_STACK_L2_VPN 8
#define TLV_FEC_STACK_L2_CID_OLD 9
#define TLV_FEC_STACK_L2_CID_NEW 10
+#define TLV_FEC_STACK_L2_FEC_129 11
+#define TLV_FEC_STACK_BGP_LAB_v4 12
+#define TLV_FEC_STACK_BGP_LAB_v6 13
+#define TLV_FEC_STACK_GEN_IPv4 14
+#define TLV_FEC_STACK_GEN_IPv6 15
+#define TLV_FEC_STACK_NIL 16
#define TLV_FEC_VENDOR_PRIVATE_START 0xFC00
#define TLV_FEC_VENDOR_PRIVATE_END 0xFFFF
@@ -162,8 +236,14 @@ static const value_string mpls_echo_tlv_fec_names[] = {
{ TLV_FEC_STACK_VPN_IPv4, "VPN IPv4 prefix"},
{ TLV_FEC_STACK_VPN_IPv6, "VPN IPv6 prefix"},
{ TLV_FEC_STACK_L2_VPN, "L2 VPN endpoint"},
- { TLV_FEC_STACK_L2_CID_OLD, "L2 cirtuit ID (deprecated)"},
- { TLV_FEC_STACK_L2_CID_NEW, "L2 cirtuit ID (current)"},
+ { TLV_FEC_STACK_L2_CID_OLD, "FEC 128 Pseudowire (old)"},
+ { TLV_FEC_STACK_L2_CID_NEW, "FEC 128 Pseudowire (new)"},
+ { TLV_FEC_STACK_L2_FEC_129, "FEC 129 Pseudowire"},
+ { TLV_FEC_STACK_BGP_LAB_v4, "BGP labeled IPv4 prefix"},
+ { TLV_FEC_STACK_BGP_LAB_v6, "BGP labeled IPv6 prefix"},
+ { TLV_FEC_STACK_GEN_IPv4, "Generic IPv4 prefix"},
+ { TLV_FEC_STACK_GEN_IPv6, "Generic IPv6 prefix"},
+ { TLV_FEC_STACK_NIL, "Nil FEC"},
{ TLV_FEC_VENDOR_PRIVATE_START, "Vendor Private"},
{ 0, NULL}
};
@@ -174,6 +254,54 @@ static const value_string mpls_echo_tlv_pad[] = {
{ 0, NULL}
};
+#define TLV_DS_MAP_ADDR_IPv4 1
+#define TLV_DS_MAP_ADDR_UNNUM_IPv4 2
+#define TLV_DS_MAP_ADDR_IPv6 3
+#define TLV_DS_MAP_ADDR_UNNUM_IPv6 4
+
+static const value_string mpls_echo_tlv_ds_map_addr_type[] = {
+ {TLV_DS_MAP_ADDR_IPv4, "IPv4 Numbered"},
+ {TLV_DS_MAP_ADDR_UNNUM_IPv4, "IPv4 Unnumbered"},
+ {TLV_DS_MAP_ADDR_IPv6, "IPv6 Numbered"},
+ {TLV_DS_MAP_ADDR_UNNUM_IPv6, "IPv6 Unnumbered"},
+ {0, NULL}
+};
+
+#define TLV_DS_MAP_HASH_NO_MP 0
+#define TLV_DS_MAP_HASH_LABEL 1
+#define TLV_DS_MAP_HASH_IP 2
+#define TLV_DS_MAP_HASH_LABEL_RANGE 3
+#define TLV_DS_MAP_HASH_IP_RANGE 4
+#define TLV_DS_MAP_HASH_NO_LABEL 5
+#define TLV_DS_MAP_HASH_ALL_IP 6
+#define TLV_DS_MAP_HASH_NO_MATCH 7
+#define TLV_DS_MAP_HASH_BITMASK_IP 8
+#define TLV_DS_MAP_HASH_BITMASK_LABEL 9
+
+static const value_string mpls_echo_tlv_ds_map_hash_type[] = {
+ {TLV_DS_MAP_HASH_NO_MP, "no multipath"},
+ {TLV_DS_MAP_HASH_LABEL, "label"},
+ {TLV_DS_MAP_HASH_IP, "IP address"},
+ {TLV_DS_MAP_HASH_LABEL_RANGE, "label range"},
+ {TLV_DS_MAP_HASH_IP_RANGE, "IP address range"},
+ {TLV_DS_MAP_HASH_NO_LABEL, "no more labels"},
+ {TLV_DS_MAP_HASH_ALL_IP, "All IP addresses"},
+ {TLV_DS_MAP_HASH_NO_MATCH, "no match"},
+ {TLV_DS_MAP_HASH_BITMASK_IP, "Bit-masked IPv4 address set"},
+ {TLV_DS_MAP_HASH_BITMASK_LABEL, "Bit-masked label set"},
+ {0, NULL}
+};
+
+static const value_string mpls_echo_tlv_ds_map_mp_proto[] = {
+ {0, "Unknown"},
+ {1, "Static"},
+ {2, "BGP"},
+ {3, "LDP"},
+ {4, "RSVP-TE"},
+ {5, "Reserved"},
+ {0, NULL}
+};
+
/*
* Dissector for FEC sub-TLVs
*/
@@ -181,12 +309,15 @@ static void
dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
proto_tree *ti = NULL, *tlv_fec_tree = NULL;
- guint16 index = 1, type;
- int length;
+ guint16 index = 1, nil_index = 1, type, saved_type;
+ int length, nil_length, pad;
+ guint32 label;
+ guint8 exp, bos, ttl;
if (tree){
while (rem >= 4){ /* Type, Length */
type = tvb_get_ntohs(tvb, offset);
+ saved_type = type;
/* Check for Vendor Private sub-TLVs */
if(type >= TLV_FEC_VENDOR_PRIVATE_START) /* && <= TLV_FEC_VENDOR_PRIVATE_END always true */
type = TLV_FEC_VENDOR_PRIVATE_START;
@@ -199,11 +330,20 @@ dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem
if(tlv_fec_tree == NULL) return;
/* FEC sub-TLV Type and Length */
- proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb, offset,
- 2, FALSE);
+ proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_type, tvb,
+ offset, 2, saved_type, "Type: %s (%u)",
+ val_to_str(type, mpls_echo_tlv_fec_names, "Unknown sub-TLV type"), saved_type);
+
proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_len, tvb, offset + 2,
2, FALSE);
+ if (length + 4 > rem){
+ proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
+ "Error processing FEC sub-TLV: length is %u and reminder is %u",
+ length, rem - 4);
+ return;
+ }
+
/* FEC sub-TLV Value */
switch (type) {
case TLV_FEC_STACK_LDP_IPv4:
@@ -310,15 +450,78 @@ dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem
offset + 8, length - 4, FALSE);
}
break;
+ case TLV_FEC_STACK_BGP_LAB_v4:
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_nh,
+ tvb, offset + 4, 4, FALSE);
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_ipv4,
+ tvb, offset + 8, 4, FALSE);
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_bgp_len,
+ tvb, offset + 12, 1, FALSE);
+ if (length == 12)
+ proto_tree_add_text(tlv_fec_tree, tvb, offset + 13, 3, "Padding");
+ break;
+ case TLV_FEC_STACK_GEN_IPv4:
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4,
+ tvb, offset + 4, 4, FALSE);
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv4_mask,
+ tvb, offset + 8, 1, FALSE);
+ if (length == 8)
+ proto_tree_add_text(tlv_fec_tree, tvb, offset + 9, 3, "Padding");
+ break;
+ case TLV_FEC_STACK_GEN_IPv6:
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6,
+ tvb, offset + 4, 16, FALSE);
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_gen_ipv6_mask,
+ tvb, offset + 20, 1, FALSE);
+ if (length == 20)
+ proto_tree_add_text(tlv_fec_tree, tvb, offset + 21, 3, "Padding");
+ break;
+ case TLV_FEC_STACK_NIL:
+ nil_length = length;
+ while (nil_length >= 4){
+ decode_mpls_label(tvb, offset + 4, &label, &exp, &bos, &ttl);
+ if (label <= LABEL_MAX_RESERVED){
+ proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
+ tvb, offset + 4, 3, label, "Label %u: %u (%s)", nil_index, label,
+ val_to_str(label, special_labels, "Reserved - Unknown"));
+ } else {
+ proto_tree_add_uint_format(tlv_fec_tree, hf_mpls_echo_tlv_fec_nil_label,
+ tvb, offset + 4, 3, label, "Label %u: %u", nil_index, label);
+ }
+ nil_length -= 4;
+ offset += 4;
+ nil_index++;
+ }
+ break;
+
case TLV_FEC_STACK_RES:
case TLV_FEC_STACK_VPN_IPv4:
case TLV_FEC_STACK_VPN_IPv6:
case TLV_FEC_STACK_L2_VPN:
default:
- proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value, tvb, offset + 4,
- length, FALSE);
+ if(length)
+ proto_tree_add_item(tlv_fec_tree, hf_mpls_echo_tlv_fec_value,
+ tvb, offset + 4, length, FALSE);
break;
}
+
+ /*
+ * Check for padding based on sub-TLV length alignment;
+ * FEC sub-TLVs is zero-padded to align to four-octet boundary.
+ */
+ if (length % 4){
+ pad = 4 - (length % 4);
+ if (length + 4 + pad > rem){
+ proto_tree_add_text(tlv_fec_tree, tvb, offset, rem,
+ "Error processing FEC sub-TLV: padded length is %u and reminder is %u",
+ length + pad, rem - 4);
+ return;
+ } else {
+ proto_tree_add_text(tlv_fec_tree, tvb, offset + 4 + length, pad, "Padding");
+ }
+ length += pad;
+ }
+
rem -= 4 + length;
offset += 4 + length;
index++;
@@ -327,12 +530,256 @@ dissect_mpls_echo_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem
}
/*
+ * Dissector for Downstream Mapping TLV
+ */
+static void
+dissect_mpls_echo_tlv_ds_map(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ proto_tree *ti = NULL, *tlv_ds_map_tree = NULL;
+ guint16 mplen, index = 1;
+ guint32 label;
+ guint8 exp, bos, proto;
+ guint8 hash_type, addr_type;
+
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mtu, tvb,
+ offset, 2, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_addr_type, tvb,
+ offset + 2, 1, FALSE);
+ ti = proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_res, tvb,
+ offset + 3, 1, FALSE);
+ tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
+
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_res, tvb,
+ offset + 3, 1, FALSE);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_i, tvb,
+ offset + 3, 1, FALSE);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_flag_n, tvb,
+ offset + 3, 1, FALSE);
+
+ addr_type = tvb_get_guint8(tvb, offset + 2);
+ switch(addr_type){
+ case TLV_DS_MAP_ADDR_IPv4:
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
+ offset + 4, 4, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ip, tvb,
+ offset + 8, 4, FALSE);
+ break;
+ case TLV_DS_MAP_ADDR_UNNUM_IPv4:
+ case TLV_DS_MAP_ADDR_UNNUM_IPv6:
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ip, tvb,
+ offset + 4, 4, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_if_index, tvb,
+ offset + 8, 4, FALSE);
+ break;
+ case TLV_DS_MAP_ADDR_IPv6:
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_ds_ipv6, tvb,
+ offset + 4, 16, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_int_ipv6, tvb,
+ offset + 20, 16, FALSE);
+ rem -= 24;
+ offset += 24;
+ break;
+ default:
+ proto_tree_add_text(tree, tvb, offset + 4, 8,
+ "Error processing TLV: Unknown Address Type of %u",
+ addr_type);
+ break;
+ }
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_hash_type, tvb,
+ offset + 12, 1, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_depth, tvb,
+ offset + 13, 1, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_muti_len, tvb,
+ offset + 14, 2, FALSE);
+
+ /* Get the Multipath Length and Hash Type */
+ mplen = tvb_get_ntohs(tvb, offset + 14);
+ hash_type = tvb_get_guint8(tvb, offset + 12);
+
+ rem -= 16;
+ offset += 16;
+ if (rem < mplen){
+ proto_tree_add_text(tree, tvb, offset, rem,
+ "Error processing TLV: Multi Path length is %d and reminder is %u",
+ mplen, rem);
+ return;
+ }
+ rem -= mplen;
+ if(mplen){
+ switch(hash_type){
+ case TLV_DS_MAP_HASH_IP:
+ if(mplen != 4){
+ proto_tree_add_text(tree, tvb, offset, mplen,
+ "Multi Path length is %u and should be 4", mplen);
+ break;
+ }
+ ti = proto_tree_add_text(tree, tvb, offset, 4,
+ "Multipath Information");
+ tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
+ offset, 4, FALSE);
+ break;
+ case TLV_DS_MAP_HASH_IP_RANGE:
+ if(mplen != 8){
+ proto_tree_add_text(tree, tvb, offset, mplen,
+ "Multi Path length is %u and should be 8", mplen);
+ break;
+ }
+ ti = proto_tree_add_text(tree, tvb, offset, 8,
+ "Multipath Information");
+ tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_low, tvb,
+ offset, 4, FALSE);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip_high, tvb,
+ offset + 4, 4, FALSE);
+ break;
+ case TLV_DS_MAP_HASH_NO_MP:
+ case TLV_DS_MAP_HASH_NO_LABEL:
+ case TLV_DS_MAP_HASH_ALL_IP:
+ case TLV_DS_MAP_HASH_NO_MATCH:
+ proto_tree_add_text(tree, tvb, offset, mplen,
+ "No Multipath Information");
+ break;
+ case TLV_DS_MAP_HASH_BITMASK_IP:
+ if(mplen < 4){
+ proto_tree_add_text(tree, tvb, offset, mplen,
+ "Multi Path length is %u and should be >= 4", mplen);
+ break;
+ }
+ ti = proto_tree_add_text(tree, tvb, offset, mplen,
+ "Multipath Information");
+ tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_ip, tvb,
+ offset, 4, FALSE);
+ if(mplen > 4)
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_mask, tvb,
+ offset + 4, mplen - 4, FALSE);
+ break;
+ default:
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ds_map_mp_value, tvb,
+ offset, mplen, FALSE);
+ break;
+ }
+ }
+
+ offset += mplen;
+
+ while (rem >= 4){
+ decode_mpls_label(tvb, offset, &label, &exp, &bos, &proto);
+ ti = proto_tree_add_text(tree, tvb, offset, 4, "Downstream Label Element %u",
+ index);
+ tlv_ds_map_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ds_map);
+ proto_item_append_text(ti, ", Label: %u", label);
+ if (label <= LABEL_MAX_RESERVED){
+ proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
+ tvb, offset, 3, label, "Downstream Label: %u (%s)", label,
+ val_to_str(label, special_labels, "Reserved - Unknown"));
+ proto_item_append_text(ti, " (%s)", val_to_str(label, special_labels,
+ "Reserved - Unknown"));
+ } else {
+ proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_label,
+ tvb, offset, 3, label, "Downstream Label: %u", label);
+ }
+ proto_item_append_text(ti, ", Exp: %u, BOS: %u", exp, bos);
+ proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_exp,
+ tvb, offset + 2, 1, exp, "Downstream Exp: %u", exp);
+ proto_tree_add_uint_format(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_bos,
+ tvb, offset + 2, 1, bos, "Downstream BOS: %u", bos);
+ proto_tree_add_item(tlv_ds_map_tree, hf_mpls_echo_tlv_ds_map_mp_proto,
+ tvb, offset + 3, 1, FALSE);
+ proto_item_append_text(ti, ", Protocol: %u (%s)", proto, val_to_str(proto,
+ mpls_echo_tlv_ds_map_mp_proto, "Unknown"));
+ rem -= 4;
+ offset += 4;
+ index++;
+ }
+}
+
+/*
+ * Dissector for IPv4 and IPv6 Interface and Label Stack Object
+ */
+static void
+dissect_mpls_echo_tlv_ilso(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean is_ipv6)
+{
+ proto_tree *ti = NULL, *tlv_ilso = NULL;
+ guint16 index = 1;
+ guint32 label;
+ guint8 exp, bos, ttl;
+
+ if (is_ipv6){
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_addr, tvb,
+ offset, 16, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv6_int_addr, tvb,
+ offset + 16, 16, FALSE);
+
+ offset += 32;
+ rem -= 32;
+ } else {
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_addr, tvb,
+ offset, 4, FALSE);
+ proto_tree_add_item(tree, hf_mpls_echo_tlv_ilso_ipv4_int_addr, tvb,
+ offset + 4, 4, FALSE);
+
+ offset += 8;
+ rem -= 8;
+ }
+
+
+ while (rem >= 4){
+ decode_mpls_label(tvb, offset, &label, &exp, &bos, &ttl);
+ ti = proto_tree_add_text(tree, tvb, offset, 4, "Label Stack Element %u",
+ index);
+ tlv_ilso = proto_item_add_subtree(ti, ett_mpls_echo_tlv_ilso);
+ proto_item_append_text(ti, ", Label: %u", label);
+ if (label <= LABEL_MAX_RESERVED){
+ proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
+ tvb, offset, 3, label, "Label: %u (%s)", label,
+ val_to_str(label, special_labels, "Reserved - Unknown"));
+ proto_item_append_text(ti, " (%s)", val_to_str(label, special_labels,
+ "Reserved - Unknown"));
+ } else {
+ proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_label,
+ tvb, offset, 3, label, "Label: %u", label);
+ }
+ proto_item_append_text(ti, ", Exp: %u, BOS: %u, TTL: %u",
+ exp, bos, ttl);
+ proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_exp,
+ tvb, offset + 2, 1, exp, "Exp: %u", exp);
+ proto_tree_add_uint_format(tlv_ilso, hf_mpls_echo_tlv_ilso_bos,
+ tvb, offset + 2, 1, bos, "BOS: %u", bos);
+ proto_tree_add_item(tlv_ilso, hf_mpls_echo_tlv_ilso_ttl,
+ tvb, offset + 3, 1, FALSE);
+ rem -= 4;
+ offset += 4;
+ index++;
+ }
+}
+
+static int
+dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean in_errored);
+
+/*
+ * Dissector for Errored TLVs
+ */
+static void
+dissect_mpls_echo_tlv_errored(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ int errored_tlv_length;
+
+ while(rem >= 4){
+ errored_tlv_length = dissect_mpls_echo_tlv(tvb, offset, tree, rem, TRUE);
+ rem -= errored_tlv_length;
+ offset += errored_tlv_length;
+ }
+}
+
+/*
* Dissector for MPLS Echo TLVs and return bytes consumed
*/
static int
-dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem, gboolean in_errored)
{
- guint16 type;
+ guint16 type, saved_type;
int length;
proto_tree *ti = NULL, *mpls_echo_tlv_tree = NULL;
@@ -353,18 +800,26 @@ dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
if (tree) {
/* Check for Vendor Private TLVs */
+ saved_type = type;
if(type >= TLV_VENDOR_PRIVATE_START) /* && <= TLV_VENDOR_PRIVATE_END always true */
type = TLV_VENDOR_PRIVATE_START;
- ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
+ ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s%s",
+ in_errored ? "Errored TLV Type: " : "",
val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type (0x%04X)"));
mpls_echo_tlv_tree = proto_item_add_subtree(ti, ett_mpls_echo_tlv);
if(mpls_echo_tlv_tree == NULL) return length+4;
/* MPLS Echo TLV Type and Length */
- proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
- offset, 2, type, "Type: %s (%u)",
- val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), type );
+ if (in_errored){
+ proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_errored_type, tvb,
+ offset, 2, saved_type, "Errored TLV Type: %s (%u)",
+ val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), saved_type);
+ } else {
+ proto_tree_add_uint_format(mpls_echo_tlv_tree, hf_mpls_echo_tlv_type, tvb,
+ offset, 2, saved_type, "Type: %s (%u)",
+ val_to_str(type, mpls_echo_tlv_type_names, "Unknown TLV type"), saved_type);
+ }
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_len, tvb, offset + 2, 2, FALSE);
/* MPLS Echo TLV Value */
@@ -378,13 +833,52 @@ dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
case TLV_PAD:
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padaction, tvb,
offset + 4, 1, FALSE);
- proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
- offset + 5, length - 1, FALSE);
+ if (length > 1)
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_padding, tvb,
+ offset + 5, length - 1, FALSE);
break;
case TLV_VENDOR_CODE:
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_vendor, tvb,
offset + 4, 4, FALSE);
break;
+ case TLV_ILSO_IPv4:
+ if(length < 8) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be >= 8",
+ length);
+ break;
+ }
+ dissect_mpls_echo_tlv_ilso(tvb, offset + 4, mpls_echo_tlv_tree, length, FALSE);
+ break;
+ case TLV_ILSO_IPv6:
+ if(length < 32) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be >= 32",
+ length);
+ break;
+ }
+ dissect_mpls_echo_tlv_ilso(tvb, offset + 4, mpls_echo_tlv_tree, length, TRUE);
+ break;
+ case TLV_RTO_IPv4:
+ if(length != 4) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be 4",
+ length);
+ break;
+ }
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv4,
+ tvb, offset + 4, 4, FALSE);
+ break;
+ case TLV_RTO_IPv6:
+ if(length != 16) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be 16",
+ length);
+ break;
+ }
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_rto_ipv6,
+ tvb, offset + 4, 16, FALSE);
+ break;
case TLV_VENDOR_PRIVATE_START:
if (length < 4) { /* SMI Enterprise code */
proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
@@ -398,6 +892,33 @@ dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
}
break;
case TLV_DOWNSTREAM_MAPPING:
+ if(length < 16) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be >= 16",
+ length);
+ break;
+ }
+ dissect_mpls_echo_tlv_ds_map(tvb, offset + 4, mpls_echo_tlv_tree, length);
+ break;
+ case TLV_ERRORED_TLV:
+ if (in_errored)
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
+ offset + 4, length, FALSE);
+ else
+ dissect_mpls_echo_tlv_errored(tvb, offset + 4, mpls_echo_tlv_tree, length);
+ break;
+ case TLV_REPLY_TOS:
+ if(length != 4) {
+ proto_tree_add_text(mpls_echo_tlv_tree, tvb, offset + 4, length,
+ "Error processing TLV: length is %d, should be 4",
+ length);
+ break;
+ }
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos, tvb,
+ offset + 4, 1, FALSE);
+ proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_reply_tos_mbz, tvb,
+ offset + 5, 3, FALSE);
+ break;
case TLV_ERROR_CODE:
default:
proto_tree_add_item(mpls_echo_tlv_tree, hf_mpls_echo_tlv_value, tvb,
@@ -408,6 +929,9 @@ dissect_mpls_echo_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
return length + 4; /* Length of the Value field + Type Length */
}
+#define MSGTYPE_MPLS_ECHO(msgtype) ((msgtype == 1) || (msgtype == 2))
+#define MSGTYPE_DATAPLANE(msgtype) ((msgtype == 3) || (msgtype == 4))
+
/*
* Dissector for MPLS Echo (LSP PING) packets
*/
@@ -416,14 +940,14 @@ dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0, rem = 0, len;
proto_item *ti = NULL;
- proto_tree *mpls_echo_tree = NULL;
+ proto_tree *mpls_echo_tree = NULL, *mpls_echo_gflags = NULL;
guint8 msgtype;
const guint8 *ts_sent, *ts_rec;
gchar buff[NTP_TS_SIZE];
/* If version != 1 we assume it's not an mpls ping packet */
- if (!tvb_bytes_exist(tvb, 0, 2)) {
- return; /* Not enough information to tell. */
+ if (!tvb_bytes_exist(tvb, 0, 5)) {
+ return; /* Not enough information to tell version and message type. */
}
if (tvb_get_ntohs(tvb, 0) != 1) {
return; /* Not version 1. */
@@ -434,18 +958,24 @@ dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
rem = tvb_reported_length_remaining(tvb, offset);
- if( rem < 32 ) { /* The fixed part of the packet is 32 Bytes */
+ /* Get the message type and fill in the Column info */
+ msgtype = tvb_get_guint8(tvb, offset + 4);
+
+ /* The minimum fixed part of the packet is 16 Bytes or 32 Bytes depending on Msg Type */
+ if( ((!MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 16)) ||
+ ((MSGTYPE_MPLS_ECHO(msgtype)) && (rem < 32)) ) {
if( check_col(pinfo->cinfo, COL_INFO) )
col_set_str(pinfo->cinfo, COL_INFO, "Malformed Message");
- if(tree)
- proto_tree_add_text(tree, tvb, offset, rem,
- "Error processing Message: length is %d, should be >= 32",
- rem);
+ if(tree) {
+ ti = proto_tree_add_item(tree, proto_mpls_echo, tvb, 0, -1, FALSE);
+ mpls_echo_tree = proto_item_add_subtree(ti, ett_mpls_echo);
+ proto_tree_add_text(mpls_echo_tree, tvb, offset, rem,
+ "Error processing Message: length is %d, should be >= %u",
+ rem, (MSGTYPE_MPLS_ECHO(msgtype)) ? 32 : 16);
+ }
return;
}
- /* Get the message type and fill in the Column info */
- msgtype = tvb_get_guint8(tvb, offset + 4);
if (check_col(pinfo->cinfo, COL_INFO))
col_set_str(pinfo->cinfo, COL_INFO,
val_to_str(msgtype, mpls_echo_msgtype, "Unknown Message Type (0x%02X)"));
@@ -459,8 +989,20 @@ dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(mpls_echo_tree,
hf_mpls_echo_version, tvb, offset, 2, FALSE);
- proto_tree_add_item(mpls_echo_tree,
- hf_mpls_echo_mbz, tvb, offset + 2, 2, FALSE);
+
+ if(MSGTYPE_MPLS_ECHO(msgtype)){
+ ti = proto_tree_add_item(mpls_echo_tree,
+ hf_mpls_echo_gflags, tvb, offset + 2, 2, FALSE);
+ mpls_echo_gflags = proto_item_add_subtree(ti, ett_mpls_echo_gflags);
+ proto_tree_add_item(mpls_echo_gflags,
+ hf_mpls_echo_flag_sbz, tvb, offset + 2, 2, FALSE);
+ proto_tree_add_item(mpls_echo_gflags,
+ hf_mpls_echo_flag_v, tvb, offset + 2, 2, FALSE);
+ } else {
+ proto_tree_add_item(mpls_echo_tree,
+ hf_mpls_echo_mbz, tvb, offset + 2, 2, FALSE);
+ }
+
proto_tree_add_item(mpls_echo_tree,
hf_mpls_echo_msgtype, tvb, offset + 4, 1, FALSE);
proto_tree_add_item(mpls_echo_tree,
@@ -474,22 +1016,29 @@ dissect_mpls_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(mpls_echo_tree,
hf_mpls_echo_sequence, tvb, offset + 12, 4, FALSE);
- /* Using NTP routine to calculate the timestamp */
- ts_sent = tvb_get_ptr(tvb, 16, 8);
- proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
- offset + 16, 8, ts_sent, "Timestamp Sent: %s", ntp_fmt_ts(ts_sent, buff));
- ts_rec = tvb_get_ptr(tvb, 24, 8);
- proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
- offset + 24, 8, ts_rec, "Timestamp Received: %s", ntp_fmt_ts(ts_rec, buff));
+ if(MSGTYPE_MPLS_ECHO(msgtype)){
+ /* Using NTP routine to calculate the timestamp */
+ ts_sent = tvb_get_ptr(tvb, 16, 8);
+ proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_sent, tvb,
+ offset + 16, 8, ts_sent, "Timestamp Sent: %s", ntp_fmt_ts(ts_sent, buff));
+ ts_rec = tvb_get_ptr(tvb, 24, 8);
+ proto_tree_add_bytes_format(mpls_echo_tree, hf_mpls_echo_ts_rec, tvb,
+ offset + 24, 8, ts_rec, "Timestamp Received: %s", ntp_fmt_ts(ts_rec, buff));
+ }
}
- offset += 32;
- rem -= 32;
+ if(MSGTYPE_MPLS_ECHO(msgtype)){
+ offset += 32;
+ rem -= 32;
+ } else {
+ offset += 16;
+ rem -= 16;
+ }
/* Dissect all TLVs */
while(tvb_reported_length_remaining(tvb, offset) > 0 ) {
- len = dissect_mpls_echo_tlv(tvb, offset, mpls_echo_tree, rem);
+ len = dissect_mpls_echo_tlv(tvb, offset, mpls_echo_tree, rem, FALSE);
offset += len;
rem -= len;
}
@@ -510,7 +1059,19 @@ proto_register_mpls_echo(void)
},
{ &hf_mpls_echo_mbz,
{ "MBZ", "mpls_echo.mbz",
- FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO Must Be Zero", HFILL}
+ FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Must be Zero", HFILL}
+ },
+ { &hf_mpls_echo_gflags,
+ { "Global Flags", "mpls_echo.flags",
+ FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO Global Flags", HFILL}
+ },
+ { &hf_mpls_echo_flag_sbz,
+ { "Reserved", "mpls_echo.flag_sbz",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFE, "MPLS ECHO Reserved Flags", HFILL}
+ },
+ { &hf_mpls_echo_flag_v,
+ { "Validate FEC Stack", "mpls_echo.flag_v",
+ FT_BOOLEAN, 16, NULL, 0x0001, "MPLS ECHO Validate FEC Stack Flag", HFILL}
},
{ &hf_mpls_echo_msgtype,
{ "Message Type", "mpls_echo.msg_type",
@@ -572,19 +1133,19 @@ proto_register_mpls_echo(void)
},
{ &hf_mpls_echo_tlv_fec_ldp_ipv4,
{ "IPv4 Prefix", "mpls_echo.tlv.fec.ldp_ipv4",
- FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv4", HFILL}
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4", HFILL}
},
{ &hf_mpls_echo_tlv_fec_ldp_ipv4_mask,
{ "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv4_mask",
- FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv4 Prefix Length", HFILL}
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv4 Prefix Length", HFILL}
},
{ &hf_mpls_echo_tlv_fec_ldp_ipv6,
{ "IPv6 Prefix", "mpls_echo.tlv.fec.ldp_ipv6",
- FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv6", HFILL}
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6", HFILL}
},
{ &hf_mpls_echo_tlv_fec_ldp_ipv6_mask,
{ "Prefix Length", "mpls_echo.tlv.fec.ldp_ipv6_mask",
- FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack IPv6 Prefix Length", HFILL}
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack LDP IPv6 Prefix Length", HFILL}
},
{ &hf_mpls_echo_tlv_fec_rsvp_ipv4_ipv4_endpoint,
{ "IPv4 Tunnel endpoint address", "mpls_echo.tlv.fec.rsvp_ipv4_ep",
@@ -646,6 +1207,133 @@ proto_register_mpls_echo(void)
{ "MBZ", "mpls_echo.tlv.fec.l2cid_mbz",
FT_UINT16, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV FEC Stack L2CID MBZ", HFILL}
},
+ { &hf_mpls_echo_tlv_fec_bgp_nh,
+ { "BGP Next Hop", "mpls_echo.tlv.fec.bgp_nh",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Next Hop", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_bgp_ipv4,
+ { "IPv4 Prefix", "mpls_echo.tlv.fec.bgp_ipv4",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP IPv4", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_bgp_len,
+ { "Prefix Length", "mpls_echo.tlv.fec.bgp_len",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack BGP Prefix Length", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_gen_ipv4,
+ { "IPv4 Prefix", "mpls_echo.tlv.fec.gen_ipv4",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_gen_ipv4_mask,
+ { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv4_mask",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv4 Prefix Length", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_gen_ipv6,
+ { "IPv6 Prefix", "mpls_echo.tlv.fec.gen_ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_gen_ipv6_mask,
+ { "Prefix Length", "mpls_echo.tlv.fec.gen_ipv6_mask",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV FEC Stack Generic IPv6 Prefix Length", HFILL}
+ },
+ { &hf_mpls_echo_tlv_fec_nil_label,
+ { "Label", "mpls_echo.tlv.fec.nil_label",
+ FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV FEC Stack NIL Label", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mtu,
+ { "MTU", "mpls_echo.tlv.ds_map.mtu",
+ FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map MTU", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_addr_type,
+ { "Address Type", "mpls_echo.tlv.ds_map.addr_type",
+ FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_addr_type), 0x0,
+ "MPLS ECHO TLV Downstream Map Address Type", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_res,
+ { "DS Flags", "mpls_echo.tlv.ds_map.res",
+ FT_UINT8, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map DS Flags", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_flag_res,
+ { "MBZ", "mpls_echo.tlv.ds_map.flag_res",
+ FT_UINT8, BASE_HEX, NULL, 0xFC, "MPLS ECHO TLV Downstream Map Reserved Flags", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_flag_i,
+ { "Interface and Label Stack Request", "mpls_echo.tlv.ds_map.flag_i",
+ FT_BOOLEAN, 8, NULL, 0x02, "MPLS ECHO TLV Downstream Map I-Flag", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_flag_n,
+ { "Treat as Non-IP Packet", "mpls_echo.tlv.ds_map.flag_n",
+ FT_BOOLEAN, 8, NULL, 0x01, "MPLS ECHO TLV Downstream Map N-Flag", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_ds_ip,
+ { "Downstream IP Address", "mpls_echo.tlv.ds_map.ds_ip",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IP Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_int_ip,
+ { "Downstream Interface Address", "mpls_echo.tlv.ds_map.int_ip",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_if_index,
+ { "Upstream Interface Index", "mpls_echo.tlv.ds_map.if_index",
+ FT_UINT32, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface Index", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_ds_ipv6,
+ { "Downstream IPv6 Address", "mpls_echo.tlv.ds_map.ds_ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map IPv6 Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_int_ipv6,
+ { "Downstream Interface IPv6 Address", "mpls_echo.tlv.ds_map.int_ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Interface IPv6 Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_hash_type,
+ { "Multipath Type", "mpls_echo.tlv.ds_map.hash_type",
+ FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_hash_type), 0x0,
+ "MPLS ECHO TLV Downstream Map Multipath Type", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_depth,
+ { "Depth Limit", "mpls_echo.tlv.ds_map.depth",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Depth Limit", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_muti_len,
+ { "Multipath Length", "mpls_echo.tlv.ds_map.multi_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Length", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_ip,
+ { "IP Address", "mpls_echo.tlv.ds_map_mp.ip",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath IP Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_mask,
+ { "Mask", "mpls_echo.tlv.ds_map_mp.mask",
+ FT_BYTES, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Mask", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_ip_low,
+ { "IP Address Low", "mpls_echo.tlv.ds_map_mp.ip_low",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath Low IP Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_ip_high,
+ { "IP Address High", "mpls_echo.tlv.ds_map_mp.ip_high",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Downstream Map Multipath High IP Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_value,
+ { "Multipath Value", "mpls_echo.tlv.ds_map_mp.value",
+ FT_BYTES, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Multipath Value", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_label,
+ { "Downstream Label", "mpls_echo.tlv.ds_map.mp_label",
+ FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Downstream Map Downstream Label", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_exp,
+ { "Downstream Experimental", "mpls_echo.tlv.ds_map.mp_exp",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream Experimental", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_bos,
+ { "Downstream BOS", "mpls_echo.tlv.ds_map.mp_bos",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Downstream Map Downstream BOS", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ds_map_mp_proto,
+ { "Downstream Protocol", "mpls_echo.tlv.ds_map.mp_proto",
+ FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_ds_map_mp_proto), 0x0,
+ "MPLS ECHO TLV Downstream Map Downstream Protocol", HFILL}
+ },
{ &hf_mpls_echo_tlv_padaction,
{ "Pad Action", "mpls_echo.tlv.pad_action",
FT_UINT8, BASE_DEC, VALS(mpls_echo_tlv_pad), 0x0, "MPLS ECHO Pad TLV Action", HFILL}
@@ -657,13 +1345,69 @@ proto_register_mpls_echo(void)
{ &hf_mpls_echo_tlv_vendor,
{ "Vendor Id", "mpls_echo.tlv.vendor_id",
FT_UINT32, BASE_DEC, VALS(sminmpec_values), 0x0, "MPLS ECHO Vendor Id", HFILL}
- }
+ },
+ { &hf_mpls_echo_tlv_ilso_ipv4_addr,
+ { "Downstream IPv4 Address", "mpls_echo.tlv.ilso_ipv4.addr",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_ipv4_int_addr,
+ { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv4.int_addr",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_ipv6_addr,
+ { "Downstream IPv6 Address", "mpls_echo.tlv.ilso_ipv6.addr",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_ipv6_int_addr,
+ { "Downstream Interface Address", "mpls_echo.tlv.ilso_ipv6.int_addr",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Address", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_label,
+ { "Label", "mpls_echo.tlv.ilso_ipv4.label",
+ FT_UINT24, BASE_DEC, VALS(special_labels), 0x0, "MPLS ECHO TLV Interface and Label Stack Label", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_exp,
+ { "Exp", "mpls_echo.tlv.ilso_ipv4.exp",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack Exp", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_bos,
+ { "BOS", "mpls_echo.tlv.ilso_ipv4.bos",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack BOS", HFILL}
+ },
+ { &hf_mpls_echo_tlv_ilso_ttl,
+ { "TTL", "mpls_echo.tlv.ilso_ipv4.ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Interface and Label Stack TTL", HFILL}
+ },
+ { &hf_mpls_echo_tlv_rto_ipv4,
+ { "Reply-to IPv4 Address", "mpls_echo.tlv.rto.ipv4",
+ FT_IPv4, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv4 Reply-To Object", HFILL}
+ },
+ { &hf_mpls_echo_tlv_rto_ipv6,
+ { "Reply-to IPv6 Address", "mpls_echo.tlv.rto.ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0, "MPLS ECHO TLV IPv6 Reply-To Object", HFILL}
+ },
+ { &hf_mpls_echo_tlv_reply_tos,
+ { "Reply-TOS Byte", "mpls_echo.tlv.reply.tos",
+ FT_UINT8, BASE_DEC, NULL, 0x0, "MPLS ECHO TLV Reply-TOS Byte", HFILL}
+ },
+ { &hf_mpls_echo_tlv_reply_tos_mbz,
+ { "MBZ", "mpls_echo.tlv.reply.tos.mbz",
+ FT_UINT24, BASE_HEX, NULL, 0x0, "MPLS ECHO TLV Reply-TOS MBZ", HFILL}
+ },
+ { &hf_mpls_echo_tlv_errored_type,
+ { "Errored TLV Type", "mpls_echo.tlv.errored.type",
+ FT_UINT16, BASE_DEC, VALS(mpls_echo_tlv_type_names), 0x0,
+ "MPLS ECHO TLV Errored TLV Type", HFILL}
+ }
};
static gint *ett[] = {
&ett_mpls_echo,
+ &ett_mpls_echo_gflags,
&ett_mpls_echo_tlv,
&ett_mpls_echo_tlv_fec,
+ &ett_mpls_echo_tlv_ds_map,
+ &ett_mpls_echo_tlv_ilso,
};
module_t *mpls_echo_module;