summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Haynes <loghyr@primarydata.com>2015-09-08 14:38:11 -0700
committerPascal Quantin <pascal.quantin@gmail.com>2015-09-09 14:56:02 +0000
commit0c6b54edd1c35232718aca2f17a5e69154a0cc2b (patch)
tree9274f5939b63b9f9d06f93a60c741c9da94a9abc
parent0f89e42de5583a0829fdf8f8e4712671e0de33bb (diff)
downloadwireshark-0c6b54edd1c35232718aca2f17a5e69154a0cc2b.tar.gz
nfs: Add support for the Flex File Layout Type in LAYOUTRETURN
Change-Id: I40462f2acf20b99b5691a5efe1f6bfa563163bee Signed-off-by: Tom Haynes <loghyr@primarydata.com> Reviewed-on: https://code.wireshark.org/review/10429 Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
-rw-r--r--epan/dissectors/packet-nfs.c363
1 files changed, 261 insertions, 102 deletions
diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c
index bf5feea15c..ecb59559ae 100644
--- a/epan/dissectors/packet-nfs.c
+++ b/epan/dissectors/packet-nfs.c
@@ -612,7 +612,6 @@ static int hf_nfs4_ff_ops_requested = -1;
static int hf_nfs4_io_bytes = -1;
static int hf_nfs4_io_count = -1;
static int hf_nfs4_layoutstats = -1;
-
static int hf_nfs4_callback_stateids = -1;
static int hf_nfs4_callback_stateids_index = -1;
static int hf_nfs4_consecutive = -1;
@@ -623,6 +622,15 @@ static int hf_nfs4_nl_url = -1;
static int hf_nfs4_source_server_index = -1;
static int hf_nfs4_source_servers = -1;
static int hf_nfs4_synchronous = -1;
+static int hf_nfs4_device_error_count = -1;
+static int hf_nfs4_device_errors_index = -1;
+static int hf_nfs4_ff_ioerrs_count = -1;
+static int hf_nfs4_ff_ioerrs_index = -1;
+static int hf_nfs4_ff_ioerrs_length = -1;
+static int hf_nfs4_ff_ioerrs_offset = -1;
+static int hf_nfs4_ff_iostats_count = -1;
+static int hf_nfs4_ff_iostats_index = -1;
+static int hf_nfs4_io_error_op = -1;
static int hf_nfs4_io_hints_mask = -1;
static int hf_nfs4_io_hint_count = -1;
static int hf_nfs4_io_advise_hint = -1;
@@ -828,6 +836,9 @@ static gint ett_nfs4_callback_stateids_sub = -1;
static gint ett_nfs4_source_servers_sub = -1;
static gint ett_nfs4_copy = -1;
static gint ett_nfs4_copy_notify = -1;
+static gint ett_nfs4_device_errors_sub = -1;
+static gint ett_nfs4_ff_ioerrs_sub = -1;
+static gint ett_nfs4_ff_iostats_sub = -1;
static gint ett_nfs4_clone = -1;
static gint ett_nfs4_offload_cancel = -1;
static gint ett_nfs4_offload_status = -1;
@@ -8360,9 +8371,176 @@ dissect_nfs4_app_data_block(tvbuff_t *tvb, int offset, proto_tree *tree, guint32
}
static int
-dissect_nfs4_layoutreturn(tvbuff_t *tvb, int offset, proto_tree *tree)
+dissect_nfs4_io_time(tvbuff_t *tvb, int offset, proto_tree *tree, const char *timer_mode)
+{
+ proto_tree *newtree;
+
+ newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_time, NULL, "%s", timer_mode);
+ offset = dissect_nfs4_nfstime(tvb, offset, newtree);
+
+ return offset;
+}
+
+static int
+dissect_nfs4_io_latency(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
+{
+ proto_tree *newtree;
+
+ newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "%s Latency", io_mode);
+
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_requested, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_requested, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_completed, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_completed, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_not_delivered, offset);
+
+ offset = dissect_nfs4_io_time(tvb, offset, newtree, "Busy time");
+ offset = dissect_nfs4_io_time(tvb, offset, newtree, "Completion time");
+
+ return offset;
+}
+
+static int
+dissect_nfs4_io_info(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
+{
+ proto_tree *newtree;
+
+ newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_info, NULL, "%s Info", io_mode);
+
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_count, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_bytes, offset);
+
+ return offset;
+}
+
+static int
+dissect_nfs4_layoutstats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ, gboolean has_layout_type)
+{
+ guint layout_type;
+ proto_tree *netaddr;
+ proto_item *fitem;
+ int old_offset;
+ guint32 last_fh_hash = 0;
+
+ /* FIXME: Are these here or in the caller? Check for layoutcommit */
+ offset = dissect_nfs4_io_info(tvb, offset, tree, "Read");
+ offset = dissect_nfs4_io_info(tvb, offset, tree, "Write");
+ offset = dissect_nfs4_deviceid(tvb, offset, tree);
+
+ if (has_layout_type) {
+ layout_type = tvb_get_ntohl(tvb, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
+ }
+
+ /* If not flex files layout type eat the rest and move on.. */
+ if (!has_layout_type || layout_type == LAYOUT4_FLEX_FILES) {
+
+ /* NFS Flex Files */
+ if (has_layout_type)
+ offset += 4; /* Skip past opaque count */
+
+ /* The netaddr */
+ old_offset = offset;
+ netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "DS address");
+
+ offset = dissect_nfs4_clientaddr(tvb, offset, netaddr);
+ proto_item_set_len(fitem, offset - old_offset);
+
+ /* The file handle */
+ offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "Filehandle", &last_fh_hash, civ);
+
+ /* Read Latency */
+ offset = dissect_nfs4_io_latency(tvb, offset, tree, "Read");
+
+ /* Write Latency */
+ offset = dissect_nfs4_io_latency(tvb, offset, tree, "Write");
+
+ /* Duration */
+ offset = dissect_nfs4_io_time(tvb, offset, tree, "Duration");
+
+ /* Local? */
+ offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_local, offset);
+ } else {
+ offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_layoutstats);
+ }
+
+ return offset;
+}
+
+static int
+dissect_nfs4_ff_io_stats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
+{
+ offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
+ offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
+ offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
+
+ /* Note that we've already determined that we are in the Flex File Layout Type */
+ offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, tree, civ, FALSE);
+
+ return offset;
+}
+
+static int
+dissect_nfs4_ff_io_error(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+ proto_tree *newtree;
+
+ proto_item *sub_fitem;
+ proto_tree *ss_tree;
+ proto_tree *subtree;
+ proto_item *ss_fitem;
+ guint i;
+ guint count;
+
+ guint opcode;
+
+ newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "IO errors");
+
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_offset, offset);
+ offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_length, offset);
+ offset = dissect_nfs4_stateid(tvb, offset, newtree, NULL);
+
+ count = tvb_get_ntohl(tvb, offset);
+ sub_fitem = proto_tree_add_item(newtree, hf_nfs4_device_error_count,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_device_errors_sub);
+ for (i = 0; i < count; i++) {
+ ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_device_errors_index,
+ tvb, offset+0, 4, i, "Error [%u]", i);
+ ss_tree = proto_item_add_subtree(ss_fitem,
+ ett_nfs4_device_errors_sub);
+ offset = dissect_nfs4_deviceid(tvb, offset, ss_tree);
+ offset = dissect_nfs4_status(tvb, offset, ss_tree, NULL);
+
+ opcode = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(ss_tree, hf_nfs4_io_error_op, tvb, offset, 4, opcode);
+ offset += 4;
+ }
+
+ return offset;
+}
+
+static int
+dissect_nfs4_layoutreturn(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
{
guint returntype;
+ guint layout_type;
+
+ proto_item *sub_fitem;
+ proto_tree *ss_tree;
+ proto_tree *subtree;
+ proto_item *ss_fitem;
+ guint i;
+ guint count;
+
+ offset = dissect_rpc_bool(tvb, tree, hf_nfs4_reclaim, offset);
+
+ layout_type = tvb_get_ntohl(tvb, offset);
+ offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
+
+ offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_iomode, offset);
returntype = tvb_get_ntohl(tvb, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_return_type, offset);
@@ -8370,13 +8548,51 @@ dissect_nfs4_layoutreturn(tvbuff_t *tvb, int offset, proto_tree *tree)
offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
- offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_lrf_body_content);
+
+ /* If not flex files layout type eat the rest and move on.. */
+ if (layout_type == LAYOUT4_FLEX_FILES) {
+ offset += 4; /* Skip past opaque count */
+
+ /* Get the errors */
+ count = tvb_get_ntohl(tvb, offset);
+ sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_ioerrs_count,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_ioerrs_sub);
+ for (i = 0; i < count; i++) {
+ ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_ioerrs_index,
+ tvb, offset+0, 4, i, "IO Error [%u]", i);
+ ss_tree = proto_item_add_subtree(ss_fitem,
+ ett_nfs4_ff_ioerrs_sub);
+
+ offset = dissect_nfs4_ff_io_error(tvb, offset, ss_tree);
+ }
+
+ /* Get the stats */
+ count = tvb_get_ntohl(tvb, offset);
+ sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_iostats_count,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_iostats_sub);
+ for (i = 0; i < count; i++) {
+ ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_iostats_index,
+ tvb, offset+0, 4, i, "IO Stat [%u]", i);
+ ss_tree = proto_item_add_subtree(ss_fitem,
+ ett_nfs4_ff_iostats_sub);
+
+ offset = dissect_nfs4_ff_io_stats(tvb, offset, pinfo, ss_tree, civ);
+ }
+
+ } else {
+ offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_lrf_body_content);
+ }
}
return offset;
}
-
static int
dissect_nfs_layoutreturn_stateid(tvbuff_t *tvb, proto_tree *tree, int offset)
{
@@ -8749,99 +8965,6 @@ dissect_rpc_secparms4(tvbuff_t *tvb, int offset, proto_tree *tree)
}
static int
-dissect_nfs4_io_time(tvbuff_t *tvb, int offset, proto_tree *tree, const char *timer_mode)
-{
- proto_tree *newtree;
-
- newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_time, NULL, "%s", timer_mode);
- offset = dissect_nfs4_nfstime(tvb, offset, newtree);
-
- return offset;
-}
-
-static int
-dissect_nfs4_io_latency(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
-{
- proto_tree *newtree;
-
- newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "%s Latency", io_mode);
-
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_requested, offset);
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_requested, offset);
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_completed, offset);
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_completed, offset);
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_not_delivered, offset);
-
- offset = dissect_nfs4_io_time(tvb, offset, newtree, "Busy time");
- offset = dissect_nfs4_io_time(tvb, offset, newtree, "Completion time");
-
- return offset;
-}
-
-static int
-dissect_nfs4_io_info(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
-{
- proto_tree *newtree;
-
- newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_info, NULL, "%s Info", io_mode);
-
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_count, offset);
- offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_bytes, offset);
-
- return offset;
-}
-
-static int
-dissect_nfs4_layoutstats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
-{
- guint layout_type;
- proto_tree *netaddr;
- proto_item *fitem;
- int old_offset;
- guint32 last_fh_hash = 0;
-
- /* FIXME: Are these here or in the caller? Check for layoutcommit */
- offset = dissect_nfs4_io_info(tvb, offset, tree, "Read");
- offset = dissect_nfs4_io_info(tvb, offset, tree, "Write");
- offset = dissect_nfs4_deviceid(tvb, offset, tree);
-
- layout_type = tvb_get_ntohl(tvb, offset);
- offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
-
- /* If not flex files layout type eat the rest and move on.. */
- if (layout_type == LAYOUT4_FLEX_FILES) {
- /* NFS Flex Files */
- offset += 4; /* Skip past opaque count */
-
- /* The netaddr */
- old_offset = offset;
- netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "DS address");
-
- offset = dissect_nfs4_clientaddr(tvb, offset, netaddr);
- proto_item_set_len(fitem, offset - old_offset);
-
- /* The file handle */
- offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "Filehandle", &last_fh_hash, civ);
-
- /* Read Latency */
- offset = dissect_nfs4_io_latency(tvb, offset, tree, "Read");
-
- /* Write Latency */
- offset = dissect_nfs4_io_latency(tvb, offset, tree, "Write");
-
- /* Duration */
- offset = dissect_nfs4_io_time(tvb, offset, tree, "Duration");
-
- /* Local? */
- offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_local, offset);
- } else {
- offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_layoutstats);
- }
-
- return offset;
-}
-
-static int
dissect_nfs4_layoutget(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
{
guint layout_type;
@@ -9627,10 +9750,7 @@ dissect_nfs4_request_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tre
break;
case NFS4_OP_LAYOUTRETURN:
- offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_reclaim, offset);
- offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
- offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_iomode, offset);
- offset = dissect_nfs4_layoutreturn(tvb, offset, newftree);
+ offset = dissect_nfs4_layoutreturn(tvb, offset, pinfo, newftree, civ);
break;
case NFS4_OP_GETDEVINFO:
@@ -9778,7 +9898,7 @@ dissect_nfs4_request_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tre
wmem_strbuf_append_printf (op_summary[ops_counter].optext,
" StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u Len: %u",
sid_hash, file_offset, length);
- offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, newftree, civ);
+ offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, newftree, civ, TRUE);
break;
case NFS4_OP_SEEK:
@@ -13242,6 +13362,42 @@ proto_register_nfs(void)
"layout", "nfs.layoutstats", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL }},
+ { &hf_nfs4_device_error_count, {
+ "Device Error count", "nfs.device_error_count", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_device_errors_index, {
+ "Device Error index", "nfs.device_errors_index", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_ioerrs_count, {
+ "IO Errors count", "nfs.ff.ioerrs_count", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_ioerrs_index, {
+ "IO Errors index", "nfs.ff.ioerrs_index", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_ioerrs_length, {
+ "length", "nfs.ff.ioerrs_length", FT_UINT64, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_ioerrs_offset, {
+ "offset", "nfs.ff.ioerrs_offset", FT_UINT64, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_iostats_count, {
+ "IO Stats count", "nfs.ff.iostats_count", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_ff_iostats_index, {
+ "IO Stats index", "nfs.ff.iostats_index", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_nfs4_io_error_op, {
+ "OP", "nfs.ff_ioerrs_op", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
+ &names_nfs4_operation_ext, 0, NULL, HFILL }},
+
/* Hidden field for v2, v3, and v4 status */
{ &hf_nfs_status, {
"Status", "nfs.status", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
@@ -13457,6 +13613,9 @@ proto_register_nfs(void)
&ett_nfs4_source_servers_sub,
&ett_nfs4_copy,
&ett_nfs4_copy_notify,
+ &ett_nfs4_device_errors_sub,
+ &ett_nfs4_ff_ioerrs_sub,
+ &ett_nfs4_ff_iostats_sub,
&ett_nfs4_clone,
&ett_nfs4_offload_cancel,
&ett_nfs4_offload_status,