Ethereal-dev: [ethereal-dev] further NFS and mount dissectors

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

From: Uwe Girlich <Uwe.Girlich@xxxxxxxxxxx>
Date: Mon, 29 Nov 1999 13:01:02 +0100
NFS evolves slowly but it does. New checked-in functions are:

packet-mount.c
	MOUNT	v1,v2	MNT	reply

packet-nfs.c
	NFS	v2,v3	LOOKUP	call,reply
	NFS	v2	WRITE	reply
	NFS	v2	CREATE	call,reply
	NFS	v2	REMOVE	call

Index: packet-mount.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-mount.c,v
retrieving revision 1.7
diff -u -r1.7 packet-mount.c
--- packet-mount.c	1999/11/20 06:17:00	1.7
+++ packet-mount.c	1999/11/29 11:44:26
@@ -66,7 +66,34 @@
 static gint ett_mount = -1;
 static gint ett_mount_pathconf_mask = -1;
 
+
+/* RFC 1094, Page 24 */
 static int
+dissect_fhstatus(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+	guint32 status;
+
+	if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+	status = EXTRACT_UINT(pd, offset+0);
+	if (tree) {
+		proto_tree_add_item(tree, hf_mount_status, offset, 4, status);
+	}
+	offset += 4;
+
+	switch (status) {
+		case 0:
+			offset = dissect_fhandle(pd,offset,fd,tree,"fhandle");
+		break;
+		default:
+			/* void */
+		break;
+	}
+
+	return offset;
+}
+
+
+static int
 dissect_mount_dirpath_call(const u_char *pd, int offset, frame_data *fd,
 	proto_tree *tree)
 {
@@ -78,6 +105,18 @@
 	return offset;
 }
 
+
+/* RFC 1094, Page 25,26 */
+static int
+dissect_mount_mnt_reply(const u_char *pd, int offset, frame_data *fd,
+	proto_tree *tree)
+{
+	offset = dissect_fhstatus(pd, offset, fd, tree);
+
+	return offset;
+}
+
+
 #define	OFFS_MASK	32	/* offset of the "pc_mask" field */
 
 #define	PC_ERROR_ALL		0x0001
