Wireshark-dev: [Wireshark-dev] [PATCH 07/16] NFS: Always show all possible NFS access bits for
From: Pali Rohár <pali@xxxxxxxxxx>
Date: Fri, 13 Sep 2024 23:08:42 +0200
Hide only bits which are not supported by particular NFS version, which are xattr access bits for NFSv3 packets. --- epan/dissectors/packet-nfs.c | 100 ++++++++++++++++++++++---------- epan/dissectors/packet-nfs.h | 2 +- epan/dissectors/packet-nfsacl.c | 2 +- 3 files changed, 72 insertions(+), 32 deletions(-) diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c index d71f12374154..1adee60fff5e 100644 --- a/epan/dissectors/packet-nfs.c +++ b/epan/dissectors/packet-nfs.c @@ -4731,6 +4731,29 @@ dissect_nfs3_lookup_reply(tvbuff_t *tvb, packet_info *pinfo, } +static gchar* +proto_item_get_text(wmem_allocator_t *pool, proto_item *item) +{ + field_info *fi = NULL; + gchar *result; + + if (item == NULL) + return NULL; + + fi = PITEM_FINFO(item); + + if (fi == NULL) + return NULL; + + if (fi->rep == NULL) { + fi->rep = wmem_new(PNODE_POOL(item), item_label_t); + proto_item_fill_label(fi, fi->rep->representation); + } + + result = wmem_strdup(pool, fi->rep->representation); + return result; +} + static const value_string accvs[] = { { 0x001, "RD" }, { 0x002, "LU" }, @@ -4749,7 +4772,7 @@ static const true_false_string tfs_access_rights = {"allowed", "*Access Denied*" proto_tree* display_access_items(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree *tree, - uint32_t amask, char mtype, int version, wmem_strbuf_t* optext, const char *label) + uint32_t amask, uint32_t rmask, char mtype, int version, wmem_strbuf_t* optext, const char *label) { bool nfsv3 = ((version == 3) ? true : false); proto_item *access_item = NULL; @@ -4796,8 +4819,7 @@ display_access_items(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree * } for (itype=0; itype < 9; itype++) { - if (amask & accvs[itype].value) { - if (mtype != 'S' && mtype != 'R') { + if (mtype != 'S' && mtype != 'R' && (amask & accvs[itype].value)) { /* List access type in Info column and tree */ if (nfsv3) { col_append_fstr(pinfo->cinfo, COL_INFO, " %s", accvs[itype].strptr); @@ -4840,24 +4862,36 @@ display_access_items(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree * tvb, offset, 4, ENC_BIG_ENDIAN); break; case 6: + if (nfsv3) access_subitem = NULL; else access_subitem = proto_tree_add_item (access_subtree, (mtype == 'S' ? hf_nfs_access_supp_xattr_read : hf_nfs_access_xattr_read), tvb, offset, 4, ENC_BIG_ENDIAN); break; case 7: + if (nfsv3) access_subitem = NULL; else access_subitem = proto_tree_add_item (access_subtree, (mtype == 'S' ? hf_nfs_access_supp_xattr_write : hf_nfs_access_xattr_write), tvb, offset, 4, ENC_BIG_ENDIAN); break; case 8: + if (nfsv3) access_subitem = NULL; else access_subitem = proto_tree_add_item (access_subtree, (mtype == 'S' ? hf_nfs_access_supp_xattr_list : hf_nfs_access_xattr_list), tvb, offset, 4, ENC_BIG_ENDIAN); break; + default: + access_subitem = NULL; + break; + } + if (!(rmask & accvs[itype].value) && access_subitem) { + const char* text_start = proto_item_get_text(pinfo->pool, access_subitem); + const char* text_end = text_start ? strrchr(text_start, ':') : NULL; + if (text_start && text_end) + proto_item_set_text(access_subitem, "%.*s: %s", (int)(text_end - text_start), text_start, mtype == 'C' ? "not asked" : "unknown"); + } else if (mtype == 'C' && access_subitem) { + proto_item_append_text(access_subitem, "?" ); } - if (mtype == 'C') proto_item_append_text(access_subitem, "?" ); } - } } if (mtype != 'S' && mtype != 'R') { if (nfsv3) { @@ -4882,6 +4916,7 @@ dissect_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree * uint32_t mask_not_supp; uint32_t mask_denied; uint32_t mask_allowed; + uint32_t mask_result; uint32_t e_check, e_rights; bool nfsv3 = ((version == 3) ? true : false); bool nfsv4 = ((version == 4) ? true : false); @@ -4914,6 +4949,11 @@ dissect_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree * else mask_not_supp = 0; + if (acc_req) + mask_result = *acc_req; + else + mask_result = acc_supp; + e_check = acc_supp; e_rights = acc_supp & acc_rights; /* guard against broken implementations */ mask_denied = e_check ^ e_rights; @@ -4921,26 +4961,26 @@ dissect_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree * if (nfsv4) { if (mask_not_supp > 0) { - display_access_items(tvb, offset, pinfo, tree, mask_not_supp, 'N', 4, + display_access_items(tvb, offset, pinfo, tree, mask_not_supp, mask_result, 'N', 4, optext, "NOT Supported") ; } - display_access_items(tvb, offset, pinfo, tree, acc_supp, 'S', 4, + display_access_items(tvb, offset, pinfo, tree, acc_supp, mask_result, 'S', 4, optext, "Supported"); offset+=4; } if (mask_denied > 0) { - display_access_items(tvb, offset, pinfo, tree, mask_denied, 'D', version, + display_access_items(tvb, offset, pinfo, tree, mask_denied, mask_result, 'D', version, optext, "Access Denied") ; } if (mask_allowed > 0) { - display_access_items(tvb, offset, pinfo, tree, mask_allowed, 'A', version, + display_access_items(tvb, offset, pinfo, tree, mask_allowed, mask_result, 'A', version, optext, "Allowed") ; } /* Pass the OR'd masks rather than acc_rights so that display_access_items will process types that have been denied access. Since proto_tree_add_item uses the mask in the tvb (not the passed mask), the correct (denied) access is displayed. */ access_tree = display_access_items(tvb, offset, pinfo, tree, - (mask_allowed | mask_denied), 'R', version, optext, NULL) ; + (mask_allowed | mask_denied), mask_result, 'R', version, optext, NULL) ; ditem = proto_tree_add_boolean(access_tree, hf_nfs_access_denied, tvb, offset, 4, (mask_denied > 0 ? true : false )); @@ -4969,7 +5009,7 @@ dissect_nfs3_access_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", fhhash); proto_item_append_text(tree, ", ACCESS Call, FH: 0x%08x", fhhash); - display_access_items(tvb, offset, pinfo, tree, amask, 'C', 3, NULL, "Check") ; + display_access_items(tvb, offset, pinfo, tree, amask, amask, 'C', 3, NULL, "Check") ; offset+=4; return offset; @@ -10132,7 +10172,7 @@ dissect_nfs4_request_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tre civ->private_data = acc_request; wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash); - display_access_items(tvb, offset, pinfo, fitem, amask, 'C', 4, + display_access_items(tvb, offset, pinfo, fitem, amask, amask, 'C', 4, op_summary[ops_counter].optext, "Check") ; offset+=4; } @@ -14043,109 +14083,109 @@ proto_register_nfs(void) }, { &hf_nfs_access_supp_read, { "0x001 READ", "nfs.access_supp_read", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_READ, NULL, HFILL } }, { &hf_nfs_access_supp_lookup, { "0x002 LOOKUP", "nfs.access_supp_lookup", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_LOOKUP, NULL, HFILL } }, { &hf_nfs_access_supp_modify, { "0x004 MODIFY", "nfs.access_supp_modify", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_MODIFY, NULL, HFILL } }, { &hf_nfs_access_supp_extend, { "0x008 EXTEND", "nfs.access_supp_extend", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXTEND, NULL, HFILL } }, { &hf_nfs_access_supp_delete, { "0x010 DELETE", "nfs.access_supp_delete", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_DELETE, NULL, HFILL } }, { &hf_nfs_access_supp_execute, { "0x020 EXECUTE", "nfs.access_supp_execute", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXECUTE, NULL, HFILL } }, { &hf_nfs_access_supp_xattr_read, { "0x040 XATTR READ", "nfs.access_supp_xattr_read", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_READ, NULL, HFILL } }, { &hf_nfs_access_supp_xattr_write, { "0x080 XATTR WRITE", "nfs.access_supp_xattr_write", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_WRITE, NULL, HFILL } }, { &hf_nfs_access_supp_xattr_list, { "0x100 XATTR LIST", "nfs.access_supp_xattr_list", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_LIST, NULL, HFILL } }, { &hf_nfs_access_read, { "0x001 READ", "nfs.access_read", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_READ, NULL, HFILL } }, { &hf_nfs_access_lookup, { "0x002 LOOKUP", "nfs.access_lookup", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_LOOKUP, NULL, HFILL } }, { &hf_nfs_access_modify, { "0x004 MODIFY", "nfs.access_modify", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_MODIFY, NULL, HFILL } }, { &hf_nfs_access_extend, { "0x008 EXTEND", "nfs.access_extend", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXTEND, NULL, HFILL } }, { &hf_nfs_access_delete, { "0x010 DELETE", "nfs.access_delete", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_DELETE, NULL, HFILL } }, { &hf_nfs_access_execute, { "0x020 EXECUTE", "nfs.access_execute", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXECUTE, NULL, HFILL } }, { &hf_nfs_access_xattr_read, { "0x040 XATTR READ", "nfs.access_xattr_read", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_READ, NULL, HFILL } }, { &hf_nfs_access_xattr_write, { "0x080 XATTR WRITE", "nfs.access_xattr_write", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_WRITE, NULL, HFILL } }, { &hf_nfs_access_xattr_list, { "0x100 XATTR LIST", "nfs.access_xattr_list", - FT_BOOLEAN, 8, + FT_BOOLEAN, 32, TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_LIST, NULL, HFILL } }, diff --git a/epan/dissectors/packet-nfs.h b/epan/dissectors/packet-nfs.h index 1fcfe9f3e54a..c51465f6f868 100644 --- a/epan/dissectors/packet-nfs.h +++ b/epan/dissectors/packet-nfs.h @@ -216,7 +216,7 @@ extern int dissect_nfs3_post_op_attr(tvbuff_t *tvb, int offset, packet_info *pin const char* name); extern int dissect_nfs2_fattr(tvbuff_t *tvb, int offset, proto_tree *tree, const char* name); extern proto_tree* display_access_items(tvbuff_t* tvb, int offset, packet_info* pinfo, - proto_tree* tree, uint32_t amask, char mtype, int version, + proto_tree* tree, uint32_t amask, uint32_t rmask, char mtype, int version, wmem_strbuf_t* optext, const char* label); extern int dissect_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree, int version, wmem_strbuf_t *optext, rpc_call_info_value *civ); diff --git a/epan/dissectors/packet-nfsacl.c b/epan/dissectors/packet-nfsacl.c index a876029c9049..b484c5093d46 100644 --- a/epan/dissectors/packet-nfsacl.c +++ b/epan/dissectors/packet-nfsacl.c @@ -288,7 +288,7 @@ dissect_nfsacl2_access_call(tvbuff_t *tvb, packet_info *pinfo _U_, acc_request = (uint32_t *)wmem_memdup(wmem_file_scope(), &amask, sizeof(uint32_t)); civ->private_data = acc_request; - display_access_items(tvb, offset, pinfo, tree, amask, 'C', 3, NULL, "Check") ; + display_access_items(tvb, offset, pinfo, tree, amask, amask, 'C', 3, NULL, "Check") ; offset+=4; return offset; -- 2.20.1
- References:
- [Wireshark-dev] [PATCH 00/16] NFS: Improve dissector
- From: Pali Rohár
- [Wireshark-dev] [PATCH 00/16] NFS: Improve dissector
- Prev by Date: [Wireshark-dev] [PATCH 12/16] NFS: Consistently show NFS4 fileid in decimal notation, including mounted_on_fileid
- Next by Date: [Wireshark-dev] [PATCH 04/16] NFS: Fix detection of NFS4 packets
- Previous by thread: [Wireshark-dev] [PATCH 12/16] NFS: Consistently show NFS4 fileid in decimal notation, including mounted_on_fileid
- Next by thread: [Wireshark-dev] [PATCH 04/16] NFS: Fix detection of NFS4 packets
- Index(es):