Ethereal-dev: [Ethereal-dev] [patch] packet-nfs.c - fix NFSv4 ACL decoding

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Mike Frisch <mfrisch@xxxxxxxxxx>
Date: Mon, 5 Aug 2002 22:56:15 -0400
The enclosed patch addresses NFSv4 ACL decoding issues.
Index: packet-nfs.c
===================================================================
RCS file: /cvsroot/ethereal/packet-nfs.c,v
retrieving revision 1.74
diff -u -r1.74 packet-nfs.c
--- packet-nfs.c	2002/08/02 23:35:55	1.74
+++ packet-nfs.c	2002/08/06 02:53:30
@@ -278,6 +278,9 @@
 static int hf_nfs_stateid4_other = -1;
 static int hf_nfs_lock4_reclaim = -1;
 static int hf_nfs_acl4 = -1;
+static int hf_nfs_callback_ident = -1;
+static int hf_nfs_r_netid = -1;
+static int hf_nfs_r_addr = -1;
 
 static gint ett_nfs = -1;
 static gint ett_nfs_fh_encoding = -1;
@@ -378,6 +381,9 @@
 static gint ett_nfs_stateid4 = -1;
 static gint ett_nfs_fattr4_fh_expire_type = -1;
 static gint ett_nfs_ace4 = -1;
