aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorJustin Iurman <justin.iurman@uliege.be>2021-11-03 18:41:08 +0100
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-11-03 21:58:05 +0000
commit8d071fde541850024de08b92818ebb4a7e7acd22 (patch)
treecd43d545c845f2219c8a878860db762f818417da /epan
parentc82123aceaf62458e7cbc2a1f25e0e9baef3c065 (diff)
ipv6: dissector for the IOAM Trace option
Add support for the IOAM Trace option dissection Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ipv6.c255
1 files changed, 254 insertions, 1 deletions
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index 7c97c7343c..9bbde46577 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -200,6 +200,31 @@ static int hf_ipv6_opt_qs_nonce = -1;
static int hf_ipv6_opt_qs_reserved = -1;
static int hf_ipv6_opt_ioam_rsv = -1;
static int hf_ipv6_opt_ioam_opt_type = -1;
+static int hf_ipv6_opt_ioam_trace_ns = -1;
+static int hf_ipv6_opt_ioam_trace_nodelen = -1;
+static int hf_ipv6_opt_ioam_trace_flags = -1;
+static int hf_ipv6_opt_ioam_trace_flag_o = -1;
+static int hf_ipv6_opt_ioam_trace_flag_l = -1;
+static int hf_ipv6_opt_ioam_trace_flag_a = -1;
+static int hf_ipv6_opt_ioam_trace_flag_rsv = -1;
+static int hf_ipv6_opt_ioam_trace_remlen = -1;
+static int hf_ipv6_opt_ioam_trace_type = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit0 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit1 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit2 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit3 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit4 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit5 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit6 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit7 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit8 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit9 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit10 = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit11 = -1;
+static int hf_ipv6_opt_ioam_trace_type_undef = -1;
+static int hf_ipv6_opt_ioam_trace_type_bit22 = -1;
+static int hf_ipv6_opt_ioam_trace_type_rsv = -1;
+static int hf_ipv6_opt_ioam_trace_rsv = -1;
static int hf_ipv6_opt_tpf_information = -1;
static int hf_ipv6_opt_mipv6_home_address = -1;
static int hf_ipv6_opt_rpl_flag = -1;
@@ -313,6 +338,8 @@ static gint ett_ipv6_opt_type = -1;
static gint ett_ipv6_opt_rpl = -1;
static gint ett_ipv6_opt_mpl = -1;
static gint ett_ipv6_opt_dff_flags = -1;
+static gint ett_ipv6_opt_ioam_trace_flags = -1;
+static gint ett_ipv6_opt_ioam_trace_types = -1;
static gint ett_ipv6_hopopts_proto = -1;
static gint ett_ipv6_fraghdr_proto = -1;
static gint ett_ipv6_routing_proto = -1;
@@ -349,6 +376,8 @@ static expert_field ei_ipv6_plen_zero = EI_INIT;
static expert_field ei_ipv6_bogus_ipv6_version = EI_INIT;
static expert_field ei_ipv6_invalid_header = EI_INIT;
static expert_field ei_ipv6_opt_header_mismatch = EI_INIT;
+static expert_field ei_ipv6_opt_ioam_invalid_remlen = EI_INIT;
+static expert_field ei_ipv6_opt_ioam_invalid_trace_type = EI_INIT;
static dissector_handle_t ipv6_handle;
@@ -1644,6 +1673,89 @@ static const value_string ipv6_ioam_opt_types[] = {
};
/*
+ * IOAM Trace Option Header
+ *
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Namespace-ID | NodeLen | Flags | RemainingLen|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IOAM-Trace-Type | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+static gint
+dissect_opt_ioam_trace(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *opt_tree, struct opt_proto_item *opt_ti, guint8 opt_len)
+{
+ proto_item *ti;
+ guint32 trace_type;
+ guint8 remlen;
+
+ static int * const ioam_trace_flags[] = {
+ &hf_ipv6_opt_ioam_trace_flag_o,
+ &hf_ipv6_opt_ioam_trace_flag_l,
+ &hf_ipv6_opt_ioam_trace_flag_a,
+ &hf_ipv6_opt_ioam_trace_flag_rsv,
+ NULL
+ };
+
+ static int * const ioam_trace_types[] = {
+ &hf_ipv6_opt_ioam_trace_type_bit0,
+ &hf_ipv6_opt_ioam_trace_type_bit1,
+ &hf_ipv6_opt_ioam_trace_type_bit2,
+ &hf_ipv6_opt_ioam_trace_type_bit3,
+ &hf_ipv6_opt_ioam_trace_type_bit4,
+ &hf_ipv6_opt_ioam_trace_type_bit5,
+ &hf_ipv6_opt_ioam_trace_type_bit6,
+ &hf_ipv6_opt_ioam_trace_type_bit7,
+ &hf_ipv6_opt_ioam_trace_type_bit8,
+ &hf_ipv6_opt_ioam_trace_type_bit9,
+ &hf_ipv6_opt_ioam_trace_type_bit10,
+ &hf_ipv6_opt_ioam_trace_type_bit11,
+ &hf_ipv6_opt_ioam_trace_type_undef,
+ &hf_ipv6_opt_ioam_trace_type_bit22,
+ &hf_ipv6_opt_ioam_trace_type_rsv,
+ NULL
+ };
+
+ if (opt_len < 10) {
+ expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
+ "IOAM Option: Invalid length (%u bytes)", opt_len);
+ }
+
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_ns, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_bits_item(opt_tree, hf_ipv6_opt_ioam_trace_nodelen, tvb,
+ offset * 8, 5, ENC_BIG_ENDIAN);
+
+ proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_trace_flags,
+ ett_ipv6_opt_ioam_trace_flags, ioam_trace_flags, ENC_NA);
+
+ remlen = tvb_get_bits8(tvb, offset * 8 + 9, 7);
+ ti = proto_tree_add_bits_item(opt_tree, hf_ipv6_opt_ioam_trace_remlen, tvb,
+ offset * 8 + 9, 7, ENC_BIG_ENDIAN);
+ if (remlen * 4 > opt_len - 10) {
+ expert_add_info_format(pinfo, ti, &ei_ipv6_opt_ioam_invalid_remlen,
+ "IOAM RemLen: Invalid length (%u bytes)", remlen * 4);
+ }
+
+ offset += 2;
+
+ trace_type = tvb_get_bits32(tvb, offset * 8, 24, ENC_BIG_ENDIAN);
+ ti = proto_tree_add_bitmask(opt_tree, tvb, offset, hf_ipv6_opt_ioam_trace_type,
+ ett_ipv6_opt_ioam_trace_types, ioam_trace_types, ENC_BIG_ENDIAN);
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_rsv, tvb, offset + 3, 1, ENC_NA);
+ offset += 4;
+
+ if (!(trace_type & 0xfff002) || (trace_type & 0xffd)) {
+ expert_add_info(pinfo, ti, &ei_ipv6_opt_ioam_invalid_trace_type);
+ }
+
+ return offset;
+}
+
+/*
* IOAM Option Header
*
0 1 2 3
@@ -1668,9 +1780,15 @@ dissect_opt_ioam(tvbuff_t *tvb, gint offset, packet_info *pinfo,
offset + 1, 1, ENC_NA, &opt_type);
offset += 2;
+ proto_tree* opt_type_tree
+ = proto_tree_add_subtree(opt_tree, tvb, offset, opt_len - 2, 0, NULL,
+ val_to_str_const(opt_type, ipv6_ioam_opt_types,
+ "Unknown Option-Type"));
+
switch (opt_type) {
case IP6IOAM_PRE_TRACE:
case IP6IOAM_INC_TRACE:
+ offset = dissect_opt_ioam_trace(tvb, offset, pinfo, opt_type_tree, opt_ti, opt_len);
break;
case IP6IOAM_POT:
break;
@@ -3191,6 +3309,131 @@ proto_register_ipv6(void)
FT_UINT8, BASE_DEC, VALS(ipv6_ioam_opt_types), 0x0,
NULL, HFILL }
},
+ { &hf_ipv6_opt_ioam_trace_ns,
+ { "Namespace ID", "ipv6.opt.ioam.trace.ns",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_nodelen,
+ { "Node Length", "ipv6.opt.ioam.trace.nodelen",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_flags,
+ { "Flags", "ipv6.opt.ioam.trace.flags",
+ FT_UINT16, BASE_HEX, NULL, 0x780,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_flag_o,
+ { "Overflow", "ipv6.opt.ioam.trace.flag.o",
+ FT_BOOLEAN, 16, NULL, 0x400,
+ "Not enough free space", HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_flag_l,
+ { "Loopback", "ipv6.opt.ioam.trace.flag.l",
+ FT_BOOLEAN, 16, NULL, 0x200,
+ "Send a copy of the packet back towards the source", HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_flag_a,
+ { "Active", "ipv6.opt.ioam.trace.flag.a",
+ FT_BOOLEAN, 16, NULL, 0x100,
+ "Active measurement packet", HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_flag_rsv,
+ { "Reserved", "ipv6.opt.ioam.trace.flag.rsv",
+ FT_BOOLEAN, 16, NULL, 0x80,
+ "Reserved (must be zero)", HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_remlen,
+ { "Remaining Length", "ipv6.opt.ioam.trace.remlen",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type,
+ { "Trace Type", "ipv6.opt.ioam.trace.type",
+ FT_UINT24, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit0,
+ { "Hop_Lim and Node ID (short)", "ipv6.opt.ioam.trace.type.bit0",
+ FT_BOOLEAN, 24, NULL, 0x800000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit1,
+ { "Ingress and Egress IDs (short)", "ipv6.opt.ioam.trace.type.bit1",
+ FT_BOOLEAN, 24, NULL, 0x400000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit2,
+ { "Timestamp seconds", "ipv6.opt.ioam.trace.type.bit2",
+ FT_BOOLEAN, 24, NULL, 0x200000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit3,
+ { "Timestamp fraction", "ipv6.opt.ioam.trace.type.bit3",
+ FT_BOOLEAN, 24, NULL, 0x100000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit4,
+ { "Transit delay", "ipv6.opt.ioam.trace.type.bit4",
+ FT_BOOLEAN, 24, NULL, 0x80000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit5,
+ { "IOAM-Namespace specific data (short)", "ipv6.opt.ioam.trace.type.bit5",
+ FT_BOOLEAN, 24, NULL, 0x40000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit6,
+ { "Queue depth", "ipv6.opt.ioam.trace.type.bit6",
+ FT_BOOLEAN, 24, NULL, 0x20000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit7,
+ { "Checksum complement", "ipv6.opt.ioam.trace.type.bit7",
+ FT_BOOLEAN, 24, NULL, 0x10000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit8,
+ { "Hop_Lim and Node ID (wide)", "ipv6.opt.ioam.trace.type.bit8",
+ FT_BOOLEAN, 24, NULL, 0x8000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit9,
+ { "Ingress and Egress IDs (wide)", "ipv6.opt.ioam.trace.type.bit9",
+ FT_BOOLEAN, 24, NULL, 0x4000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit10,
+ { "IOAM-Namespace specific data (wide)", "ipv6.opt.ioam.trace.type.bit10",
+ FT_BOOLEAN, 24, NULL, 0x2000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit11,
+ { "Buffer occupancy", "ipv6.opt.ioam.trace.type.bit11",
+ FT_BOOLEAN, 24, NULL, 0x1000,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_undef,
+ { "Undefined", "ipv6.opt.ioam.trace.type.undef",
+ FT_BOOLEAN, 24, NULL, 0xffc,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_bit22,
+ { "Opaque State Snapshot", "ipv6.opt.ioam.trace.type.bit22",
+ FT_BOOLEAN, 24, NULL, 0x2,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_type_rsv,
+ { "Reserved", "ipv6.opt.ioam.trace.type.rsv",
+ FT_BOOLEAN, 24, NULL, 0x1,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_rsv,
+ { "Reserved", "ipv6.opt.ioam.trace.rsv",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Reserved (must be zero)", HFILL }
+ },
{ &hf_ipv6_opt_tpf_information,
{ "TPF Information", "ipv6.opt.tpf_information",
FT_UINT32, BASE_HEX, NULL, 0x0,
@@ -3605,6 +3848,8 @@ proto_register_ipv6(void)
&ett_ipv6_opt_rpl,
&ett_ipv6_opt_mpl,
&ett_ipv6_opt_dff_flags,
+ &ett_ipv6_opt_ioam_trace_flags,
+ &ett_ipv6_opt_ioam_trace_types,
&ett_ipv6_fragment,
&ett_ipv6_fragments
};
@@ -3678,7 +3923,15 @@ proto_register_ipv6(void)
{ &ei_ipv6_opt_mpl_ipv6_src_seed_id,
{ "ipv6.opt.mpl.ipv6_src_seed_id", PI_PROTOCOL, PI_COMMENT,
"Seed ID is the IPv6 Source Address", EXPFILL }
- }
+ },
+ { &ei_ipv6_opt_ioam_invalid_remlen,
+ { "ipv6.opt.ioam.trace.invalid_remlen", PI_PROTOCOL, PI_ERROR,
+ "Invalid \"RemLen\" value", EXPFILL }
+ },
+ { &ei_ipv6_opt_ioam_invalid_trace_type,
+ { "ipv6.opt.ioam.trace.invalid_type", PI_PROTOCOL, PI_WARN,
+ "Invalid Trace Type", EXPFILL }
+ },
};
static ei_register_info ei_ipv6_hopopts[] = {