@@ -273,7 +312,7 @@
 static const vsff mount1_proc[] = {
     { 0, "NULL", NULL, NULL },
     { MOUNTPROC_MNT,        "MNT",      
-		dissect_mount_dirpath_call, NULL },
+		dissect_mount_dirpath_call, dissect_mount_mnt_reply },
     { MOUNTPROC_DUMP,       "DUMP",
 		NULL, NULL },
     { MOUNTPROC_UMNT,      "UMNT",        
@@ -295,7 +334,7 @@
 static const vsff mount2_proc[] = {
     { 0, "NULL", NULL, NULL },
     { MOUNTPROC_MNT,        "MNT",      
-		dissect_mount_dirpath_call, NULL },
+		dissect_mount_dirpath_call, dissect_mount_mnt_reply },
     { MOUNTPROC_DUMP,       "DUMP",
 		NULL, NULL },
     { MOUNTPROC_UMNT,      "UMNT",        
Index: packet-nfs.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-nfs.c,v
retrieving revision 1.8
diff -u -r1.8 packet-nfs.c
--- packet-nfs.c	1999/11/26 13:32:58	1.8
+++ packet-nfs.c	1999/11/29 11:44:34
@@ -41,18 +41,22 @@
 
 static int proto_nfs = -1;
 
+static int hf_nfs_name = -1;
+
 static gint ett_nfs = -1;
 static gint ett_nfs_fhandle = -1;
 static gint ett_nfs_timeval = -1;
 static gint ett_nfs_mode = -1;
 static gint ett_nfs_fattr = -1;
 static gint ett_nfs_sattr = -1;
+static gint ett_nfs_diropargs = -1;
 static gint ett_nfs_mode3 = -1;
 static gint ett_nfs_specdata3 = -1;
 static gint ett_nfs_fh3 = -1;
 static gint ett_nfs_nfstime3 = -1;
 static gint ett_nfs_fattr3 = -1;
 static gint ett_nfs_sattr3 = -1;
+static gint ett_nfs_diropargs3 = -1;
 static gint ett_nfs_sattrguard3 = -1;
 static gint ett_nfs_set_mode3 = -1;
 static gint ett_nfs_set_uid3 = -1;
@@ -390,6 +394,82 @@
 }
 
 
+/* RFC 1094, Page 17 */
+int
+dissect_filename(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
+{
+	offset = dissect_rpc_string(pd,offset,fd,tree,hf);
+	return offset;
+}
+
+
+/* RFC 1094, Page 17 */
+int
+dissect_attrstat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
+	guint32 status;
+
+	offset = dissect_stat(pd, offset, fd, tree, "status", &status);
+	switch (status) {
+		case 0:
+			offset = dissect_fattr(pd, offset, fd, tree, "attributes");
+		break;
+		default:
+			/* do nothing */
+		break;
+	}
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 18 */
+int
+dissect_diropargs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+	proto_item* diropargs_item = NULL;
+	proto_tree* diropargs_tree = NULL;
+	int old_offset = offset;
+
+	if (tree) {
+		diropargs_item = proto_tree_add_text(tree, offset,
+			END_OF_FRAME, "%s", name);
+		if (diropargs_item)
+			diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs);
+	}
+
+	offset = dissect_fhandle (pd,offset,fd,diropargs_tree,"dir");
+	offset = dissect_filename(pd,offset,fd,diropargs_tree,hf_nfs_name);
+
+	/* now we know, that diropargs is shorter */
+	if (diropargs_item) {
+		proto_item_set_len(diropargs_item, offset - old_offset);
+	}
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 18 */
+int
+dissect_diropres(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+	guint32	status;
+
+	offset = dissect_stat(pd, offset, fd, tree, "status", &status);
+	switch (status) {
+		case 0:
+			offset = dissect_fhandle(pd, offset, fd, tree, "file");
+			offset = dissect_fattr  (pd, offset, fd, tree, "attributes");
+		break;
+		default:
+			/* do nothing */
+		break;
+	}
+
+	return offset;
+}
+
+
 /* generic NFS2 call dissector */
 int
 dissect_nfs2_any_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
@@ -426,19 +506,8 @@
 int
 dissect_nfs2_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
 {
-	guint32 status;
+	offset = dissect_attrstat(pd, offset, fd, tree);
 
-	/* attrstat: RFC 1094, Page 17 */
-	offset = dissect_stat(pd, offset, fd, tree, "status", &status);
-	switch (status) {
-		case 0:
-			offset = dissect_fattr(pd, offset, fd, tree, "attributes");
-		break;
-		default:
-			/* do nothing */
-		break;
-	}
-
 	return offset;
 }
 
@@ -458,23 +527,73 @@
 int
 dissect_nfs2_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
 {
-	guint32 status;
+	offset = dissect_attrstat(pd, offset, fd, tree);
 
-	/* attrstat: RFC 1094, Page 17 */
-	offset = dissect_stat(pd, offset, fd, tree, "status", &status);
-	switch (status) {
-		case 0:
-			offset = dissect_fattr(pd, offset, fd, tree, "attributes");
-		break;
-		default:
-			/* do nothing */
-		break;
-	}
+	return offset;
+}
+
 
+/* RFC 1094, Page 6 */
+int
+dissect_nfs2_lookup_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+	offset = dissect_diropargs(pd, offset, fd, tree, "what");
+
 	return offset;
 }
 
 
+/* RFC 1094, Page 6 */
+int
+dissect_nfs2_lookup_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+	offset = dissect_diropres(pd, offset, fd, tree);
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 8 */
+int
+dissect_nfs2_write_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+	offset = dissect_attrstat(pd, offset, fd, tree);
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 8 */
+int
+dissect_nfs2_create_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+	offset = dissect_diropargs(pd, offset, fd, tree, "where");
+	offset = dissect_sattr    (pd, offset, fd, tree, "attributes");
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 8 */
+int
+dissect_nfs2_create_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+	offset = dissect_diropres(pd, offset, fd, tree);
+
+	return offset;
+}
+
+
+/* RFC 1094, Page 8 */
+int
+dissect_nfs2_remove_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+	offset = dissect_diropargs(pd, offset, fd, tree, "where");
+
+	return offset;
+}
+
+
 /* more to come here */
 
 
@@ -485,13 +604,13 @@
 	{ 1,	"GETATTR",	dissect_nfs2_getattr_call,	dissect_nfs2_getattr_reply },
 	{ 2,	"SETATTR",	dissect_nfs2_setattr_call,	dissect_nfs2_setattr_reply },
 	{ 3,	"ROOT",		NULL,				NULL },