+static gint ett_nfs_clientaddr4 = -1;
+static gint ett_nfs_aceflag4 = -1;
+static gint ett_nfs_acemask4 = -1;
 
 
 /* fhandle displayfilters to match also corresponding request/response
@@ -4522,16 +4528,153 @@
 	return offset;
 }
 
+static const value_string names_acetype4[] = {
+#define ACE4_ACCESS_ALLOWED_ACE_TYPE	0x00000000
+	{	ACE4_ACCESS_ALLOWED_ACE_TYPE, "ACE4_ACCESS_ALLOWED_ACE_TYPE"  },
+#define ACE4_ACCESS_DENIED_ACE_TYPE		0x00000001
+	{	ACE4_ACCESS_DENIED_ACE_TYPE, "ACE4_ACCESS_DENIED_ACE_TYPE" },
+#define ACE4_SYSTEM_AUDIT_ACE_TYPE		0x00000002
+	{	ACE4_SYSTEM_AUDIT_ACE_TYPE, "ACE4_SYSTEM_AUDIT_ACE_TYPE" },
+#define ACE4_SYSTEM_ALARM_ACE_TYPE		0x00000003
+	{	ACE4_SYSTEM_ALARM_ACE_TYPE, "ACE4_SYSTEM_ALARM_ACE_TYPE"	},
+	{ 0, NULL }
+};
+
+/* ACE mask values */
+#define ACE4_READ_DATA				0x00000001
+#define ACE4_LIST_DIRECTORY		0x00000001
+#define ACE4_WRITE_DATA				0x00000002
+#define ACE4_ADD_FILE				0x00000002
+#define ACE4_APPEND_DATA			0x00000004
+#define ACE4_ADD_SUBDIRECTORY		0x00000004
+#define ACE4_READ_NAMED_ATTRS		0x00000008
+#define ACE4_WRITE_NAMED_ATTRS	0x00000010
+#define ACE4_EXECUTE					0x00000020
+#define ACE4_DELETE_CHILD			0x00000040
+#define ACE4_READ_ATTRIBUTES		0x00000080
+#define ACE4_WRITE_ATTRIBUTES		0x00000100
+#define ACE4_DELETE					0x00010000
+#define ACE4_READ_ACL				0x00020000
+#define ACE4_WRITE_ACL				0x00040000
+#define ACE4_WRITE_OWNER			0x00080000
+#define ACE4_SYNCHRONIZE			0x00100000
+
+static int
+dissect_nfs_acemask4(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+	guint32 acemask;
+	proto_item *acemask_item = NULL;
+	proto_tree *acemask_tree = NULL;
+
+	acemask = tvb_get_ntohl(tvb, offset);
+
+	acemask_item = proto_tree_add_text(tree, tvb, offset, 4, 
+		"acemask: 0x%08x", acemask);
+
+	if (acemask_item)
+		acemask_tree = proto_item_add_subtree(acemask_item, ett_nfs_acemask4);
+
+	if (acemask_tree)
+	{
+		if (acemask & ACE4_READ_DATA)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4, 
+				"ACE4_READ_DATA/ACE4_LIST_DIRECTORY (0x%08x)",
+				ACE4_READ_DATA);
+
+		if (acemask & ACE4_WRITE_DATA)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_WRITE_DATA/ACE4_ADD_FILE (0x%08x)",
+				ACE4_WRITE_DATA);
+
+		if (acemask & ACE4_APPEND_DATA)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_ADD_FILE/ACE4_ADD_SUBDIRECTORY (0x%08x)",
+				ACE4_APPEND_DATA);
+
+		if (acemask & ACE4_READ_NAMED_ATTRS)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_READ_NAMED_ATTRS (0x%08x)",
+				ACE4_READ_NAMED_ATTRS);
+
+		if (acemask & ACE4_WRITE_NAMED_ATTRS)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_WRITE_NAMED_ATTRS (0x%08x)",
+				ACE4_WRITE_NAMED_ATTRS);
+
+		if (acemask & ACE4_EXECUTE)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_EXECUTE (0x%08x)",
+				ACE4_EXECUTE);
+
+		if (acemask & ACE4_DELETE_CHILD)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_DELETE_CHILD (0x%08x)",
+				ACE4_DELETE_CHILD);
+					
+		if (acemask & ACE4_READ_ATTRIBUTES)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_READ_ATTRIBUTES (0x%08x)",
+				ACE4_READ_ATTRIBUTES);
+
+		if (acemask & ACE4_WRITE_ATTRIBUTES)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_WRITE_ATTRIBUTES (0x%08x)",
+				ACE4_WRITE_ATTRIBUTES);
+
+		if (acemask & ACE4_DELETE)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_DELETE (0x%08x)",
+				ACE4_DELETE);
+
+		if (acemask & ACE4_READ_ACL)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_READ_ACL (0x%08x)",
+				ACE4_READ_ACL);
+
+		if (acemask & ACE4_WRITE_ACL)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_WRITE_ACL (0x%08x)",
+				ACE4_WRITE_ACL);
+
+		if (acemask & ACE4_WRITE_OWNER)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_WRITE_OWNER (0x%08x)",
+				ACE4_WRITE_OWNER);
+
+		if (acemask & ACE4_SYNCHRONIZE)
+			proto_tree_add_text(acemask_tree, tvb, offset, 4,
+				"ACE4_SYNCHRONIZE (0x%08x)",
+				ACE4_SYNCHRONIZE);
+	}
+
+	offset += 4;
+
+	return offset;
+}
+
+/* ACE flag values */
+#define ACE4_FILE_INHERIT_ACE					0x00000001
+#define ACE4_DIRECTORY_INHERIT_ACE			0x00000002
+#define ACE4_NO_PROPAGATE_INHERIT_ACE		0x00000004
+#define ACE4_INHERIT_ONLY_ACE					0x00000008
+#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	0x00000010
+#define ACE4_FAILED_ACCESS_ACE_FLAG			0x00000020
+#define ACE4_IDENTIFIER_GROUP					0x00000040
+
+
 static int
 dissect_nfs_ace4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
 	proto_tree *tree)
 {
 	proto_item* ace_item = NULL;
 	proto_tree* ace_tree = NULL;
+	proto_item *aceflag_item = NULL;
+	proto_tree *aceflag_tree = NULL;
+	guint32 aceflag4;
 
 	if (tree) {
 		ace_item = proto_tree_add_text(tree, tvb, offset, 4, 
-			"Access Control Entry");
+			"ACE");
 
 		if (ace_item)
 			ace_tree = proto_item_add_subtree(ace_item, ett_nfs_ace4);
@@ -4539,8 +4682,53 @@
 
 	if (ace_tree) {
 		offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_acetype4, offset);
-		offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_aceflag4, offset);
-		offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_acemask4, offset);
+
+		aceflag4 = tvb_get_ntohl(tvb, offset);
+
+		aceflag_item = proto_tree_add_text(ace_tree, tvb, offset, 4, 
+			"aceflag: 0x%08x", aceflag4);
+
+		if (aceflag_item)
+		{
+			aceflag_tree = proto_item_add_subtree(aceflag_item, ett_nfs_aceflag4);
+
+			if (aceflag_tree)
+			{
+				if (aceflag4 & ACE4_FILE_INHERIT_ACE)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4, 
+						"ACE4_FILE_INHERIT_ACE (0x%08x)", ACE4_FILE_INHERIT_ACE);
+
+				if (aceflag4 & ACE4_DIRECTORY_INHERIT_ACE)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+						"ACE4_DIRECTORY_INHERIT_ACE (0x%08x)",
+						 ACE4_DIRECTORY_INHERIT_ACE);
+
+				if (aceflag4 & ACE4_INHERIT_ONLY_ACE)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4, 
+						"ACE4_INHERIT_ONLY_ACE (0x%08x)", 
+						ACE4_INHERIT_ONLY_ACE);
+
+				if (aceflag4 & ACE4_SUCCESSFUL_ACCESS_ACE_FLAG)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+						"ACE4_SUCCESSFUL_ACCESS_ACE_FLAG (0x%08x)",
+						ACE4_SUCCESSFUL_ACCESS_ACE_FLAG);
+
+				if (aceflag4 & ACE4_FAILED_ACCESS_ACE_FLAG)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+						"ACE4_FAILED_ACCESS_ACE_FLAG (0x%08x)",
+						ACE4_FAILED_ACCESS_ACE_FLAG);
+
+				if (aceflag4 & ACE4_IDENTIFIER_GROUP)
+					proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+						"ACE4_IDENTIFIER_GROUP (0x%08x)",
+						ACE4_IDENTIFIER_GROUP);
+			}
+		}
+
+		offset += 4;
+
+		offset = dissect_nfs_acemask4(tvb, offset, ace_tree);
+		
 		offset = dissect_nfs_utf8string(tvb, offset, ace_tree, hf_nfs_who, NULL);
 	}
 
