aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ipv6.c
diff options
context:
space:
mode:
authorJustin Iurman <justin.iurman@uliege.be>2021-11-03 18:44:05 +0100
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-11-03 21:58:05 +0000
commitc92bb35bcf735246e1c54007231c5e4f1639ab0f (patch)
treebac7a4d19a0427983a1453f46050097674627873 /epan/dissectors/packet-ipv6.c
parent8d071fde541850024de08b92818ebb4a7e7acd22 (diff)
ipv6: dissector for the IOAM Trace data list
Add support for the IOAM Trace data list dissection Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
Diffstat (limited to 'epan/dissectors/packet-ipv6.c')
-rw-r--r--epan/dissectors/packet-ipv6.c308
1 files changed, 306 insertions, 2 deletions
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index 9bbde46577..9a7dfb4a89 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -103,6 +103,21 @@ void proto_reg_handoff_ipv6(void);
#define IP6IOAM_POT 2 /* Proof of Transit */
#define IP6IOAM_E2E 3 /* Edge to Edge */
+/* IOAM Trace Types */
+#define IP6IOAM_TRACE_MASK_BIT0 (1 << 23) /* Hop_lim + Node ID */
+#define IP6IOAM_TRACE_MASK_BIT1 (1 << 22) /* Ingress and Egress IDs */
+#define IP6IOAM_TRACE_MASK_BIT2 (1 << 21) /* Timestamp seconds */
+#define IP6IOAM_TRACE_MASK_BIT3 (1 << 20) /* Timestamp fraction */
+#define IP6IOAM_TRACE_MASK_BIT4 (1 << 19) /* Transit delay */
+#define IP6IOAM_TRACE_MASK_BIT5 (1 << 18) /* IOAM-Namespace data */
+#define IP6IOAM_TRACE_MASK_BIT6 (1 << 17) /* Queue depth */
+#define IP6IOAM_TRACE_MASK_BIT7 (1 << 16) /* Checksum complement */
+#define IP6IOAM_TRACE_MASK_BIT8 (1 << 15) /* (wide) Hop_lim + Node ID */
+#define IP6IOAM_TRACE_MASK_BIT9 (1 << 14) /* (wide) Ingress and Egress IDs */
+#define IP6IOAM_TRACE_MASK_BIT10 (1 << 13) /* (wide) IOAM-Namespace data */
+#define IP6IOAM_TRACE_MASK_BIT11 (1 << 12) /* Buffer occupancy */
+#define IP6IOAM_TRACE_MASK_BIT22 (1 << 1) /* Opaque state snapshot */
+
/* Protocol specific data indices */
#define IPV6_PROTO_VALUE 1
#define IPV6_PROTO_PINFO 2
@@ -225,6 +240,25 @@ 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_ioam_trace_free_space = -1;
+static int hf_ipv6_opt_ioam_trace_node_hlim = -1;
+static int hf_ipv6_opt_ioam_trace_node_id = -1;
+static int hf_ipv6_opt_ioam_trace_node_iif = -1;
+static int hf_ipv6_opt_ioam_trace_node_eif = -1;
+static int hf_ipv6_opt_ioam_trace_node_tss = -1;
+static int hf_ipv6_opt_ioam_trace_node_tsf = -1;
+static int hf_ipv6_opt_ioam_trace_node_trdelay = -1;
+static int hf_ipv6_opt_ioam_trace_node_nsdata = -1;
+static int hf_ipv6_opt_ioam_trace_node_qdepth = -1;
+static int hf_ipv6_opt_ioam_trace_node_csum = -1;
+static int hf_ipv6_opt_ioam_trace_node_id_wide = -1;
+static int hf_ipv6_opt_ioam_trace_node_iif_wide = -1;
+static int hf_ipv6_opt_ioam_trace_node_eif_wide = -1;
+static int hf_ipv6_opt_ioam_trace_node_nsdata_wide = -1;
+static int hf_ipv6_opt_ioam_trace_node_bufoccup = -1;
+static int hf_ipv6_opt_ioam_trace_node_oss_len = -1;
+static int hf_ipv6_opt_ioam_trace_node_oss_scid = -1;
+static int hf_ipv6_opt_ioam_trace_node_oss_data = -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;
@@ -1672,6 +1706,103 @@ static const value_string ipv6_ioam_opt_types[] = {
{ 0, NULL}
};
+static gint
+dissect_opt_ioam_trace_node(tvbuff_t *tvb, gint offset,
+ proto_tree *opt_tree, guint32 trace_type)
+{
+ proto_tree* sub_tree;
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT0) {
+ sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 4, 0, NULL,
+ "Hop_Lim and Node ID (short)");
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_hlim,
+ tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_id,
+ tvb, offset + 1, 3, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT1) {
+ sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 4, 0, NULL,
+ "Ingress and Egress IDs (short)");
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_iif,
+ tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_eif,
+ tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT2) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_tss,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT3) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_tsf,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT4) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_trdelay,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT5) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_nsdata,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT6) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_qdepth,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT7) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_csum,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT8) {
+ sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 8, 0, NULL,
+ "Hop_Lim and Node ID (wide)");
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_hlim,
+ tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_id_wide,
+ tvb, offset + 1, 7, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT9) {
+ sub_tree = proto_tree_add_subtree(opt_tree, tvb, offset, 8, 0, NULL,
+ "Ingress and Egress IDs (wide)");
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_iif_wide,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_ipv6_opt_ioam_trace_node_eif_wide,
+ tvb, offset + 4, 4, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT10) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_nsdata_wide,
+ tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT11) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_node_bufoccup,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+
+ return offset;
+}
+
/*
* IOAM Trace Option Header
*
@@ -1681,15 +1812,34 @@ static const value_string ipv6_ioam_opt_types[] = {
| Namespace-ID | NodeLen | Flags | RemainingLen|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IOAM-Trace-Type | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+
+ | | |
+ | node data list [0] | |
+ | | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ D
+ | | a
+ | node data list [1] | t
+ | | a
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ~ ........ ~ S
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ p
+ | | a
+ | node data list [n-1] | c
+ | | e
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ | | |
+ | node data list [n] | |
+ | | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+
*/
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;
+ guint32 trace_type, oss_scid;
+ guint16 len;
+ guint8 remlen, nodelen, oss_len, i = 0;
static int * const ioam_trace_flags[] = {
&hf_ipv6_opt_ioam_trace_flag_o,
@@ -1726,6 +1876,7 @@ dissect_opt_ioam_trace(tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree_add_item(opt_tree, hf_ipv6_opt_ioam_trace_ns, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
+ nodelen = tvb_get_bits8(tvb, offset * 8, 5);
proto_tree_add_bits_item(opt_tree, hf_ipv6_opt_ioam_trace_nodelen, tvb,
offset * 8, 5, ENC_BIG_ENDIAN);
@@ -1752,6 +1903,64 @@ dissect_opt_ioam_trace(tvbuff_t *tvb, gint offset, packet_info *pinfo,
expert_add_info(pinfo, ti, &ei_ipv6_opt_ioam_invalid_trace_type);
}
+ /* node data list parsing starts here */
+ proto_tree* trace_tree
+ = proto_tree_add_subtree(opt_tree, tvb, offset, opt_len - 10, 0, NULL, "Trace Data");
+
+ if (remlen) {
+ proto_tree_add_item(trace_tree, hf_ipv6_opt_ioam_trace_free_space, tvb,
+ offset, remlen * 4, ENC_NA);
+ offset += remlen * 4;
+ }
+
+ len = opt_len - 10 - remlen * 4;
+ while (len && len >= nodelen * 4) {
+ proto_tree* node_tree
+ = proto_tree_add_subtree_format(trace_tree, tvb, offset,
+ nodelen * 4, 0, NULL, "Node %u", ++i);
+
+ offset = dissect_opt_ioam_trace_node(tvb, offset, node_tree, trace_type);
+ len -= nodelen * 4;
+
+ /* Opaque State Snapshot */
+ if (trace_type & IP6IOAM_TRACE_MASK_BIT22) {
+ if (len < 4) {
+ expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
+ "IOAM Option: Invalid length (%u bytes)", opt_len);
+ }
+
+ oss_len = tvb_get_guint8(tvb, offset);
+
+ proto_tree* oss_tree
+ = proto_tree_add_subtree(node_tree, tvb, offset, (oss_len + 1) * 4,
+ 0, NULL, "Opaque State Snapshot");
+ proto_tree_add_item(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_len,
+ tvb, offset, 1, ENC_NA);
+ proto_tree_add_item_ret_uint(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_scid,
+ tvb, offset + 1, 3, ENC_BIG_ENDIAN, &oss_scid);
+ offset += 4;
+
+ len -= 4;
+ if (len < oss_len * 4) {
+ expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
+ "IOAM Option: Invalid length (%u bytes)", opt_len);
+ }
+
+ if (oss_len > 0) {
+ proto_tree_add_item(oss_tree, hf_ipv6_opt_ioam_trace_node_oss_data,
+ tvb, offset, oss_len * 4, ENC_NA);
+
+ len -= oss_len * 4;
+ offset += oss_len * 4;
+ }
+ }
+ }
+
+ if (len) {
+ expert_add_info_format(pinfo, opt_ti->len, &ei_ipv6_opt_invalid_len,
+ "IOAM Option: Invalid length (%u bytes)", opt_len);
+ }
+
return offset;
}
@@ -3434,6 +3643,101 @@ proto_register_ipv6(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
"Reserved (must be zero)", HFILL }
},
+ { &hf_ipv6_opt_ioam_trace_free_space,
+ { "Free space", "ipv6.opt.ioam.trace.free_space",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_hlim,
+ { "Hop Limit", "ipv6.opt.ioam.trace.node.hlim",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_id,
+ { "ID", "ipv6.opt.ioam.trace.node.id",
+ FT_UINT24, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_iif,
+ { "Ingress ID", "ipv6.opt.ioam.trace.node.iif",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_eif,
+ { "Egress ID", "ipv6.opt.ioam.trace.node.eif",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_tss,
+ { "Timestamp Seconds", "ipv6.opt.ioam.trace.node.tss",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_tsf,
+ { "Timestamp Fraction", "ipv6.opt.ioam.trace.node.tsf",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_trdelay,
+ { "Transit Delay", "ipv6.opt.ioam.trace.node.trdelay",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_nsdata,
+ { "Namespace Data (short)", "ipv6.opt.ioam.trace.node.nsdata",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_qdepth,
+ { "Queue Depth", "ipv6.opt.ioam.trace.node.qdepth",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_csum,
+ { "Checksum Complement", "ipv6.opt.ioam.trace.node.csum",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_id_wide,
+ { "ID", "ipv6.opt.ioam.trace.node.id_wide",
+ FT_UINT56, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_iif_wide,
+ { "Ingress ID", "ipv6.opt.ioam.trace.node.iif_wide",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_eif_wide,
+ { "Egress ID", "ipv6.opt.ioam.trace.node.eif_wide",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_nsdata_wide,
+ { "Namespace Data (wide)", "ipv6.opt.ioam.trace.node.nsdata_wide",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_bufoccup,
+ { "Buffer Occupancy", "ipv6.opt.ioam.trace.node.bufoccup",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_oss_len,
+ { "Length", "ipv6.opt.ioam.trace.node.oss.len",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_oss_scid,
+ { "Schema ID", "ipv6.opt.ioam.trace.node.oss.scid",
+ FT_UINT24, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ipv6_opt_ioam_trace_node_oss_data,
+ { "Data", "ipv6.opt.ioam.trace.node.oss.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_ipv6_opt_tpf_information,
{ "TPF Information", "ipv6.opt.tpf_information",
FT_UINT32, BASE_HEX, NULL, 0x0,