-	{ 4,	"LOOKUP",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
+	{ 4,	"LOOKUP",	dissect_nfs2_lookup_call,	dissect_nfs2_lookup_reply },
 	{ 5,	"READLINK",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
 	{ 6,	"READ",		dissect_nfs2_any_call,		dissect_nfs2_any_reply },
 	{ 7,	"WRITECACHE",	NULL,				NULL },
-	{ 8,	"WRITE",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
-	{ 9,	"CREATE",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
-	{ 10,	"REMOVE",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
+	{ 8,	"WRITE",	dissect_nfs2_any_call,		dissect_nfs2_write_reply },
+	{ 9,	"CREATE",	dissect_nfs2_create_call,	dissect_nfs2_create_reply },
+	{ 10,	"REMOVE",	dissect_nfs2_remove_call,	dissect_nfs2_any_reply },
 	{ 11,	"RENAME",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
 	{ 12,	"LINK",		dissect_nfs2_any_call,		dissect_nfs2_any_reply },
 	{ 13,	"SYMLINK",	dissect_nfs2_any_call,		dissect_nfs2_any_reply },
@@ -531,6 +650,15 @@
 
 /* RFC 1813, Page 15 */
 int
+dissect_filename3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
+{
+	offset = dissect_rpc_string(pd,offset,fd,tree,hf);
+	return offset;
+}
+
+
+/* RFC 1813, Page 15 */
+int
 dissect_fileid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
 char* name)
 {
@@ -1335,6 +1463,33 @@
 }
 
 
+/* RFC 1813, Page 27 */
+int
+dissect_diropargs3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+	proto_item* diropargs3_item = NULL;
+	proto_tree* diropargs3_tree = NULL;
+	int old_offset = offset;
+
+	if (tree) {
+		diropargs3_item = proto_tree_add_text(tree, offset,
+			END_OF_FRAME, "%s", name);
+		if (diropargs3_item)
+			diropargs3_tree = proto_item_add_subtree(diropargs3_item, ett_nfs_diropargs3);
+	}
+
+	offset = dissect_nfs_fh3  (pd, offset, fd, diropargs3_tree, "dir");
+	offset = dissect_filename3(pd, offset, fd, diropargs3_tree, hf_nfs_name);
+
+	/* now we know, that diropargs3 is shorter */
+	if (diropargs3_item) {
+		proto_item_set_len(diropargs3_item, offset - old_offset);
+	}
+
+	return offset;
+}
+
+
 /* generic NFS3 call dissector */
 int
 dissect_nfs3_any_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
@@ -1463,13 +1618,43 @@
 }
 
 
+/* RFC 1813, Page 37 */
+int
+dissect_nfs3_lookup_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+	offset = dissect_diropargs3 (pd, offset, fd, tree, "what");
+	return offset;
+}
+
+
+/* RFC 1813, Page 37 */
+int
+dissect_nfs3_lookup_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+	guint32 status;
+
+	offset = dissect_nfsstat3(pd, offset, fd, tree, "status", &status);
+	switch (status) {
+		case 0:
+			offset = dissect_nfs_fh3     (pd, offset, fd, tree, "object");
+			offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
+			offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
+		break;
+		default:
+			offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
+		break;
+	}
+		
+	return offset;
+}
+
 /* proc number, "proc name", dissect_request, dissect_reply */
 /* NULL as function pointer means: take the generic one. */
 const vsff nfs3_proc[] = {
 	{ 0,	"NULL",		NULL,				NULL },
 	{ 1,	"GETATTR",	dissect_nfs3_getattr_call,	dissect_nfs3_getattr_reply },
 	{ 2,	"SETATTR",	dissect_nfs3_setattr_call,	dissect_nfs3_setattr_reply },
-	{ 3,	"LOOKUP",	dissect_nfs3_any_call,		dissect_nfs3_any_reply },
+	{ 3,	"LOOKUP",	dissect_nfs3_lookup_call,	dissect_nfs3_lookup_reply },
 	{ 4,	"ACCESS",	dissect_nfs3_any_call,		dissect_nfs3_any_reply },
 	{ 5,	"READLINK",	dissect_nfs3_any_call,		dissect_nfs3_any_reply },
 	{ 6,	"READ",		dissect_nfs3_any_call,		dissect_nfs3_any_reply },
@@ -1496,6 +1681,11 @@
 void
 proto_register_nfs(void)
 {
+	static hf_register_info hf[] = {
+		{ &hf_nfs_name, {
+			"Name", "nfs.name", FT_STRING, BASE_DEC,
+			NULL, 0, "Name" }}
+	};
 	static gint *ett[] = {
 		&ett_nfs,
 		&ett_nfs_fhandle,
@@ -1503,12 +1693,14 @@
 		&ett_nfs_mode,
 		&ett_nfs_fattr,
 		&ett_nfs_sattr,
+		&ett_nfs_diropargs,
 		&ett_nfs_mode3,
 		&ett_nfs_specdata3,
 		&ett_nfs_fh3,
 		&ett_nfs_nfstime3,
 		&ett_nfs_fattr3,
 		&ett_nfs_sattr3,
+		&ett_nfs_diropargs3,
 		&ett_nfs_sattrguard3,
 		&ett_nfs_set_mode3,
 		&ett_nfs_set_uid3,
@@ -1522,6 +1714,7 @@
 		&ett_nfs_wcc_data,
 	};
 	proto_nfs = proto_register_protocol("Network File System", "nfs");
+	proto_register_field_array(proto_nfs, hf, array_length(hf));
 	proto_register_subtree_array(ett, array_length(ett));
 
 	/* Register the protocol as RPC */