@@ -5375,19 +5563,29 @@
 static int
 dissect_nfs_clientaddr4(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
-	offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
-	offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
+	offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_r_netid);
+	offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_r_addr);
 
 	return offset;
 }
 	
 
 static int
-dissect_nfs_cb_client4(tvbuff_t *tvb, int offset,
-	proto_tree *tree)
+dissect_nfs_cb_client4(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
+	proto_tree *cb_location = NULL;
+	proto_item *fitem = NULL;
+
 	offset = dissect_rpc_uint32(tvb, tree, hf_nfs_cb_program, offset);
-	offset = dissect_nfs_clientaddr4(tvb, offset, tree);
+
+	fitem = proto_tree_add_text(tree, tvb, offset, 0, "cb_location");
+
+	if (fitem) 
+	{
+		cb_location = proto_item_add_subtree(fitem, ett_nfs_clientaddr4);
+	
+		offset = dissect_nfs_clientaddr4(tvb, offset, cb_location);
+	}
 
 	return offset;
 }
@@ -5826,6 +6024,15 @@
 }
 
 static int
+dissect_nfs_client_id4(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+	offset = dissect_rpc_uint64(tvb, tree, hf_nfs_verifier4, offset);
+	offset = dissect_rpc_data(tvb, tree, hf_nfs_client_id4_id, offset);
+
+	return offset;
+}
+
+static int
 dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo, 
 	proto_tree *tree)
 {
@@ -6067,28 +6274,29 @@
 		case NFS4_OP_SETCLIENTID:
 			{
 				proto_tree *client_tree = NULL;
+				proto_tree *callback_tree = NULL;
 
 				fitem = proto_tree_add_text(newftree, tvb, offset, 0, "client");
-
-				if (fitem) 
+				if (fitem)
 				{
 					client_tree = proto_item_add_subtree(fitem, ett_nfs_client_id4);
 
-					if (newftree)
-					{
-						offset = dissect_rpc_uint64(tvb, ftree, hf_nfs_clientid4, 
-							offset);
-						offset = dissect_nfsdata(tvb, offset, client_tree, 
-							hf_nfs_client_id4_id); 
-					}
+					if (client_tree)
+						offset = dissect_nfs_client_id4(tvb, offset, client_tree);
 				}
 
 				fitem = proto_tree_add_text(newftree, tvb, offset, 0, "callback");
-				if (fitem) {
-					newftree = proto_item_add_subtree(fitem, ett_nfs_cb_client4);
-					if (newftree)
-						offset = dissect_nfs_cb_client4(tvb, offset, newftree);
+				if (fitem) 
+				{
+					callback_tree = proto_item_add_subtree(fitem, 
+						ett_nfs_cb_client4);
+
+					if (callback_tree)
+						offset = dissect_nfs_cb_client4(tvb, offset, callback_tree);
 				}
+
+				offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_callback_ident, 
+					offset);
 			}
 			break;
 
@@ -7034,7 +7242,7 @@
 
 		{ &hf_nfs_acetype4, {
 			"acetype", "nfs.acetype4", FT_UINT32, BASE_DEC,
-			NULL, 0, "nfs.acetype4", HFILL }},
+			VALS(names_acetype4), 0, "nfs.acetype4", HFILL }},
 
 		{ &hf_nfs_aceflag4, {
 			"aceflag", "nfs.aceflag4", FT_UINT32, BASE_DEC,
@@ -7149,7 +7357,7 @@
 			NULL, 0, "nfs.delegate_stateid", HFILL }},
 
 		{ &hf_nfs_verifier4, {
-			"verifier", "nfs.verifier4", FT_UINT64, BASE_DEC,
+			"verifier", "nfs.verifier4", FT_UINT64, BASE_HEX,
 			NULL, 0, "nfs.verifier4", HFILL }},
 
 		{ &hf_nfs_cookie4, {
@@ -7285,16 +7493,28 @@
 			BASE_DEC, NULL, 0, "qop", HFILL }},
 
 		{ &hf_nfs_client_id4_id, {
-			"Data", "nfs.nfs_client_id4.id", FT_BYTES, BASE_DEC,
-			NULL, 0, "Data", HFILL }},
+			"id", "nfs.nfs_client_id4.id", FT_BYTES, BASE_DEC,
+			NULL, 0, "nfs.nfs_client_id4.id", HFILL }},
 
 		{ &hf_nfs_stateid4_other, {
 			"Data", "nfs.stateid4.other", FT_BYTES, BASE_DEC,
 			NULL, 0, "Data", HFILL }},
 
 		{ &hf_nfs_acl4, {
-			"Access Control List", "nfs.acl", FT_NONE, BASE_NONE,
+			"ACL", "nfs.acl", FT_NONE, BASE_NONE,
 			NULL, 0, "Access Control List", HFILL }},
+
+		{ &hf_nfs_callback_ident, {
+			"callback_ident", "nfs.callback.ident", FT_UINT32, BASE_HEX,
+			NULL, 0, "Callback Identifier", HFILL }},
+
+		{ &hf_nfs_r_netid, {
+			"r_netid", "nfs.r_netid", FT_BYTES, BASE_DEC, NULL, 0, 
+			"r_netid", HFILL }},
+
+		{ &hf_nfs_r_addr, {
+			"r_addr", "nfs.r_addr", FT_BYTES, BASE_DEC, NULL, 0,
+			"r_addr", HFILL }},
 	};
 
 	static gint *ett[] = {
@@ -7394,7 +7614,10 @@
 		&ett_nfs_secinfo4_flavor_info,
 		&ett_nfs_stateid4,
 		&ett_nfs_fattr4_fh_expire_type,
-		&ett_nfs_ace4
+		&ett_nfs_ace4,
+		&ett_nfs_clientaddr4,
+		&ett_nfs_aceflag4,
+		&ett_nfs_acemask4,
 	};
 	module_t *nfs_module;