aboutsummaryrefslogtreecommitdiffstats
path: root/packet-nfs.c
diff options
context:
space:
mode:
authorNathan Neulinger <nneul@umr.edu>1999-11-15 14:17:20 +0000
committerNathan Neulinger <nneul@umr.edu>1999-11-15 14:17:20 +0000
commitb72c0d1f60e3db127fba8494eb9fb00d516c6088 (patch)
treed5fecec4094c54b28370c295bafc91e9a3858828 /packet-nfs.c
parente1ef668523ba2215888a9f82a70e6ee6e3c79c8b (diff)
Uwe Girlich's patches for nfs,mount,portmap and addition of nlm.
svn path=/trunk/; revision=1034
Diffstat (limited to 'packet-nfs.c')
-rw-r--r--packet-nfs.c654
1 files changed, 633 insertions, 21 deletions
diff --git a/packet-nfs.c b/packet-nfs.c
index 446847cee9..0d454fd41a 100644
--- a/packet-nfs.c
+++ b/packet-nfs.c
@@ -2,7 +2,7 @@
* Routines for nfs dissection
* Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
*
- * $Id: packet-nfs.c,v 1.2 1999/11/05 07:16:23 guy Exp $
+ * $Id: packet-nfs.c,v 1.3 1999/11/15 14:17:18 nneul Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
@@ -94,7 +94,7 @@ char* name, guint32* status)
if (tree) {
proto_tree_add_text(tree, offset, 4,
- "%s (stat): %s (%u)", name, stat_name, stat);
+ "%s: %s (%u)", name, stat_name, stat);
}
offset += 4;
@@ -128,7 +128,7 @@ char* name)
if (tree) {
proto_tree_add_text(tree, offset, 4,
- "%s (ftype): %s (%u)", name, ftype_name, ftype);
+ "%s: %s (%u)", name, ftype_name, ftype);
}
offset += 4;
@@ -145,7 +145,7 @@ dissect_fhandle(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
if (tree) {
fitem = proto_tree_add_text(tree, offset, FHSIZE,
- "%s (fhandle)", name);
+ "%s", name);
if (fitem)
ftree = proto_item_add_subtree(fitem, ETT_NFS_FHANDLE);
}
@@ -175,7 +175,7 @@ dissect_timeval(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
if (tree) {
time_item = proto_tree_add_text(tree, offset, 8,
- "%s (timeval): %u.%06u", name, seconds, mseconds);
+ "%s: %u.%06u", name, seconds, mseconds);
if (time_item)
time_tree = proto_item_add_subtree(time_item, ETT_NFS_TIMEVAL);
}
@@ -214,7 +214,7 @@ char* name)
if (tree) {
mode_item = proto_tree_add_text(tree, offset, 4,
- "%s (mode): 0%o", name, mode);
+ "%s: 0%o", name, mode);
if (mode_item)
mode_tree = proto_item_add_subtree(mode_item, ETT_NFS_MODE);
}
@@ -264,7 +264,7 @@ dissect_fattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, ch
if (tree) {
fattr_item = proto_tree_add_text(tree, offset,
- END_OF_FRAME, "%s (fattr)", name);
+ END_OF_FRAME, "%s", name);
if (fattr_item)
fattr_tree = proto_item_add_subtree(fattr_item, ETT_NFS_FATTR);
}
@@ -293,6 +293,38 @@ dissect_fattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, ch
}
+/* RFC 1094, Page 17 */
+int
+dissect_sattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* sattr_item = NULL;
+ proto_tree* sattr_tree = NULL;
+ int old_offset = offset;
+
+ if (tree) {
+ sattr_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (sattr_item)
+ sattr_tree = proto_item_add_subtree(sattr_item, ETT_NFS_SATTR);
+ }
+
+ /* some how we should indicate here, that -1 means "do not set" */
+ offset = dissect_mode (pd,offset,fd,sattr_tree,"mode");
+ offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"uid");
+ offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"gid");
+ offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"size");
+ offset = dissect_timeval (pd,offset,fd,sattr_tree,"atime");
+ offset = dissect_timeval (pd,offset,fd,sattr_tree,"mtime");
+
+ /* now we know, that sattr is shorter */
+ if (sattr_item) {
+ proto_item_set_len(sattr_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
/* generic NFS2 call dissector */
int
dissect_nfs2_any_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
@@ -345,6 +377,39 @@ dissect_nfs2_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_t
return offset;
}
+
+/* RFC 1094, Page 6 */
+int
+dissect_nfs2_setattr_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+{
+ offset = dissect_fhandle(pd, offset, fd, tree, "file" );
+ offset = dissect_sattr (pd, offset, fd, tree, "attributes");
+
+ return offset;
+}
+
+
+/* RFC 1094, Page 6 */
+int
+dissect_nfs2_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+ guint32 status;
+
+ /* 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;
+}
+
+
/* more to come here */
@@ -353,7 +418,7 @@ dissect_nfs2_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_t
const vsff nfs2_proc[] = {
{ 0, "NULL", NULL, NULL },
{ 1, "GETATTR", dissect_nfs2_getattr_call, dissect_nfs2_getattr_reply },
- { 2, "SETATTR", dissect_nfs2_any_call, dissect_nfs2_any_reply },
+ { 2, "SETATTR", dissect_nfs2_any_call, dissect_nfs2_setattr_reply },
{ 3, "ROOT", NULL, NULL },
{ 4, "LOOKUP", dissect_nfs2_any_call, dissect_nfs2_any_reply },
{ 5, "READLINK", dissect_nfs2_any_call, dissect_nfs2_any_reply },
@@ -453,7 +518,7 @@ char* name)
if (tree) {
mode3_item = proto_tree_add_text(tree, offset, 4,
- "%s (mode3): 0%o", name, mode3);
+ "%s: 0%o", name, mode3);
if (mode3_item)
mode3_tree = proto_item_add_subtree(mode3_item, ETT_NFS_MODE3);
}
@@ -550,7 +615,7 @@ char* name, guint32* status)
if (tree) {
proto_tree_add_text(tree, offset, 4,
- "%s (nfsstat3): %s (%u)", name, nfsstat3_name, nfsstat3);
+ "%s: %s (%u)", name, nfsstat3_name, nfsstat3);
}
offset += 4;
@@ -588,7 +653,7 @@ char* name)
if (tree) {
proto_tree_add_text(tree, offset, 4,
- "%s (ftype3): %s (%u)", name, ftype3_name, ftype3);
+ "%s: %s (%u)", name, ftype3_name, ftype3);
}
offset += 4;
@@ -612,7 +677,7 @@ dissect_specdata3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree
if (tree) {
specdata3_item = proto_tree_add_text(tree, offset, 8,
- "%s (specdata3) : %u,%u", name, specdata1, specdata2);
+ "%s: %u,%u", name, specdata1, specdata2);
if (specdata3_item)
specdata3_tree = proto_item_add_subtree(specdata3_item,
ETT_NFS_SPECDATA3);
@@ -641,12 +706,12 @@ dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
proto_tree* ftree = NULL;
fh_len = EXTRACT_UINT(pd, offset+0);
- fh_len_full = roundup(fh_len);
+ fh_len_full = rpc_roundup(fh_len);
fh_fill = fh_len_full - fh_len;
if (tree) {
fitem = proto_tree_add_text(tree, offset, 4+fh_len_full,
- "%s (nfs_fh3)", name);
+ "%s", name);
if (fitem)
ftree = proto_item_add_subtree(fitem, ETT_NFS_FH3);
}
@@ -667,7 +732,7 @@ dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
/* RFC 1813, Page 21 */
int
-dissect_nfs3time(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name)
+dissect_nfstime3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name)
{
guint32 seconds;
guint32 nseconds;
@@ -681,7 +746,7 @@ dissect_nfs3time(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
if (tree) {
time_item = proto_tree_add_text(tree, offset, 8,
- "%s (nfs3time): %u.%09u", name, seconds, nseconds);
+ "%s: %u.%09u", name, seconds, nseconds);
if (time_item)
time_tree = proto_item_add_subtree(time_item, ETT_NFS_NFSTIME3);
}
@@ -707,7 +772,7 @@ dissect_fattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, c
if (tree) {
fattr3_item = proto_tree_add_text(tree, offset,
- END_OF_FRAME, "%s (fattr3)", name);
+ END_OF_FRAME, "%s", name);
if (fattr3_item)
fattr3_tree = proto_item_add_subtree(fattr3_item, ETT_NFS_FATTR3);
}
@@ -722,9 +787,9 @@ dissect_fattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, c
offset = dissect_specdata3(pd,offset,fd,fattr3_tree,"rdev");
offset = dissect_uint64 (pd,offset,fd,fattr3_tree,"fsid");
offset = dissect_fileid3 (pd,offset,fd,fattr3_tree,"fileid");
- offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"atime");
- offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"mtime");
- offset = dissect_nfs3time (pd,offset,fd,fattr3_tree,"ctime");
+ offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"atime");
+ offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"mtime");
+ offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"ctime");
/* now we know, that fattr3 is shorter */
if (fattr3_item) {
@@ -735,6 +800,476 @@ dissect_fattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, c
}
+const value_string value_follows[3] =
+ {
+ { 0, "no value" },
+ { 1, "value follows"},
+ { 0, NULL }
+ };
+
+
+/* RFC 1813, Page 23 */
+int
+dissect_post_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* post_op_attr_item = NULL;
+ proto_tree* post_op_attr_tree = NULL;
+ int old_offset = offset;
+ guint32 attributes_follow;
+
+ if (tree) {
+ post_op_attr_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (post_op_attr_item)
+ post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, ETT_NFS_POST_OP_ATTR);
+ }
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ attributes_follow = EXTRACT_UINT(pd, offset+0);
+ proto_tree_add_text(post_op_attr_tree, offset, 4,
+ "attributes_follow: %s (%u)",
+ val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
+ offset += 4;
+ switch (attributes_follow) {
+ case TRUE:
+ offset = dissect_fattr3(pd, offset, fd, post_op_attr_tree,
+ "attributes");
+ break;
+ case FALSE:
+ /* void */
+ break;
+ }
+
+ /* now we know, that post_op_attr_tree is shorter */
+ if (post_op_attr_item) {
+ proto_item_set_len(post_op_attr_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 24 */
+int
+dissect_wcc_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* wcc_attr_item = NULL;
+ proto_tree* wcc_attr_tree = NULL;
+ int old_offset = offset;
+
+ if (tree) {
+ wcc_attr_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (wcc_attr_item)
+ wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, ETT_NFS_WCC_ATTR);
+ }
+
+ offset = dissect_size3 (pd, offset, fd, wcc_attr_tree, "size" );
+ offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "mtime");
+ offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "ctime");
+
+ /* now we know, that wcc_attr_tree is shorter */
+ if (wcc_attr_item) {
+ proto_item_set_len(wcc_attr_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 24 */
+int
+dissect_pre_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* pre_op_attr_item = NULL;
+ proto_tree* pre_op_attr_tree = NULL;
+ int old_offset = offset;
+ guint32 attributes_follow;
+
+ if (tree) {
+ pre_op_attr_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (pre_op_attr_item)
+ pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, ETT_NFS_PRE_OP_ATTR);
+ }
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ attributes_follow = EXTRACT_UINT(pd, offset+0);
+ proto_tree_add_text(pre_op_attr_tree, offset, 4,
+ "attributes_follow: %s (%u)",
+ val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
+ offset += 4;
+ switch (attributes_follow) {
+ case TRUE:
+ offset = dissect_wcc_attr(pd, offset, fd, pre_op_attr_tree,
+ "attributes");
+ break;
+ case FALSE:
+ /* void */
+ break;
+ }
+
+ /* now we know, that pre_op_attr_tree is shorter */
+ if (pre_op_attr_item) {
+ proto_item_set_len(pre_op_attr_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 24 */
+int
+dissect_wcc_data(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* wcc_data_item = NULL;
+ proto_tree* wcc_data_tree = NULL;
+ int old_offset = offset;
+
+ if (tree) {
+ wcc_data_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (wcc_data_item)
+ wcc_data_tree = proto_item_add_subtree(wcc_data_item, ETT_NFS_WCC_DATA);
+ }
+
+ offset = dissect_pre_op_attr (pd, offset, fd, wcc_data_tree, "before");
+ offset = dissect_post_op_attr(pd, offset, fd, wcc_data_tree, "after" );
+
+ /* now we know, that wcc_data is shorter */
+ if (wcc_data_item) {
+ proto_item_set_len(wcc_data_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 25 */
+int
+dissect_set_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_mode3_item = NULL;
+ proto_tree* set_mode3_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,value_follows,"Unknown");
+
+ if (tree) {
+ set_mode3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s", name, set_it_name);
+ if (set_mode3_item)
+ set_mode3_tree = proto_item_add_subtree(set_mode3_item, ETT_NFS_SET_MODE3);
+ }
+
+ if (set_mode3_tree)
+ proto_tree_add_text(set_mode3_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case 1:
+ offset = dissect_mode3(pd, offset, fd, set_mode3_tree,
+ "mode");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_mode3 is shorter */
+ if (set_mode3_item) {
+ proto_item_set_len(set_mode3_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_set_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_uid3_item = NULL;
+ proto_tree* set_uid3_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,value_follows,"Unknown");
+
+ if (tree) {
+ set_uid3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s", name, set_it_name);
+ if (set_uid3_item)
+ set_uid3_tree = proto_item_add_subtree(set_uid3_item, ETT_NFS_SET_UID3);
+ }
+
+ if (set_uid3_tree)
+ proto_tree_add_text(set_uid3_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case 1:
+ offset = dissect_uid3(pd, offset, fd, set_uid3_tree,
+ "uid");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_uid3 is shorter */
+ if (set_uid3_item) {
+ proto_item_set_len(set_uid3_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_set_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_gid3_item = NULL;
+ proto_tree* set_gid3_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,value_follows,"Unknown");
+
+ if (tree) {
+ set_gid3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s", name, set_it_name);
+ if (set_gid3_item)
+ set_gid3_tree = proto_item_add_subtree(set_gid3_item, ETT_NFS_SET_GID3);
+ }
+
+ if (set_gid3_tree)
+ proto_tree_add_text(set_gid3_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case 1:
+ offset = dissect_gid3(pd, offset, fd, set_gid3_tree,
+ "gid");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_gid3 is shorter */
+ if (set_gid3_item) {
+ proto_item_set_len(set_gid3_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_set_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_size3_item = NULL;
+ proto_tree* set_size3_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,value_follows,"Unknown");
+
+ if (tree) {
+ set_size3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s", name, set_it_name);
+ if (set_size3_item)
+ set_size3_tree = proto_item_add_subtree(set_size3_item, ETT_NFS_SET_SIZE3);
+ }
+
+ if (set_size3_tree)
+ proto_tree_add_text(set_size3_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case 1:
+ offset = dissect_size3(pd, offset, fd, set_size3_tree,
+ "size");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_size3 is shorter */
+ if (set_size3_item) {
+ proto_item_set_len(set_size3_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 25 */
+#define DONT_CHANGE 0
+#define SET_TO_SERVER_TIME 1
+#define SET_TO_CLIENT_TIME 2
+
+const value_string time_how[] =
+ {
+ { DONT_CHANGE, "don't change" },
+ { SET_TO_SERVER_TIME, "set to server time" },
+ { SET_TO_CLIENT_TIME, "set to client time" },
+ { 0, NULL }
+ };
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_set_atime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_atime_item = NULL;
+ proto_tree* set_atime_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,time_how,"Unknown");
+
+ if (tree) {
+ set_atime_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s",
+ name, set_it_name, set_it);
+ if (set_atime_item)
+ set_atime_tree = proto_item_add_subtree(set_atime_item, ETT_NFS_SET_ATIME);
+ }
+
+ if (set_atime_tree)
+ proto_tree_add_text(set_atime_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (set_atime_item)
+ offset = dissect_nfstime3(pd, offset, fd, set_atime_tree,
+ "atime");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_atime is shorter */
+ if (set_atime_item) {
+ proto_item_set_len(set_atime_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_set_mtime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* set_mtime_item = NULL;
+ proto_tree* set_mtime_tree = NULL;
+ int old_offset = offset;
+ guint32 set_it;
+ char* set_it_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ set_it = EXTRACT_UINT(pd, offset+0);
+ set_it_name = val_to_str(set_it,time_how,"Unknown");
+
+ if (tree) {
+ set_mtime_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s",
+ name, set_it_name, set_it);
+ if (set_mtime_item)
+ set_mtime_tree = proto_item_add_subtree(set_mtime_item, ETT_NFS_SET_MTIME);
+ }
+
+ if (set_mtime_tree)
+ proto_tree_add_text(set_mtime_tree, offset, 4,
+ "set_it: %s (%u)", set_it_name, set_it);
+
+ offset += 4;
+
+ switch (set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (set_mtime_item)
+ offset = dissect_nfstime3(pd, offset, fd, set_mtime_tree,
+ "atime");
+ break;
+ default:
+ /* void */
+ break;
+ }
+
+ /* now we know, that set_mtime is shorter */
+ if (set_mtime_item) {
+ proto_item_set_len(set_mtime_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 26 */
+int
+dissect_sattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
+{
+ proto_item* sattr3_item = NULL;
+ proto_tree* sattr3_tree = NULL;
+ int old_offset = offset;
+
+ if (tree) {
+ sattr3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s", name);
+ if (sattr3_item)
+ sattr3_tree = proto_item_add_subtree(sattr3_item, ETT_NFS_SATTR3);
+ }
+
+ offset = dissect_set_mode3(pd, offset, fd, sattr3_tree, "mode");
+ offset = dissect_set_uid3 (pd, offset, fd, sattr3_tree, "uid");
+ offset = dissect_set_gid3 (pd, offset, fd, sattr3_tree, "gid");
+ offset = dissect_set_size3(pd, offset, fd, sattr3_tree, "size");
+ offset = dissect_set_atime(pd, offset, fd, sattr3_tree, "atime");
+ offset = dissect_set_mtime(pd, offset, fd, sattr3_tree, "mtime");
+
+ /* now we know, that sattr3 is shorter */
+ if (sattr3_item) {
+ proto_item_set_len(sattr3_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)
@@ -786,12 +1321,89 @@ dissect_nfs3_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_t
}
+/* RFC 1813, Page 33 */
+int
+dissect_sattrguard3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, char *name)
+{
+ proto_item* sattrguard3_item = NULL;
+ proto_tree* sattrguard3_tree = NULL;
+ int old_offset = offset;
+ guint32 check;
+ char* check_name;
+
+ if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
+ check = EXTRACT_UINT(pd, offset+0);
+ check_name = val_to_str(check,value_follows,"Unknown");
+
+ if (tree) {
+ sattrguard3_item = proto_tree_add_text(tree, offset,
+ END_OF_FRAME, "%s: %s", name, check_name);
+ if (sattrguard3_item)
+ sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, ETT_NFS_SATTRGUARD3);
+ }
+
+ if (sattrguard3_tree)
+ proto_tree_add_text(sattrguard3_tree, offset, 4,
+ "check: %s (%u)", check_name, check);
+
+ offset += 4;
+
+ switch (check) {
+ case TRUE:
+ offset = dissect_nfstime3(pd, offset, fd, sattrguard3_tree,
+ "obj_ctime");
+ break;
+ case FALSE:
+ /* void */
+ break;
+ }
+
+ /* now we know, that sattrguard3 is shorter */
+ if (sattrguard3_item) {
+ proto_item_set_len(sattrguard3_item, offset - old_offset);
+ }
+
+ return offset;
+}
+
+
+/* RFC 1813, Page 33 */
+int
+dissect_nfs3_setattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+{
+ offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object");
+ offset = dissect_sattr3 (pd, offset, fd, tree, "new_attributes");
+ offset = dissect_sattrguard3(pd, offset, fd, tree, "guard");
+ return offset;
+}
+
+
+/* RFC 1813, Page 33 */
+int
+dissect_nfs3_setattr_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_wcc_data(pd, offset, fd, tree, "obj_wcc");
+ break;
+ default:
+ offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc");
+ 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_any_call, dissect_nfs3_any_reply },
+ { 2, "SETATTR", dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply },
{ 3, "LOOKUP", dissect_nfs3_any_call, dissect_nfs3_any_reply },
{ 4, "ACCESS", dissect_nfs3_any_call, dissect_nfs3_any_reply },
{ 5, "READLINK", dissect_nfs3_any_call, dissect_nfs3_any_reply },