2 * Routines for nfs dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
5 * $Id: packet-nfs.c,v 1.37 2000/08/27 02:03:31 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-smb.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
38 #include "packet-rpc.h"
39 #include "packet-nfs.h"
42 static int proto_nfs = -1;
44 static int hf_nfs_fh_fsid_major = -1;
45 static int hf_nfs_fh_fsid_minor = -1;
46 static int hf_nfs_fh_xfsid_major = -1;
47 static int hf_nfs_fh_xfsid_minor = -1;
48 static int hf_nfs_fh_fstype = -1;
49 static int hf_nfs_fh_fn = -1;
50 static int hf_nfs_fh_fn_len = -1;
51 static int hf_nfs_fh_fn_inode = -1;
52 static int hf_nfs_fh_fn_generation = -1;
53 static int hf_nfs_fh_xfn = -1;
54 static int hf_nfs_fh_xfn_len = -1;
55 static int hf_nfs_fh_xfn_inode = -1;
56 static int hf_nfs_fh_xfn_generation = -1;
57 static int hf_nfs_fh_dentry = -1;
58 static int hf_nfs_fh_dev = -1;
59 static int hf_nfs_fh_xdev = -1;
60 static int hf_nfs_fh_dirinode = -1;
61 static int hf_nfs_fh_pinode = -1;
62 static int hf_nfs_fh_hp_len = -1;
63 static int hf_nfs_stat = -1;
64 static int hf_nfs_name = -1;
65 static int hf_nfs_readlink_data = -1;
66 static int hf_nfs_read_offset = -1;
67 static int hf_nfs_read_count = -1;
68 static int hf_nfs_read_totalcount = -1;
69 static int hf_nfs_data = -1;
70 static int hf_nfs_write_beginoffset = -1;
71 static int hf_nfs_write_offset = -1;
72 static int hf_nfs_write_totalcount = -1;
73 static int hf_nfs_symlink_to = -1;
74 static int hf_nfs_readdir_cookie = -1;
75 static int hf_nfs_readdir_count = -1;
76 static int hf_nfs_readdir_entry = -1;
77 static int hf_nfs_readdir_entry_fileid = -1;
78 static int hf_nfs_readdir_entry_name = -1;
79 static int hf_nfs_readdirplus_entry_name = -1;
80 static int hf_nfs_readdir_entry_cookie = -1;
81 static int hf_nfs_readdir_eof = -1;
82 static int hf_nfs_statfs_tsize = -1;
83 static int hf_nfs_statfs_bsize = -1;
84 static int hf_nfs_statfs_blocks = -1;
85 static int hf_nfs_statfs_bfree = -1;
86 static int hf_nfs_statfs_bavail = -1;
87 static int hf_nfs_ftype3 = -1;
88 static int hf_nfs_nfsstat3 = -1;
89 static int hf_nfs_read_eof = -1;
90 static int hf_nfs_write_stable = -1;
91 static int hf_nfs_write_committed = -1;
92 static int hf_nfs_createmode3 = -1;
93 static int hf_nfs_fsstat_invarsec = -1;
94 static int hf_nfs_fsinfo_rtmax = -1;
95 static int hf_nfs_fsinfo_rtpref = -1;
96 static int hf_nfs_fsinfo_rtmult = -1;
97 static int hf_nfs_fsinfo_wtmax = -1;
98 static int hf_nfs_fsinfo_wtpref = -1;
99 static int hf_nfs_fsinfo_wtmult = -1;
100 static int hf_nfs_fsinfo_dtpref = -1;
101 static int hf_nfs_fsinfo_properties = -1;
102 static int hf_nfs_pathconf_linkmax = -1;
103 static int hf_nfs_pathconf_name_max = -1;
104 static int hf_nfs_pathconf_no_trunc = -1;
105 static int hf_nfs_pathconf_chown_restricted = -1;
106 static int hf_nfs_pathconf_case_insensitive = -1;
107 static int hf_nfs_pathconf_case_preserving = -1;
110 static gint ett_nfs = -1;
111 static gint ett_nfs_fh_fsid = -1;
112 static gint ett_nfs_fh_xfsid = -1;
113 static gint ett_nfs_fh_fn = -1;
114 static gint ett_nfs_fh_xfn = -1;
115 static gint ett_nfs_fh_hp = -1;
116 static gint ett_nfs_fhandle = -1;
117 static gint ett_nfs_timeval = -1;
118 static gint ett_nfs_mode = -1;
119 static gint ett_nfs_fattr = -1;
120 static gint ett_nfs_sattr = -1;
121 static gint ett_nfs_diropargs = -1;
122 static gint ett_nfs_readdir_entry = -1;
123 static gint ett_nfs_mode3 = -1;
124 static gint ett_nfs_specdata3 = -1;
125 static gint ett_nfs_fh3 = -1;
126 static gint ett_nfs_nfstime3 = -1;
127 static gint ett_nfs_fattr3 = -1;
128 static gint ett_nfs_post_op_fh3 = -1;
129 static gint ett_nfs_sattr3 = -1;
130 static gint ett_nfs_diropargs3 = -1;
131 static gint ett_nfs_sattrguard3 = -1;
132 static gint ett_nfs_set_mode3 = -1;
133 static gint ett_nfs_set_uid3 = -1;
134 static gint ett_nfs_set_gid3 = -1;
135 static gint ett_nfs_set_size3 = -1;
136 static gint ett_nfs_set_atime = -1;
137 static gint ett_nfs_set_mtime = -1;
138 static gint ett_nfs_pre_op_attr = -1;
139 static gint ett_nfs_post_op_attr = -1;
140 static gint ett_nfs_wcc_attr = -1;
141 static gint ett_nfs_wcc_data = -1;
142 static gint ett_nfs_access = -1;
143 static gint ett_nfs_fsinfo_properties = -1;
146 /* file handle dissection */
149 const value_string names_fhtype[] =
151 #define FHT_UNKNOWN 0
152 { FHT_UNKNOWN, "unknown" },
154 { FHT_SVR4, "System V R4" },
155 #define FHT_LINUX_KNFSD_LE 2
156 { FHT_LINUX_KNFSD_LE, "Linux knfsd (little-endian)" },
157 #define FHT_LINUX_NFSD_LE 3
158 { FHT_LINUX_NFSD_LE, "Linux user-land nfsd (little-endian)" },
163 /* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45) */
166 dissect_fhandle_data_SVR4(tvbuff_t* tvb, proto_tree *tree, int fhlen)
180 temp = tvb_get_ntohl(tvb, fsid_O);
181 fsid_major = ( temp>>18 ) & 0x3fff; /* 14 bits */
182 fsid_minor = ( temp ) & 0x3ffff; /* 18 bits */
184 proto_item* fsid_item = NULL;
185 proto_tree* fsid_tree = NULL;
187 fsid_item = proto_tree_add_text(tree, tvb,
189 "file system ID: %d,%d", fsid_major, fsid_minor);
191 fsid_tree = proto_item_add_subtree(fsid_item,
193 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major,
194 tvb, fsid_O, 2, fsid_major);
195 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor,
196 tvb, fsid_O+1, 3, fsid_minor);
199 nof = fsid_O + fsid_L;
202 /* file system type */
210 fstype = tvb_get_ntohl(tvb, fstype_O);
212 proto_tree_add_uint(tree, hf_nfs_fh_fstype, tvb,
213 fstype_O, fstype_L, fstype);
215 nof = fstype_O + fstype_L;
225 guint32 fn_data_inode_O;
226 guint32 fn_data_inode_L;
228 guint32 fn_data_gen_O;
229 guint32 fn_data_gen_L;
236 fn_len = tvb_get_ntohs(tvb, fn_len_O);
237 fn_data_O = fn_O + fn_len_L;
238 fn_data_inode_O = fn_data_O + 2;
240 inode = tvb_get_ntohl(tvb, fn_data_inode_O);
241 fn_data_gen_O = fn_data_inode_O + fn_data_inode_L;
243 gen = tvb_get_ntohl(tvb, fn_data_gen_O);
244 fn_L = fn_len_L + fn_len;
246 proto_item* fn_item = NULL;
247 proto_tree* fn_tree = NULL;
249 fn_item = proto_tree_add_uint(tree, hf_nfs_fh_fn, tvb,
252 fn_tree = proto_item_add_subtree(fn_item,
254 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_len,
255 tvb, fn_len_O, fn_len_L, fn_len);
256 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_inode,
257 tvb, fn_data_inode_O, fn_data_inode_L, inode);
258 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_generation,
259 tvb, fn_data_gen_O, fn_data_gen_L, gen);
262 nof = fn_O + fn_len_L + fn_len;
265 /* exported file number */
272 guint32 xfn_data_inode_O;
273 guint32 xfn_data_inode_L;
275 guint32 xfn_data_gen_O;
276 guint32 xfn_data_gen_L;
283 xfn_len = tvb_get_ntohs(tvb, xfn_len_O);
284 xfn_data_O = xfn_O + xfn_len_L;
285 xfn_data_inode_O = xfn_data_O + 2;
286 xfn_data_inode_L = 4;
287 xinode = tvb_get_ntohl(tvb, xfn_data_inode_O);
288 xfn_data_gen_O = xfn_data_inode_O + xfn_data_inode_L;
290 xgen = tvb_get_ntohl(tvb, xfn_data_gen_O);
291 xfn_L = xfn_len_L + xfn_len;
293 proto_item* xfn_item = NULL;
294 proto_tree* xfn_tree = NULL;
296 xfn_item = proto_tree_add_uint(tree, hf_nfs_fh_xfn, tvb,
297 xfn_O, xfn_L, xinode);
299 xfn_tree = proto_item_add_subtree(xfn_item,
301 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_len,
302 tvb, xfn_len_O, xfn_len_L, xfn_len);
303 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_inode,
304 tvb, xfn_data_inode_O, xfn_data_inode_L, xinode);
305 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_generation,
306 tvb, xfn_data_gen_O, xfn_data_gen_L, xgen);
313 /* Checked with RedHat Linux 6.2 (kernel 2.2.14 knfsd) */
316 dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, proto_tree *tree, int fhlen)
329 dentry = tvb_get_letohl(tvb, 0);
330 inode = tvb_get_letohl(tvb, 4);
331 dirinode = tvb_get_letohl(tvb, 8);
332 temp = tvb_get_letohs (tvb,12);
333 fsid_major = (temp >> 8) & 0xff;
334 fsid_minor = (temp ) & 0xff;
335 temp = tvb_get_letohs(tvb,16);
336 xfsid_major = (temp >> 8) & 0xff;
337 xfsid_minor = (temp ) & 0xff;
338 xinode = tvb_get_letohl(tvb,20);
339 gen = tvb_get_letohl(tvb,24);
342 proto_tree_add_uint(tree, hf_nfs_fh_dentry,
344 proto_tree_add_uint(tree, hf_nfs_fh_fn_inode,
346 proto_tree_add_uint(tree, hf_nfs_fh_dirinode,
347 tvb, 8, 4, dirinode);
349 /* file system id (device) */
351 proto_item* fsid_item = NULL;
352 proto_tree* fsid_tree = NULL;
354 fsid_item = proto_tree_add_text(tree, tvb,
356 "file system ID: %d,%d", fsid_major, fsid_minor);
358 fsid_tree = proto_item_add_subtree(fsid_item,
360 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major,
361 tvb, 13, 1, fsid_major);
362 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor,
363 tvb, 12, 1, fsid_minor);
367 /* exported file system id (device) */
369 proto_item* xfsid_item = NULL;
370 proto_tree* xfsid_tree = NULL;
372 xfsid_item = proto_tree_add_text(tree, tvb,
374 "exported file system ID: %d,%d", xfsid_major, xfsid_minor);
376 xfsid_tree = proto_item_add_subtree(xfsid_item,
378 proto_tree_add_uint(xfsid_tree, hf_nfs_fh_xfsid_major,
379 tvb, 17, 1, xfsid_major);
380 proto_tree_add_uint(xfsid_tree, hf_nfs_fh_xfsid_minor,
381 tvb, 16, 1, xfsid_minor);
385 proto_tree_add_uint(tree, hf_nfs_fh_xfn_inode,
387 proto_tree_add_uint(tree, hf_nfs_fh_fn_generation,
393 /* Checked with RedHat Linux 5.2 (nfs-server 2.2beta47 user-land nfsd) */
396 dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, proto_tree *tree, int fhlen)
401 pinode = tvb_get_letohl(tvb, 0);
403 proto_tree_add_uint(tree, hf_nfs_fh_pinode,
412 hashlen = tvb_get_guint8(tvb, 4);
414 proto_item* hash_item = NULL;
415 proto_tree* hash_tree = NULL;
417 hash_item = proto_tree_add_text(tree, tvb, 4, hashlen + 1,
419 bytes_to_str(tvb_get_ptr(tvb,5,hashlen),hashlen));
421 hash_tree = proto_item_add_subtree(hash_item,
424 proto_tree_add_uint(hash_tree,
425 hf_nfs_fh_hp_len, tvb, 4, 1, hashlen);
426 proto_tree_add_text(hash_tree, tvb, 5, hashlen,
428 bytes_to_str(tvb_get_ptr(tvb,5,hashlen),hashlen));
437 dissect_fhandle_data_unknown(tvbuff_t *tvb, proto_tree *tree, int fhlen)
449 while (bytes_left != 0) {
451 if (sublen > bytes_left)
453 proto_tree_add_text(tree, tvb, offset, sublen,
455 first_line ? "data: " :
457 bytes_to_str(tvb_get_ptr(tvb,offset,sublen),sublen));
458 bytes_left -= sublen;
466 dissect_fhandle_data(const u_char *pd, int offset, frame_data* fd, proto_tree *tree, int fhlen)
468 tvbuff_t *tvb = tvb_create_from_top(offset);
469 int fhtype = FHT_UNKNOWN;
471 /* filehandle too long */
472 if (fhlen>64) goto type_ready;
473 /* Not all bytes there. Any attempt to deduce the type would be
475 if (!tvb_bytes_exist(tvb,0,fhlen)) goto type_ready;
477 /* calculate (heuristically) fhtype */
482 if (tvb_get_ntohs(tvb,4) == 0) {
483 len1= tvb_get_ntohs(tvb,8);
484 if (tvb_bytes_exist(tvb,10+len1,2)) {
485 len2 = tvb_get_ntohs(tvb,10+len1);
486 if (fhlen==12+len1+len2) {
492 len1 = tvb_get_guint8(tvb,4);
493 if (len1<28 && tvb_bytes_exist(tvb,5,len1)) {
495 for (len2=5+len1;len2<32;len2++) {
496 if (tvb_get_guint8(tvb,len2)) {
502 fhtype=FHT_LINUX_NFSD_LE;
506 if (tvb_get_ntohl(tvb,28) == 0) {
507 if (tvb_get_ntohs(tvb,14) == 0) {
508 if (tvb_get_ntohs(tvb,18) == 0) {
509 fhtype=FHT_LINUX_KNFSD_LE;
519 proto_tree_add_text(tree, tvb, 0, 0,
520 "type: %s", val_to_str(fhtype, names_fhtype, "Unknown"));
524 dissect_fhandle_data_SVR4 (tvb, tree, fhlen);
526 case FHT_LINUX_KNFSD_LE:
527 dissect_fhandle_data_LINUX_KNFSD_LE(tvb, tree, fhlen);
529 case FHT_LINUX_NFSD_LE:
530 dissect_fhandle_data_LINUX_NFSD_LE (tvb, tree, fhlen);
534 dissect_fhandle_data_unknown(tvb, tree, fhlen);
540 /***************************/
541 /* NFS Version 2, RFC 1094 */
542 /***************************/
545 /* base 32 bit type for NFS v2 */
547 dissect_unsigned_int(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
550 offset = dissect_rpc_uint32(pd,offset,fd,tree,name);
555 /* RFC 1094, Page 12..14 */
556 const value_string names_nfs_stat[] =
565 { 18, "ERR_XDEV" }, /* not in spec, but can happen */
567 { 20, "ERR_NOTDIR" },
569 { 22, "ERR_INVAL" }, /* not in spec, but I think it can happen */
570 { 26, "ERR_TXTBSY" }, /* not in spec, but I think it can happen */
574 { 31, "ERR_MLINK" }, /* not in spec, but can happen */
575 { 45, "ERR_OPNOTSUPP" }, /* not in spec, but I think it can happen */
576 { 63, "ERR_NAMETOOLONG" },
577 { 66, "ERR_NOTEMPTY" },
580 { 99, "ERR_WFLUSH" },
585 /* RFC 1094, Page 12..14 */
587 dissect_stat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
592 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
593 stat = EXTRACT_UINT(pd, offset+0);
596 /* this gives the right NFSv2 number<->message relation */
597 /* and makes it searchable via "nfs.status" */
598 proto_tree_add_uint_format(tree, hf_nfs_nfsstat3, NullTVB,
599 offset+0, 4, stat, "Status: %s (%u)",
600 val_to_str(stat,names_nfs_stat,"%u"), stat);
609 /* RFC 1094, Page 12..14 */
611 dissect_nfs2_stat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
615 offset = dissect_stat(pd, offset, fd, tree, &status);
621 /* RFC 1094, Page 15 */
623 dissect_ftype(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
627 char* ftype_name = NULL;
629 const value_string nfs2_ftype[] =
632 { 1, "Regular File" },
634 { 3, "Block Special Device" },
635 { 4, "Character Special Device" },
636 { 5, "Symbolic Link" },
640 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
641 ftype = EXTRACT_UINT(pd, offset+0);
642 ftype_name = val_to_str(ftype, nfs2_ftype, "%u");
645 proto_tree_add_text(tree, NullTVB, offset, 4,
646 "%s: %s (%u)", name, ftype_name, ftype);
654 /* RFC 1094, Page 15 */
656 dissect_fhandle(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
659 proto_tree* ftree = NULL;
662 fitem = proto_tree_add_text(tree, NullTVB, offset, FHSIZE,
665 ftree = proto_item_add_subtree(fitem, ett_nfs_fhandle);
669 dissect_fhandle_data(pd, offset, fd, ftree, FHSIZE);
675 /* RFC 1094, Page 15 */
677 dissect_nfs2_fhandle_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
679 offset = dissect_fhandle(pd, offset, fd, tree, "object");
685 /* RFC 1094, Page 15 */
687 dissect_timeval(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
692 proto_item* time_item;
693 proto_tree* time_tree = NULL;
695 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
696 seconds = EXTRACT_UINT(pd, offset+0);
697 mseconds = EXTRACT_UINT(pd, offset+4);
700 time_item = proto_tree_add_text(tree, NullTVB, offset, 8,
701 "%s: %u.%06u", name, seconds, mseconds);
703 time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval);
707 proto_tree_add_text(time_tree, NullTVB,offset+0,4,
708 "seconds: %u", seconds);
709 proto_tree_add_text(time_tree, NullTVB,offset+4,4,
710 "micro seconds: %u", mseconds);
717 /* RFC 1094, Page 16 */
718 const value_string nfs2_mode_names[] = {
719 { 0040000, "Directory" },
720 { 0020000, "Character Special Device" },
721 { 0060000, "Block Special Device" },
722 { 0100000, "Regular File" },
723 { 0120000, "Symbolic Link" },
724 { 0140000, "Named Socket" },
729 dissect_mode(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
733 proto_item* mode_item = NULL;
734 proto_tree* mode_tree = NULL;
736 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
737 mode = EXTRACT_UINT(pd, offset+0);
740 mode_item = proto_tree_add_text(tree, NullTVB, offset, 4,
741 "%s: 0%o", name, mode);
743 mode_tree = proto_item_add_subtree(mode_item, ett_nfs_mode);
747 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
748 decode_enumerated_bitfield(mode, 0160000, 16,
749 nfs2_mode_names, "%s"));
750 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
751 decode_boolean_bitfield(mode, 04000, 16, "Set user id on exec", "not SUID"));
752 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
753 decode_boolean_bitfield(mode, 02000, 16, "Set group id on exec", "not SGID"));
754 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
755 decode_boolean_bitfield(mode, 01000, 16, "Save swapped text even after use", "not save swapped text"));
756 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
757 decode_boolean_bitfield(mode, 0400, 16, "Read permission for owner", "no Read permission for owner"));
758 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
759 decode_boolean_bitfield(mode, 0200, 16, "Write permission for owner", "no Write permission for owner"));
760 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
761 decode_boolean_bitfield(mode, 0100, 16, "Execute permission for owner", "no Execute permission for owner"));
762 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
763 decode_boolean_bitfield(mode, 040, 16, "Read permission for group", "no Read permission for group"));
764 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
765 decode_boolean_bitfield(mode, 020, 16, "Write permission for group", "no Write permission for group"));
766 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
767 decode_boolean_bitfield(mode, 010, 16, "Execute permission for group", "no Execute permission for group"));
768 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
769 decode_boolean_bitfield(mode, 04, 16, "Read permission for others", "no Read permission for others"));
770 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
771 decode_boolean_bitfield(mode, 02, 16, "Write permission for others", "no Write permission for others"));
772 proto_tree_add_text(mode_tree, NullTVB, offset, 4, "%s",
773 decode_boolean_bitfield(mode, 01, 16, "Execute permission for others", "no Execute permission for others"));
781 /* RFC 1094, Page 15 */
783 dissect_fattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
785 proto_item* fattr_item = NULL;
786 proto_tree* fattr_tree = NULL;
787 int old_offset = offset;
790 fattr_item = proto_tree_add_text(tree, NullTVB, offset,
791 END_OF_FRAME, "%s", name);
793 fattr_tree = proto_item_add_subtree(fattr_item, ett_nfs_fattr);
796 offset = dissect_ftype (pd,offset,fd,fattr_tree,"type");
797 offset = dissect_mode (pd,offset,fd,fattr_tree,"mode");
798 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"nlink");
799 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"uid");
800 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"gid");
801 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"size");
802 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"blocksize");
803 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"rdev");
804 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"blocks");
805 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"fsid");
806 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"fileid");
807 offset = dissect_timeval (pd,offset,fd,fattr_tree,"atime");
808 offset = dissect_timeval (pd,offset,fd,fattr_tree,"mtime");
809 offset = dissect_timeval (pd,offset,fd,fattr_tree,"ctime");
811 /* now we know, that fattr is shorter */
813 proto_item_set_len(fattr_item, offset - old_offset);
820 /* RFC 1094, Page 17 */
822 dissect_sattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
824 proto_item* sattr_item = NULL;
825 proto_tree* sattr_tree = NULL;
826 int old_offset = offset;
829 sattr_item = proto_tree_add_text(tree, NullTVB, offset,
830 END_OF_FRAME, "%s", name);
832 sattr_tree = proto_item_add_subtree(sattr_item, ett_nfs_sattr);
835 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
836 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
837 offset = dissect_mode (pd,offset,fd,sattr_tree,"mode");
839 proto_tree_add_text(sattr_tree, NullTVB, offset, 4, "mode: no value");
843 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
844 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
845 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"uid");
847 proto_tree_add_text(sattr_tree, NullTVB, offset, 4, "uid: no value");
851 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
852 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
853 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"gid");
855 proto_tree_add_text(sattr_tree, NullTVB, offset, 4, "gid: no value");
859 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
860 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
861 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"size");
863 proto_tree_add_text(sattr_tree, NullTVB, offset, 4, "size: no value");
867 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
868 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
869 offset = dissect_timeval (pd,offset,fd,sattr_tree,"atime");
871 proto_tree_add_text(sattr_tree, NullTVB, offset, 8, "atime: no value");
875 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
876 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
877 offset = dissect_timeval (pd,offset,fd,sattr_tree,"mtime");
879 proto_tree_add_text(sattr_tree, NullTVB, offset, 8, "mtime: no value");
883 /* now we know, that sattr is shorter */
885 proto_item_set_len(sattr_item, offset - old_offset);
892 /* RFC 1094, Page 17 */
894 dissect_filename(const u_char *pd, int offset, frame_data *fd,
895 proto_tree *tree, int hf, char **string_ret)
897 offset = dissect_rpc_string(pd,offset,fd,tree,hf,string_ret);
902 /* RFC 1094, Page 17 */
904 dissect_path(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
906 offset = dissect_rpc_string(pd,offset,fd,tree,hf,NULL);
911 /* RFC 1094, Page 17,18 */
913 dissect_attrstat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
916 offset = dissect_stat(pd, offset, fd, tree, &status);
919 offset = dissect_fattr(pd, offset, fd, tree, "attributes");
930 /* RFC 1094, Page 17,18 */
932 dissect_nfs2_attrstat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
934 offset = dissect_attrstat(pd, offset, fd, tree);
940 /* RFC 1094, Page 18 */
942 dissect_diropargs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
944 proto_item* diropargs_item = NULL;
945 proto_tree* diropargs_tree = NULL;
946 int old_offset = offset;
949 diropargs_item = proto_tree_add_text(tree, NullTVB, offset,
950 END_OF_FRAME, "%s", name);
952 diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs);
955 offset = dissect_fhandle (pd,offset,fd,diropargs_tree,"dir");
956 offset = dissect_filename(pd,offset,fd,diropargs_tree,hf_nfs_name,NULL);
958 /* now we know, that diropargs is shorter */
959 if (diropargs_item) {
960 proto_item_set_len(diropargs_item, offset - old_offset);
967 /* RFC 1094, Page 18 */
969 dissect_nfs2_diropargs_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
971 offset = dissect_diropargs(pd, offset, fd, tree, "where");
977 /* RFC 1094, Page 18 */
979 dissect_diropres(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
983 offset = dissect_stat(pd, offset, fd, tree, &status);
986 offset = dissect_fhandle(pd, offset, fd, tree, "file");
987 offset = dissect_fattr (pd, offset, fd, tree, "attributes");
998 /* nfsdata is simply a RPC string (length, data, fill bytes) */
1000 dissect_nfsdata(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1003 offset = dissect_rpc_data(pd,offset,fd,tree,hf);
1009 /* RFC 1094, Page 18 */
1011 dissect_nfs2_diropres_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1013 offset = dissect_diropres(pd, offset, fd, tree);
1019 /* RFC 1094, Page 6 */
1021 dissect_nfs2_setattr_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1023 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
1024 offset = dissect_sattr (pd, offset, fd, tree, "attributes");
1030 /* RFC 1094, Page 6 */
1032 dissect_nfs2_readlink_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1036 offset = dissect_stat(pd, offset, fd, tree, &status);
1039 offset = dissect_path(pd, offset, fd, tree, hf_nfs_readlink_data);
1050 /* RFC 1094, Page 7 */
1052 dissect_nfs2_read_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1054 guint32 offset_value;
1058 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
1059 if (!BYTES_ARE_IN_FRAME(offset,12)) return offset;
1060 offset_value = EXTRACT_UINT(pd, offset+0);
1061 count = EXTRACT_UINT(pd, offset+4);
1062 totalcount = EXTRACT_UINT(pd, offset+8);
1064 proto_tree_add_uint(tree, hf_nfs_read_offset, NullTVB,
1065 offset+0, 4, offset_value);
1066 proto_tree_add_uint(tree, hf_nfs_read_count, NullTVB,
1067 offset+4, 4, count);
1068 proto_tree_add_uint(tree, hf_nfs_read_totalcount, NullTVB,
1069 offset+8, 4, totalcount);
1077 /* RFC 1094, Page 7 */
1079 dissect_nfs2_read_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1083 offset = dissect_stat(pd, offset, fd, tree, &status);
1086 offset = dissect_fattr(pd, offset, fd, tree, "attributes");
1087 offset = dissect_nfsdata(pd, offset, fd, tree, hf_nfs_data);
1098 /* RFC 1094, Page 8 */
1100 dissect_nfs2_write_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1102 guint32 beginoffset;
1103 guint32 offset_value;
1106 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
1107 if (!BYTES_ARE_IN_FRAME(offset,12)) return offset;
1108 beginoffset = EXTRACT_UINT(pd, offset+0);
1109 offset_value = EXTRACT_UINT(pd, offset+4);
1110 totalcount = EXTRACT_UINT(pd, offset+8);
1112 proto_tree_add_uint(tree, hf_nfs_write_beginoffset, NullTVB,
1113 offset+0, 4, beginoffset);
1114 proto_tree_add_uint(tree, hf_nfs_write_offset, NullTVB,
1115 offset+4, 4, offset_value);
1116 proto_tree_add_uint(tree, hf_nfs_write_totalcount, NullTVB,
1117 offset+8, 4, totalcount);
1121 offset = dissect_nfsdata(pd, offset, fd, tree, hf_nfs_data);
1127 /* RFC 1094, Page 8 */
1129 dissect_nfs2_createargs_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1131 offset = dissect_diropargs(pd, offset, fd, tree, "where" );
1132 offset = dissect_sattr (pd, offset, fd, tree, "attributes");
1138 /* RFC 1094, Page 9 */
1140 dissect_nfs2_rename_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1142 offset = dissect_diropargs(pd, offset, fd, tree, "from");
1143 offset = dissect_diropargs(pd, offset, fd, tree, "to" );
1149 /* RFC 1094, Page 9 */
1151 dissect_nfs2_link_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1153 offset = dissect_fhandle (pd, offset, fd, tree, "from");
1154 offset = dissect_diropargs(pd, offset, fd, tree, "to" );
1160 /* RFC 1094, Page 10 */
1162 dissect_nfs2_symlink_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1164 offset = dissect_diropargs(pd, offset, fd, tree, "from" );
1165 offset = dissect_path (pd, offset, fd, tree, hf_nfs_symlink_to);
1166 offset = dissect_sattr (pd, offset, fd, tree, "attributes" );
1172 /* RFC 1094, Page 11 */
1174 dissect_nfs2_readdir_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1179 offset = dissect_fhandle (pd, offset, fd, tree, "dir");
1180 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1181 cookie = EXTRACT_UINT(pd, offset+ 0);
1182 count = EXTRACT_UINT(pd, offset+ 4);
1184 proto_tree_add_uint(tree, hf_nfs_readdir_cookie, NullTVB,
1185 offset+ 0, 4, cookie);
1186 proto_tree_add_uint(tree, hf_nfs_readdir_count, NullTVB,
1187 offset+ 4, 4, count);
1195 /* RFC 1094, Page 11 */
1197 dissect_readdir_entry(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1199 proto_item* entry_item = NULL;
1200 proto_tree* entry_tree = NULL;
1201 int old_offset = offset;
1207 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, NullTVB,
1208 offset+0, END_OF_FRAME, FALSE);
1210 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
1213 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
1215 proto_item_set_text(entry_item, "Entry: <TRUNCATED>");
1218 fileid = EXTRACT_UINT(pd, offset + 0);
1220 proto_tree_add_uint(entry_tree, hf_nfs_readdir_entry_fileid, NullTVB,
1221 offset+0, 4, fileid);
1224 offset = dissect_filename(pd, offset, fd, entry_tree,
1225 hf_nfs_readdir_entry_name, &name);
1227 proto_item_set_text(entry_item, "Entry: file ID %u, name %s",
1231 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
1232 cookie = EXTRACT_UINT(pd, offset + 0);
1234 proto_tree_add_uint(entry_tree, hf_nfs_readdir_entry_cookie, NullTVB,
1235 offset+0, 4, cookie);
1238 /* now we know, that a readdir entry is shorter */
1240 proto_item_set_len(entry_item, offset - old_offset);
1246 /* RFC 1094, Page 11 */
1248 dissect_nfs2_readdir_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1253 offset = dissect_stat(pd, offset, fd, tree, &status);
1256 offset = dissect_rpc_list(pd, offset, fd, tree,
1257 dissect_readdir_entry);
1258 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1259 eof_value = EXTRACT_UINT(pd, offset+0);
1261 proto_tree_add_uint(tree, hf_nfs_readdir_eof, NullTVB,
1262 offset+ 0, 4, eof_value);
1274 /* RFC 1094, Page 12 */
1276 dissect_nfs2_statfs_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1285 offset = dissect_stat(pd, offset, fd, tree, &status);
1288 if (!BYTES_ARE_IN_FRAME(offset,5 * 4)) return offset;
1289 tsize = EXTRACT_UINT(pd, offset+ 0);
1290 bsize = EXTRACT_UINT(pd, offset+ 4);
1291 blocks = EXTRACT_UINT(pd, offset+ 8);
1292 bfree = EXTRACT_UINT(pd, offset+12);
1293 bavail = EXTRACT_UINT(pd, offset+16);
1295 proto_tree_add_uint(tree, hf_nfs_statfs_tsize, NullTVB,
1296 offset+ 0, 4, tsize);
1297 proto_tree_add_uint(tree, hf_nfs_statfs_bsize, NullTVB,
1298 offset+ 4, 4, bsize);
1299 proto_tree_add_uint(tree, hf_nfs_statfs_blocks, NullTVB,
1300 offset+ 8, 4, blocks);
1301 proto_tree_add_uint(tree, hf_nfs_statfs_bfree, NullTVB,
1302 offset+12, 4, bfree);
1303 proto_tree_add_uint(tree, hf_nfs_statfs_bavail, NullTVB,
1304 offset+16, 4, bavail);
1317 /* proc number, "proc name", dissect_request, dissect_reply */
1318 /* NULL as function pointer means: take the generic one. */
1319 const vsff nfs2_proc[] = {
1320 { 0, "NULL", /* OK */
1322 { 1, "GETATTR", /* OK */
1323 dissect_nfs2_fhandle_call, dissect_nfs2_attrstat_reply },
1324 { 2, "SETATTR", /* OK */
1325 dissect_nfs2_setattr_call, dissect_nfs2_attrstat_reply },
1326 { 3, "ROOT", /* OK */
1328 { 4, "LOOKUP", /* OK */
1329 dissect_nfs2_diropargs_call, dissect_nfs2_diropres_reply },
1330 { 5, "READLINK", /* OK */
1331 dissect_nfs2_fhandle_call, dissect_nfs2_readlink_reply },
1332 { 6, "READ", /* OK */
1333 dissect_nfs2_read_call, dissect_nfs2_read_reply },
1334 { 7, "WRITECACHE", /* OK */
1336 { 8, "WRITE", /* OK */
1337 dissect_nfs2_write_call, dissect_nfs2_attrstat_reply },
1338 { 9, "CREATE", /* OK */
1339 dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply },
1340 { 10, "REMOVE", /* OK */
1341 dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply },
1342 { 11, "RENAME", /* OK */
1343 dissect_nfs2_rename_call, dissect_nfs2_stat_reply },
1344 { 12, "LINK", /* OK */
1345 dissect_nfs2_link_call, dissect_nfs2_stat_reply },
1346 { 13, "SYMLINK", /* OK */
1347 dissect_nfs2_symlink_call, dissect_nfs2_stat_reply },
1348 { 14, "MKDIR", /* OK */
1349 dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply },
1350 { 15, "RMDIR", /* OK */
1351 dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply },
1352 { 16, "READDIR", /* OK */
1353 dissect_nfs2_readdir_call, dissect_nfs2_readdir_reply },
1354 { 17, "STATFS", /* OK */
1355 dissect_nfs2_fhandle_call, dissect_nfs2_statfs_reply },
1356 { 0,NULL,NULL,NULL }
1358 /* end of NFS Version 2 */
1361 /***************************/
1362 /* NFS Version 3, RFC 1813 */
1363 /***************************/
1366 /* RFC 1813, Page 15 */
1368 dissect_uint64(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1371 offset = dissect_rpc_uint64(pd,offset,fd,tree,name);
1376 /* RFC 1813, Page 15 */
1378 dissect_uint32(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1381 offset = dissect_rpc_uint32(pd,offset,fd,tree,name);
1386 /* RFC 1813, Page 15 */
1388 dissect_filename3(const u_char *pd, int offset, frame_data *fd,
1389 proto_tree *tree, int hf, char **string_ret)
1391 offset = dissect_rpc_string(pd,offset,fd,tree,hf,string_ret);
1396 /* RFC 1813, Page 15 */
1398 dissect_nfspath3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
1400 offset = dissect_rpc_string(pd,offset,fd,tree,hf,NULL);
1405 /* RFC 1813, Page 15 */
1407 dissect_fileid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1410 offset = dissect_rpc_uint64(pd,offset,fd,tree,name);
1415 /* RFC 1813, Page 15 */
1417 dissect_cookie3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1420 offset = dissect_rpc_uint64(pd,offset,fd,tree,name);
1425 /* RFC 1813, Page 15 */
1427 dissect_cookieverf3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1429 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1430 proto_tree_add_text(tree, NullTVB, offset, NFS3_COOKIEVERFSIZE,
1431 "Verifier: Opaque Data");
1432 offset += NFS3_COOKIEVERFSIZE;
1437 /* RFC 1813, Page 16 */
1439 dissect_createverf3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1441 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1442 proto_tree_add_text(tree, NullTVB, offset, NFS3_CREATEVERFSIZE,
1443 "Verifier: Opaque Data");
1444 offset += NFS3_CREATEVERFSIZE;
1449 /* RFC 1813, Page 16 */
1451 dissect_writeverf3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1453 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1454 proto_tree_add_text(tree, NullTVB, offset, NFS3_WRITEVERFSIZE,
1455 "Verifier: Opaque Data");
1456 offset += NFS3_WRITEVERFSIZE;
1461 /* RFC 1813, Page 16 */
1463 dissect_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1466 offset = dissect_rpc_uint32(pd,offset,fd,tree,name);
1471 /* RFC 1813, Page 16 */
1473 dissect_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1476 offset = dissect_rpc_uint32(pd,offset,fd,tree,name);
1481 /* RFC 1813, Page 16 */
1483 dissect_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1486 offset = dissect_rpc_uint64(pd,offset,fd,tree,name);
1491 /* RFC 1813, Page 16 */
1493 dissect_offset3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1496 offset = dissect_rpc_uint64(pd,offset,fd,tree,name);
1501 /* RFC 1813, Page 16 */
1503 dissect_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1507 proto_item* mode3_item = NULL;
1508 proto_tree* mode3_tree = NULL;
1510 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1511 mode3 = EXTRACT_UINT(pd, offset+0);
1514 mode3_item = proto_tree_add_text(tree, NullTVB, offset, 4,
1515 "%s: 0%o", name, mode3);
1517 mode3_tree = proto_item_add_subtree(mode3_item, ett_nfs_mode3);
1520 /* RFC 1813, Page 23 */
1522 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1523 decode_boolean_bitfield(mode3, 0x800, 12, "Set user id on exec", "not SUID"));
1524 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1525 decode_boolean_bitfield(mode3, 0x400, 12, "Set group id on exec", "not SGID"));
1526 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1527 decode_boolean_bitfield(mode3, 0x200, 12, "Save swapped text even after use", "not save swapped text"));
1528 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1529 decode_boolean_bitfield(mode3, 0x100, 12, "Read permission for owner", "no Read permission for owner"));
1530 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1531 decode_boolean_bitfield(mode3, 0x80, 12, "Write permission for owner", "no Write permission for owner"));
1532 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1533 decode_boolean_bitfield(mode3, 0x40, 12, "Execute permission for owner", "no Execute permission for owner"));
1534 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1535 decode_boolean_bitfield(mode3, 0x20, 12, "Read permission for group", "no Read permission for group"));
1536 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1537 decode_boolean_bitfield(mode3, 0x10, 12, "Write permission for group", "no Write permission for group"));
1538 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1539 decode_boolean_bitfield(mode3, 0x8, 12, "Execute permission for group", "no Execute permission for group"));
1540 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1541 decode_boolean_bitfield(mode3, 0x4, 12, "Read permission for others", "no Read permission for others"));
1542 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1543 decode_boolean_bitfield(mode3, 0x2, 12, "Write permission for others", "no Write permission for others"));
1544 proto_tree_add_text(mode3_tree, NullTVB, offset, 4, "%s",
1545 decode_boolean_bitfield(mode3, 0x1, 12, "Execute permission for others", "no Execute permission for others"));
1553 /* RFC 1813, Page 16 */
1555 dissect_count3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1558 offset = dissect_rpc_uint32(pd,offset,fd,tree,name);
1563 /* RFC 1813, Page 16,17 */
1564 const value_string names_nfs_nfsstat3[] =
1571 { 13, "ERR_ACCES" },
1572 { 17, "ERR_EXIST" },
1574 { 19, "ERR_NODEV" },
1575 { 20, "ERR_NOTDIR" },
1576 { 21, "ERR_ISDIR" },
1577 { 22, "ERR_INVAL" },
1579 { 28, "ERR_NOSPC" },
1581 { 31, "ERR_MLINK" },
1582 { 63, "ERR_NAMETOOLONG" },
1583 { 66, "ERR_NOTEMPTY" },
1584 { 69, "ERR_DQUOT" },
1585 { 70, "ERR_STALE" },
1586 { 71, "ERR_REMOTE" },
1587 { 10001, "ERR_BADHANDLE" },
1588 { 10002, "ERR_NOT_SYNC" },
1589 { 10003, "ERR_BAD_COOKIE" },
1590 { 10004, "ERR_NOTSUPP" },
1591 { 10005, "ERR_TOOSMALL" },
1592 { 10006, "ERR_SERVERFAULT" },
1593 { 10007, "ERR_BADTYPE" },
1594 { 10008, "ERR_JUKEBOX" },
1599 /* RFC 1813, Page 16 */
1601 dissect_nfsstat3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,guint32 *status)
1605 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1606 nfsstat3 = EXTRACT_UINT(pd, offset+0);
1609 proto_tree_add_uint(tree, hf_nfs_nfsstat3, NullTVB,
1610 offset, 4, nfsstat3);
1619 const value_string names_nfs_ftype3[] =
1621 { NF3REG, "Regular File" },
1622 { NF3DIR, "Directory" },
1623 { NF3BLK, "Block Special Device" },
1624 { NF3CHR, "Character Special Device" },
1625 { NF3LNK, "Symbolic Link" },
1626 { NF3SOCK,"Socket" },
1627 { NF3FIFO,"Named Pipe" },
1632 /* RFC 1813, Page 20 */
1634 dissect_ftype3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1635 int hf, guint32* ftype3)
1639 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1640 type = EXTRACT_UINT(pd, offset+0);
1643 proto_tree_add_uint(tree, hf, NullTVB, offset, 4, type);
1652 /* RFC 1813, Page 20 */
1654 dissect_specdata3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1659 proto_item* specdata3_item;
1660 proto_tree* specdata3_tree = NULL;
1662 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1663 specdata1 = EXTRACT_UINT(pd, offset+0);
1664 specdata2 = EXTRACT_UINT(pd, offset+4);
1667 specdata3_item = proto_tree_add_text(tree, NullTVB, offset, 8,
1668 "%s: %u,%u", name, specdata1, specdata2);
1670 specdata3_tree = proto_item_add_subtree(specdata3_item,
1674 if (specdata3_tree) {
1675 proto_tree_add_text(specdata3_tree, NullTVB,offset+0,4,
1676 "specdata1: %u", specdata1);
1677 proto_tree_add_text(specdata3_tree, NullTVB,offset+4,4,
1678 "specdata2: %u", specdata2);
1686 /* RFC 1813, Page 21 */
1688 dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1694 proto_tree* ftree = NULL;
1696 fh3_len = EXTRACT_UINT(pd, offset+0);
1697 fh3_len_full = rpc_roundup(fh3_len);
1698 fh3_fill = fh3_len_full - fh3_len;
1701 fitem = proto_tree_add_text(tree, NullTVB, offset, 4+fh3_len_full,
1704 ftree = proto_item_add_subtree(fitem, ett_nfs_fh3);
1708 proto_tree_add_text(ftree, NullTVB,offset+0,4,
1709 "length: %u", fh3_len);
1710 dissect_fhandle_data(pd, offset+4, fd, ftree, fh3_len);
1712 offset += 4 + fh3_len_full;
1717 /* RFC 1813, Page 21 */
1719 dissect_nfstime3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name)
1724 proto_item* time_item;
1725 proto_tree* time_tree = NULL;
1727 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1728 seconds = EXTRACT_UINT(pd, offset+0);
1729 nseconds = EXTRACT_UINT(pd, offset+4);
1732 time_item = proto_tree_add_text(tree, NullTVB, offset, 8,
1733 "%s: %u.%09u", name, seconds, nseconds);
1735 time_tree = proto_item_add_subtree(time_item, ett_nfs_nfstime3);
1739 proto_tree_add_text(time_tree, NullTVB,offset+0,4,
1740 "seconds: %u", seconds);
1741 proto_tree_add_text(time_tree, NullTVB,offset+4,4,
1742 "nano seconds: %u", nseconds);
1749 /* RFC 1813, Page 22 */
1751 dissect_fattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1753 proto_item* fattr3_item = NULL;
1754 proto_tree* fattr3_tree = NULL;
1755 int old_offset = offset;
1759 fattr3_item = proto_tree_add_text(tree, NullTVB, offset,
1760 END_OF_FRAME, "%s", name);
1762 fattr3_tree = proto_item_add_subtree(fattr3_item, ett_nfs_fattr3);
1765 offset = dissect_ftype3 (pd,offset,fd,fattr3_tree,hf_nfs_ftype3,&type);
1766 offset = dissect_mode3 (pd,offset,fd,fattr3_tree,"mode");
1767 offset = dissect_uint32 (pd,offset,fd,fattr3_tree,"nlink");
1768 offset = dissect_uid3 (pd,offset,fd,fattr3_tree,"uid");
1769 offset = dissect_gid3 (pd,offset,fd,fattr3_tree,"gid");
1770 offset = dissect_size3 (pd,offset,fd,fattr3_tree,"size");
1771 offset = dissect_size3 (pd,offset,fd,fattr3_tree,"used");
1772 offset = dissect_specdata3(pd,offset,fd,fattr3_tree,"rdev");
1773 offset = dissect_uint64 (pd,offset,fd,fattr3_tree,"fsid");
1774 offset = dissect_fileid3 (pd,offset,fd,fattr3_tree,"fileid");
1775 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"atime");
1776 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"mtime");
1777 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"ctime");
1779 /* now we know, that fattr3 is shorter */
1781 proto_item_set_len(fattr3_item, offset - old_offset);
1788 const value_string value_follows[] =
1791 { 1, "value follows"},
1796 /* RFC 1813, Page 23 */
1798 dissect_post_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1800 proto_item* post_op_attr_item = NULL;
1801 proto_tree* post_op_attr_tree = NULL;
1802 int old_offset = offset;
1803 guint32 attributes_follow;
1806 post_op_attr_item = proto_tree_add_text(tree, NullTVB, offset,
1807 END_OF_FRAME, "%s", name);
1808 if (post_op_attr_item)
1809 post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, ett_nfs_post_op_attr);
1812 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1813 attributes_follow = EXTRACT_UINT(pd, offset+0);
1814 proto_tree_add_text(post_op_attr_tree, NullTVB, offset, 4,
1815 "attributes_follow: %s (%u)",
1816 val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
1818 switch (attributes_follow) {
1820 offset = dissect_fattr3(pd, offset, fd, post_op_attr_tree,
1828 /* now we know, that post_op_attr_tree is shorter */
1829 if (post_op_attr_item) {
1830 proto_item_set_len(post_op_attr_item, offset - old_offset);
1837 /* RFC 1813, Page 24 */
1839 dissect_wcc_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1841 proto_item* wcc_attr_item = NULL;
1842 proto_tree* wcc_attr_tree = NULL;
1843 int old_offset = offset;
1846 wcc_attr_item = proto_tree_add_text(tree, NullTVB, offset,
1847 END_OF_FRAME, "%s", name);
1849 wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, ett_nfs_wcc_attr);
1852 offset = dissect_size3 (pd, offset, fd, wcc_attr_tree, "size" );
1853 offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "mtime");
1854 offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "ctime");
1856 /* now we know, that wcc_attr_tree is shorter */
1857 if (wcc_attr_item) {
1858 proto_item_set_len(wcc_attr_item, offset - old_offset);
1865 /* RFC 1813, Page 24 */
1867 dissect_pre_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1869 proto_item* pre_op_attr_item = NULL;
1870 proto_tree* pre_op_attr_tree = NULL;
1871 int old_offset = offset;
1872 guint32 attributes_follow;
1875 pre_op_attr_item = proto_tree_add_text(tree, NullTVB, offset,
1876 END_OF_FRAME, "%s", name);
1877 if (pre_op_attr_item)
1878 pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, ett_nfs_pre_op_attr);
1881 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1882 attributes_follow = EXTRACT_UINT(pd, offset+0);
1883 proto_tree_add_text(pre_op_attr_tree, NullTVB, offset, 4,
1884 "attributes_follow: %s (%u)",
1885 val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
1887 switch (attributes_follow) {
1889 offset = dissect_wcc_attr(pd, offset, fd, pre_op_attr_tree,
1897 /* now we know, that pre_op_attr_tree is shorter */
1898 if (pre_op_attr_item) {
1899 proto_item_set_len(pre_op_attr_item, offset - old_offset);
1906 /* RFC 1813, Page 24 */
1908 dissect_wcc_data(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1910 proto_item* wcc_data_item = NULL;
1911 proto_tree* wcc_data_tree = NULL;
1912 int old_offset = offset;
1915 wcc_data_item = proto_tree_add_text(tree, NullTVB, offset,
1916 END_OF_FRAME, "%s", name);
1918 wcc_data_tree = proto_item_add_subtree(wcc_data_item, ett_nfs_wcc_data);
1921 offset = dissect_pre_op_attr (pd, offset, fd, wcc_data_tree, "before");
1922 offset = dissect_post_op_attr(pd, offset, fd, wcc_data_tree, "after" );
1924 /* now we know, that wcc_data is shorter */
1925 if (wcc_data_item) {
1926 proto_item_set_len(wcc_data_item, offset - old_offset);
1933 /* RFC 1813, Page 25 */
1935 dissect_post_op_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1937 proto_item* post_op_fh3_item = NULL;
1938 proto_tree* post_op_fh3_tree = NULL;
1939 int old_offset = offset;
1940 guint32 handle_follows;
1943 post_op_fh3_item = proto_tree_add_text(tree, NullTVB, offset,
1944 END_OF_FRAME, "%s", name);
1945 if (post_op_fh3_item)
1946 post_op_fh3_tree = proto_item_add_subtree(post_op_fh3_item, ett_nfs_post_op_fh3);
1949 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1950 handle_follows = EXTRACT_UINT(pd, offset+0);
1951 proto_tree_add_text(post_op_fh3_tree, NullTVB, offset, 4,
1952 "handle_follows: %s (%u)",
1953 val_to_str(handle_follows,value_follows,"Unknown"), handle_follows);
1955 switch (handle_follows) {
1957 offset = dissect_nfs_fh3(pd, offset, fd, post_op_fh3_tree,
1965 /* now we know, that post_op_fh3_tree is shorter */
1966 if (post_op_fh3_item) {
1967 proto_item_set_len(post_op_fh3_item, offset - old_offset);
1974 /* RFC 1813, Page 25 */
1976 dissect_set_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1978 proto_item* set_mode3_item = NULL;
1979 proto_tree* set_mode3_tree = NULL;
1980 int old_offset = offset;
1984 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1985 set_it = EXTRACT_UINT(pd, offset+0);
1986 set_it_name = val_to_str(set_it,value_follows,"Unknown");
1989 set_mode3_item = proto_tree_add_text(tree, NullTVB, offset,
1990 END_OF_FRAME, "%s: %s", name, set_it_name);
1992 set_mode3_tree = proto_item_add_subtree(set_mode3_item, ett_nfs_set_mode3);
1996 proto_tree_add_text(set_mode3_tree, NullTVB, offset, 4,
1997 "set_it: %s (%u)", set_it_name, set_it);
2003 offset = dissect_mode3(pd, offset, fd, set_mode3_tree,
2011 /* now we know, that set_mode3 is shorter */
2012 if (set_mode3_item) {
2013 proto_item_set_len(set_mode3_item, offset - old_offset);
2020 /* RFC 1813, Page 26 */
2022 dissect_set_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2024 proto_item* set_uid3_item = NULL;
2025 proto_tree* set_uid3_tree = NULL;
2026 int old_offset = offset;
2030 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2031 set_it = EXTRACT_UINT(pd, offset+0);
2032 set_it_name = val_to_str(set_it,value_follows,"Unknown");
2035 set_uid3_item = proto_tree_add_text(tree, NullTVB, offset,
2036 END_OF_FRAME, "%s: %s", name, set_it_name);
2038 set_uid3_tree = proto_item_add_subtree(set_uid3_item, ett_nfs_set_uid3);
2042 proto_tree_add_text(set_uid3_tree, NullTVB, offset, 4,
2043 "set_it: %s (%u)", set_it_name, set_it);
2049 offset = dissect_uid3(pd, offset, fd, set_uid3_tree,
2057 /* now we know, that set_uid3 is shorter */
2058 if (set_uid3_item) {
2059 proto_item_set_len(set_uid3_item, offset - old_offset);
2066 /* RFC 1813, Page 26 */
2068 dissect_set_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2070 proto_item* set_gid3_item = NULL;
2071 proto_tree* set_gid3_tree = NULL;
2072 int old_offset = offset;
2076 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2077 set_it = EXTRACT_UINT(pd, offset+0);
2078 set_it_name = val_to_str(set_it,value_follows,"Unknown");
2081 set_gid3_item = proto_tree_add_text(tree, NullTVB, offset,
2082 END_OF_FRAME, "%s: %s", name, set_it_name);
2084 set_gid3_tree = proto_item_add_subtree(set_gid3_item, ett_nfs_set_gid3);
2088 proto_tree_add_text(set_gid3_tree, NullTVB, offset, 4,
2089 "set_it: %s (%u)", set_it_name, set_it);
2095 offset = dissect_gid3(pd, offset, fd, set_gid3_tree,
2103 /* now we know, that set_gid3 is shorter */
2104 if (set_gid3_item) {
2105 proto_item_set_len(set_gid3_item, offset - old_offset);
2112 /* RFC 1813, Page 26 */
2114 dissect_set_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2116 proto_item* set_size3_item = NULL;
2117 proto_tree* set_size3_tree = NULL;
2118 int old_offset = offset;
2122 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2123 set_it = EXTRACT_UINT(pd, offset+0);
2124 set_it_name = val_to_str(set_it,value_follows,"Unknown");
2127 set_size3_item = proto_tree_add_text(tree, NullTVB, offset,
2128 END_OF_FRAME, "%s: %s", name, set_it_name);
2130 set_size3_tree = proto_item_add_subtree(set_size3_item, ett_nfs_set_size3);
2134 proto_tree_add_text(set_size3_tree, NullTVB, offset, 4,
2135 "set_it: %s (%u)", set_it_name, set_it);
2141 offset = dissect_size3(pd, offset, fd, set_size3_tree,
2149 /* now we know, that set_size3 is shorter */
2150 if (set_size3_item) {
2151 proto_item_set_len(set_size3_item, offset - old_offset);
2158 /* RFC 1813, Page 25 */
2159 #define DONT_CHANGE 0
2160 #define SET_TO_SERVER_TIME 1
2161 #define SET_TO_CLIENT_TIME 2
2163 const value_string time_how[] =
2165 { DONT_CHANGE, "don't change" },
2166 { SET_TO_SERVER_TIME, "set to server time" },
2167 { SET_TO_CLIENT_TIME, "set to client time" },
2172 /* RFC 1813, Page 26 */
2174 dissect_set_atime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2176 proto_item* set_atime_item = NULL;
2177 proto_tree* set_atime_tree = NULL;
2178 int old_offset = offset;
2182 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2183 set_it = EXTRACT_UINT(pd, offset+0);
2184 set_it_name = val_to_str(set_it,time_how,"Unknown");
2187 set_atime_item = proto_tree_add_text(tree, NullTVB, offset,
2188 END_OF_FRAME, "%s: %s",
2191 set_atime_tree = proto_item_add_subtree(set_atime_item, ett_nfs_set_atime);
2195 proto_tree_add_text(set_atime_tree, NullTVB, offset, 4,
2196 "set_it: %s (%u)", set_it_name, set_it);
2201 case SET_TO_CLIENT_TIME:
2203 offset = dissect_nfstime3(pd, offset, fd, set_atime_tree,
2211 /* now we know, that set_atime is shorter */
2212 if (set_atime_item) {
2213 proto_item_set_len(set_atime_item, offset - old_offset);
2220 /* RFC 1813, Page 26 */
2222 dissect_set_mtime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2224 proto_item* set_mtime_item = NULL;
2225 proto_tree* set_mtime_tree = NULL;
2226 int old_offset = offset;
2230 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2231 set_it = EXTRACT_UINT(pd, offset+0);
2232 set_it_name = val_to_str(set_it,time_how,"Unknown");
2235 set_mtime_item = proto_tree_add_text(tree, NullTVB, offset,
2236 END_OF_FRAME, "%s: %s",
2239 set_mtime_tree = proto_item_add_subtree(set_mtime_item, ett_nfs_set_mtime);
2243 proto_tree_add_text(set_mtime_tree, NullTVB, offset, 4,
2244 "set_it: %s (%u)", set_it_name, set_it);
2249 case SET_TO_CLIENT_TIME:
2251 offset = dissect_nfstime3(pd, offset, fd, set_mtime_tree,
2259 /* now we know, that set_mtime is shorter */
2260 if (set_mtime_item) {
2261 proto_item_set_len(set_mtime_item, offset - old_offset);
2268 /* RFC 1813, Page 25..27 */
2270 dissect_sattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2272 proto_item* sattr3_item = NULL;
2273 proto_tree* sattr3_tree = NULL;
2274 int old_offset = offset;
2277 sattr3_item = proto_tree_add_text(tree, NullTVB, offset,
2278 END_OF_FRAME, "%s", name);
2280 sattr3_tree = proto_item_add_subtree(sattr3_item, ett_nfs_sattr3);
2283 offset = dissect_set_mode3(pd, offset, fd, sattr3_tree, "mode");
2284 offset = dissect_set_uid3 (pd, offset, fd, sattr3_tree, "uid");
2285 offset = dissect_set_gid3 (pd, offset, fd, sattr3_tree, "gid");
2286 offset = dissect_set_size3(pd, offset, fd, sattr3_tree, "size");
2287 offset = dissect_set_atime(pd, offset, fd, sattr3_tree, "atime");
2288 offset = dissect_set_mtime(pd, offset, fd, sattr3_tree, "mtime");
2290 /* now we know, that sattr3 is shorter */
2292 proto_item_set_len(sattr3_item, offset - old_offset);
2299 /* RFC 1813, Page 27 */
2301 dissect_diropargs3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2303 proto_item* diropargs3_item = NULL;
2304 proto_tree* diropargs3_tree = NULL;
2305 int old_offset = offset;
2308 diropargs3_item = proto_tree_add_text(tree, NullTVB, offset,
2309 END_OF_FRAME, "%s", name);
2310 if (diropargs3_item)
2311 diropargs3_tree = proto_item_add_subtree(diropargs3_item, ett_nfs_diropargs3);
2314 offset = dissect_nfs_fh3 (pd, offset, fd, diropargs3_tree, "dir");
2315 offset = dissect_filename3(pd, offset, fd, diropargs3_tree, hf_nfs_name,NULL);
2317 /* now we know, that diropargs3 is shorter */
2318 if (diropargs3_item) {
2319 proto_item_set_len(diropargs3_item, offset - old_offset);
2326 /* RFC 1813, Page 27 */
2328 dissect_nfs3_diropargs3_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
2330 offset = dissect_diropargs3(pd, offset, fd, tree, "object");
2336 /* RFC 1813, Page 40 */
2338 dissect_access(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
2341 proto_item* access_item = NULL;
2342 proto_tree* access_tree = NULL;
2344 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2345 access = EXTRACT_UINT(pd, offset+0);
2348 access_item = proto_tree_add_text(tree, NullTVB, offset, 4,
2349 "%s: 0x%02x", name, access);
2351 access_tree = proto_item_add_subtree(access_item, ett_nfs_access);
2355 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s READ",
2356 decode_boolean_bitfield(access, 0x001, 6, "allow", "not allow"));
2357 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s LOOKUP",
2358 decode_boolean_bitfield(access, 0x002, 6, "allow", "not allow"));
2359 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s MODIFY",
2360 decode_boolean_bitfield(access, 0x004, 6, "allowed", "not allow"));
2361 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s EXTEND",
2362 decode_boolean_bitfield(access, 0x008, 6, "allow", "not allow"));
2363 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s DELETE",
2364 decode_boolean_bitfield(access, 0x010, 6, "allow", "not allow"));
2365 proto_tree_add_text(access_tree, NullTVB, offset, 4, "%s EXECUTE",
2366 decode_boolean_bitfield(access, 0x020, 6, "allow", "not allow"));
2374 /* NFS3 file handle dissector */
2376 dissect_nfs3_nfs_fh3_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2378 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
2383 /* generic NFS3 reply dissector */
2385 dissect_nfs3_any_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2389 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2396 /* RFC 1813, Page 32,33 */
2398 dissect_nfs3_getattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2400 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
2405 /* RFC 1813, Page 32,33 */
2407 dissect_nfs3_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2411 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2414 offset = dissect_fattr3(pd, offset, fd, tree, "obj_attributes");
2425 /* RFC 1813, Page 33 */
2427 dissect_sattrguard3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, char *name)
2429 proto_item* sattrguard3_item = NULL;
2430 proto_tree* sattrguard3_tree = NULL;
2431 int old_offset = offset;
2435 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2436 check = EXTRACT_UINT(pd, offset+0);
2437 check_name = val_to_str(check,value_follows,"Unknown");
2440 sattrguard3_item = proto_tree_add_text(tree, NullTVB, offset,
2441 END_OF_FRAME, "%s: %s", name, check_name);
2442 if (sattrguard3_item)
2443 sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, ett_nfs_sattrguard3);
2446 if (sattrguard3_tree)
2447 proto_tree_add_text(sattrguard3_tree, NullTVB, offset, 4,
2448 "check: %s (%u)", check_name, check);
2454 offset = dissect_nfstime3(pd, offset, fd, sattrguard3_tree,
2462 /* now we know, that sattrguard3 is shorter */
2463 if (sattrguard3_item) {
2464 proto_item_set_len(sattrguard3_item, offset - old_offset);
2471 /* RFC 1813, Page 33..36 */
2473 dissect_nfs3_setattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2475 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object");
2476 offset = dissect_sattr3 (pd, offset, fd, tree, "new_attributes");
2477 offset = dissect_sattrguard3(pd, offset, fd, tree, "guard");
2482 /* RFC 1813, Page 33..36 */
2484 dissect_nfs3_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2488 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2491 offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc");
2494 offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc");
2502 /* RFC 1813, Page 37..39 */
2504 dissect_nfs3_lookup_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2506 offset = dissect_diropargs3 (pd, offset, fd, tree, "what");
2511 /* RFC 1813, Page 37..39 */
2513 dissect_nfs3_lookup_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2517 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2520 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object");
2521 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2522 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2525 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2533 /* RFC 1813, Page 40..43 */
2535 dissect_nfs3_access_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2537 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
2538 offset = dissect_access (pd, offset, fd, tree, "access");
2544 /* RFC 1813, Page 40..43 */
2546 dissect_nfs3_access_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2550 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2553 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2554 offset = dissect_access (pd, offset, fd, tree, "access");
2557 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2565 /* RFC 1813, Page 44,45 */
2567 dissect_nfs3_readlink_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2571 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2574 offset = dissect_post_op_attr(pd, offset, fd, tree, "symlink_attributes");
2575 offset = dissect_nfspath3 (pd, offset, fd, tree, hf_nfs_readlink_data);
2578 offset = dissect_post_op_attr(pd, offset, fd, tree, "symlink_attributes");
2586 /* RFC 1813, Page 46..48 */
2588 dissect_nfs3_read_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2590 offset = dissect_nfs_fh3(pd, offset, fd, tree, "file");
2591 offset = dissect_offset3(pd, offset, fd, tree, "offset");
2592 offset = dissect_count3 (pd, offset, fd, tree, "count");
2598 /* RFC 1813, Page 46..48 */
2600 dissect_nfs3_read_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2604 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2607 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2608 offset = dissect_count3 (pd, offset, fd, tree, "count");
2609 offset = dissect_rpc_bool (pd, offset, fd, tree, hf_nfs_read_eof);
2610 offset = dissect_nfsdata (pd, offset, fd, tree, hf_nfs_data);
2613 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2621 /* RFC 1813, Page 49 */
2622 static const value_string names_stable_how[] = {
2623 { UNSTABLE, "UNSTABLE" },
2624 { DATA_SYNC, "DATA_SYNC" },
2625 { FILE_SYNC, "FILE_SYNC" },
2630 /* RFC 1813, Page 49 */
2632 dissect_stable_how(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, int hfindex)
2636 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2637 stable_how = EXTRACT_UINT(pd,offset+0);
2639 proto_tree_add_uint(tree, hfindex, NullTVB,
2640 offset, 4, stable_how);
2648 /* RFC 1813, Page 49..54 */
2650 dissect_nfs3_write_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2652 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "file");
2653 offset = dissect_offset3 (pd, offset, fd, tree, "offset");
2654 offset = dissect_count3 (pd, offset, fd, tree, "count");
2655 offset = dissect_stable_how(pd, offset, fd, tree, hf_nfs_write_stable);
2656 offset = dissect_nfsdata (pd, offset, fd, tree, hf_nfs_data);
2662 /* RFC 1813, Page 49..54 */
2664 dissect_nfs3_write_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2668 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2671 offset = dissect_wcc_data (pd, offset, fd, tree, "file_wcc");
2672 offset = dissect_count3 (pd, offset, fd, tree, "count");
2673 offset = dissect_stable_how(pd, offset, fd, tree, hf_nfs_write_committed);
2674 offset = dissect_writeverf3(pd, offset, fd, tree);
2677 offset = dissect_wcc_data(pd, offset, fd, tree, "file_wcc");
2685 /* RFC 1813, Page 54 */
2686 static const value_string names_createmode3[] = {
2687 { UNCHECKED, "UNCHECKED" },
2688 { GUARDED, "GUARDED" },
2689 { EXCLUSIVE, "EXCLUSIVE" },
2694 /* RFC 1813, Page 54 */
2696 dissect_createmode3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, guint32* mode)
2700 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
2701 mode_value = EXTRACT_UINT(pd, offset + 0);
2703 proto_tree_add_uint(tree, hf_nfs_createmode3, NullTVB,
2704 offset+0, 4, mode_value);
2713 /* RFC 1813, Page 54..58 */
2715 dissect_nfs3_create_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2719 offset = dissect_diropargs3 (pd, offset, fd, tree, "where");
2720 offset = dissect_createmode3(pd, offset, fd, tree, &mode);
2724 offset = dissect_sattr3 (pd, offset, fd, tree, "obj_attributes");
2727 offset = dissect_createverf3(pd, offset, fd, tree);
2735 /* RFC 1813, Page 54..58 */
2737 dissect_nfs3_create_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2741 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2744 offset = dissect_post_op_fh3 (pd, offset, fd, tree, "obj");
2745 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2746 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2749 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2757 /* RFC 1813, Page 58..60 */
2759 dissect_nfs3_mkdir_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2761 offset = dissect_diropargs3(pd, offset, fd, tree, "where");
2762 offset = dissect_sattr3 (pd, offset, fd, tree, "attributes");
2768 /* RFC 1813, Page 61..63 */
2770 dissect_nfs3_symlink_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2772 offset = dissect_diropargs3(pd, offset, fd, tree, "where");
2773 offset = dissect_sattr3 (pd, offset, fd, tree, "symlink_attributes");
2774 offset = dissect_nfspath3 (pd, offset, fd, tree, hf_nfs_symlink_to);
2780 /* RFC 1813, Page 63..66 */
2782 dissect_nfs3_mknod_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2786 offset = dissect_diropargs3(pd, offset, fd, tree, "where");
2787 offset = dissect_ftype3(pd, offset, fd, tree, hf_nfs_ftype3, &type);
2791 offset = dissect_sattr3(pd, offset, fd, tree, "dev_attributes");
2792 offset = dissect_specdata3(pd, offset, fd, tree, "spec");
2796 offset = dissect_sattr3(pd, offset, fd, tree, "pipe_attributes");
2807 /* RFC 1813, Page 67..69 */
2809 dissect_nfs3_remove_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2813 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2816 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2819 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2827 /* RFC 1813, Page 71..74 */
2829 dissect_nfs3_rename_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2831 offset = dissect_diropargs3(pd, offset, fd, tree, "from");
2832 offset = dissect_diropargs3(pd, offset, fd, tree, "to");
2838 /* RFC 1813, Page 71..74 */
2840 dissect_nfs3_rename_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2844 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2847 offset = dissect_wcc_data(pd, offset, fd, tree, "fromdir_wcc");
2848 offset = dissect_wcc_data(pd, offset, fd, tree, "todir_wcc");
2851 offset = dissect_wcc_data(pd, offset, fd, tree, "fromdir_wcc");
2852 offset = dissect_wcc_data(pd, offset, fd, tree, "todir_wcc");
2860 /* RFC 1813, Page 74..76 */
2862 dissect_nfs3_link_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2864 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "file");
2865 offset = dissect_diropargs3(pd, offset, fd, tree, "link");
2871 /* RFC 1813, Page 74..76 */
2873 dissect_nfs3_link_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2877 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2880 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2881 offset = dissect_wcc_data (pd, offset, fd, tree, "linkdir_wcc");
2884 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2885 offset = dissect_wcc_data (pd, offset, fd, tree, "linkdir_wcc");
2893 /* RFC 1813, Page 76..80 */
2895 dissect_nfs3_readdir_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2897 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "dir");
2898 offset = dissect_cookie3 (pd, offset, fd, tree, "cookie");
2899 offset = dissect_cookieverf3(pd, offset, fd, tree);
2900 offset = dissect_count3 (pd, offset, fd, tree, "count");
2906 /* RFC 1813, Page 76..80 */
2908 dissect_entry3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2910 proto_item* entry_item = NULL;
2911 proto_tree* entry_tree = NULL;
2912 int old_offset = offset;
2916 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, NullTVB,
2917 offset+0, END_OF_FRAME, FALSE);
2919 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
2922 offset = dissect_fileid3(pd, offset, fd, entry_tree, "fileid");
2924 offset = dissect_filename3(pd, offset, fd, entry_tree,
2925 hf_nfs_readdir_entry_name, &name);
2927 proto_item_set_text(entry_item, "Entry: name %s", name);
2930 offset = dissect_cookie3(pd, offset, fd, entry_tree, "cookie");
2932 /* now we know, that a readdir entry is shorter */
2934 proto_item_set_len(entry_item, offset - old_offset);
2941 /* RFC 1813, Page 76..80 */
2943 dissect_nfs3_readdir_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2948 offset = dissect_stat(pd, offset, fd, tree, &status);
2951 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2952 offset = dissect_cookieverf3(pd, offset, fd, tree);
2953 offset = dissect_rpc_list(pd, offset, fd, tree,
2955 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2956 eof_value = EXTRACT_UINT(pd, offset+0);
2958 proto_tree_add_uint(tree, hf_nfs_readdir_eof, NullTVB,
2959 offset+ 0, 4, eof_value);
2963 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2971 /* RFC 1813, Page 80..83 */
2973 dissect_nfs3_readdirplus_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2975 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "dir");
2976 offset = dissect_cookie3 (pd, offset, fd, tree, "cookie");
2977 offset = dissect_cookieverf3(pd, offset, fd, tree);
2978 offset = dissect_count3 (pd, offset, fd, tree, "dircount");
2979 offset = dissect_count3 (pd, offset, fd, tree, "maxcount");
2985 /* RFC 1813, Page 80..83 */
2987 dissect_entryplus3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2989 proto_item* entry_item = NULL;
2990 proto_tree* entry_tree = NULL;
2991 int old_offset = offset;
2995 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, NullTVB,
2996 offset+0, END_OF_FRAME, FALSE);
2998 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
3001 offset = dissect_fileid3(pd, offset, fd, entry_tree, "fileid");
3003 offset = dissect_filename3(pd, offset, fd, entry_tree,
3004 hf_nfs_readdirplus_entry_name, &name);
3006 proto_item_set_text(entry_item, "Entry: name %s", name);
3009 offset = dissect_cookie3(pd, offset, fd, entry_tree, "cookie");
3011 offset = dissect_post_op_attr(pd, offset, fd, entry_tree, "name_attributes");
3012 offset = dissect_post_op_fh3(pd, offset, fd, entry_tree, "name_handle");
3014 /* now we know, that a readdirplus entry is shorter */
3016 proto_item_set_len(entry_item, offset - old_offset);
3023 /* RFC 1813, Page 80..83 */
3025 dissect_nfs3_readdirplus_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3030 offset = dissect_stat(pd, offset, fd, tree, &status);
3033 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
3034 offset = dissect_cookieverf3(pd, offset, fd, tree);
3035 offset = dissect_rpc_list(pd, offset, fd, tree,
3036 dissect_entryplus3);
3037 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3038 eof_value = EXTRACT_UINT(pd, offset+0);
3040 proto_tree_add_uint(tree, hf_nfs_readdir_eof, NullTVB,
3041 offset+ 0, 4, eof_value);
3045 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
3053 /* RFC 1813, Page 84..86 */
3055 dissect_nfs3_fsstat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3060 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
3063 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3064 offset = dissect_size3 (pd, offset, fd, tree, "tbytes");
3065 offset = dissect_size3 (pd, offset, fd, tree, "fbytes");
3066 offset = dissect_size3 (pd, offset, fd, tree, "abytes");
3067 offset = dissect_size3 (pd, offset, fd, tree, "tfiles");
3068 offset = dissect_size3 (pd, offset, fd, tree, "ffiles");
3069 offset = dissect_size3 (pd, offset, fd, tree, "afiles");
3070 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
3071 invarsec = EXTRACT_UINT(pd, offset + 0);
3073 proto_tree_add_uint(tree, hf_nfs_fsstat_invarsec, NullTVB,
3074 offset+0, 4, invarsec);
3078 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3086 #define FSF3_LINK 0x0001
3087 #define FSF3_SYMLINK 0x0002
3088 #define FSF3_HOMOGENEOUS 0x0008
3089 #define FSF3_CANSETTIME 0x0010
3092 /* RFC 1813, Page 86..90 */
3094 dissect_nfs3_fsinfo_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3105 proto_item* properties_item = NULL;
3106 proto_tree* properties_tree = NULL;
3108 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
3111 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3112 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3113 rtmax = EXTRACT_UINT(pd, offset+0);
3115 proto_tree_add_uint(tree, hf_nfs_fsinfo_rtmax, NullTVB,
3116 offset+0, 4, rtmax);
3118 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3119 rtpref = EXTRACT_UINT(pd, offset+0);
3121 proto_tree_add_uint(tree, hf_nfs_fsinfo_rtpref, NullTVB,
3122 offset+0, 4, rtpref);
3124 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3125 rtmult = EXTRACT_UINT(pd, offset+0);
3127 proto_tree_add_uint(tree, hf_nfs_fsinfo_rtmult, NullTVB,
3128 offset+0, 4, rtmult);
3130 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3131 wtmax = EXTRACT_UINT(pd, offset+0);
3133 proto_tree_add_uint(tree, hf_nfs_fsinfo_wtmax, NullTVB,
3134 offset+0, 4, wtmax);
3136 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3137 wtpref = EXTRACT_UINT(pd, offset+0);
3139 proto_tree_add_uint(tree, hf_nfs_fsinfo_wtpref, NullTVB,
3140 offset+0, 4, wtpref);
3142 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3143 wtmult = EXTRACT_UINT(pd, offset+0);
3145 proto_tree_add_uint(tree, hf_nfs_fsinfo_wtmult, NullTVB,
3146 offset+0, 4, wtmult);
3148 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3149 dtpref = EXTRACT_UINT(pd, offset+0);
3151 proto_tree_add_uint(tree, hf_nfs_fsinfo_dtpref, NullTVB,
3152 offset+0, 4, dtpref);
3155 offset = dissect_size3 (pd, offset, fd, tree, "maxfilesize");
3156 offset = dissect_nfstime3(pd, offset, fd, tree, "time_delta");
3157 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
3158 properties = EXTRACT_UINT(pd, offset+0);
3160 properties_item = proto_tree_add_uint(tree,
3161 hf_nfs_fsinfo_properties,
3162 NullTVB, offset+0, 4, properties);
3163 if (properties_item)
3164 properties_tree = proto_item_add_subtree(properties_item, ett_nfs_fsinfo_properties);
3165 if (properties_tree) {
3166 proto_tree_add_text(properties_tree, NullTVB,
3168 decode_boolean_bitfield(properties,
3170 "SETATTR can set time on server",
3171 "SETATTR can't set time on server"));
3173 proto_tree_add_text(properties_tree, NullTVB,
3175 decode_boolean_bitfield(properties,
3177 "PATHCONF is valid for all files",
3178 "PATHCONF should be get for every single file"));
3180 proto_tree_add_text(properties_tree, NullTVB,
3182 decode_boolean_bitfield(properties,
3184 "File System supports symbolic links",
3185 "File System does not symbolic hard links"));
3187 proto_tree_add_text(properties_tree, NullTVB,
3189 decode_boolean_bitfield(properties,
3191 "File System supports hard links",
3192 "File System does not support hard links"));
3198 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3206 /* RFC 1813, Page 90..92 */
3208 dissect_nfs3_pathconf_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3214 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
3217 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3218 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
3219 linkmax = EXTRACT_UINT(pd, offset + 0);
3221 proto_tree_add_uint(tree, hf_nfs_pathconf_linkmax, NullTVB,
3222 offset+0, 4, linkmax);
3224 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
3225 name_max = EXTRACT_UINT(pd, offset + 0);
3227 proto_tree_add_uint(tree, hf_nfs_pathconf_name_max, NullTVB,
3228 offset+0, 4, name_max);
3230 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_no_trunc);
3231 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_chown_restricted);
3232 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_case_insensitive);
3233 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_case_preserving);
3236 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
3244 /* RFC 1813, Page 92..95 */
3246 dissect_nfs3_commit_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3248 offset = dissect_nfs_fh3(pd, offset, fd, tree, "file");
3249 offset = dissect_offset3(pd, offset, fd, tree, "offset");
3250 offset = dissect_count3 (pd, offset, fd, tree, "count");
3256 /* RFC 1813, Page 92..95 */
3258 dissect_nfs3_commit_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
3262 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
3265 offset = dissect_wcc_data (pd, offset, fd, tree, "file_wcc");
3266 offset = dissect_writeverf3(pd, offset, fd, tree);
3269 offset = dissect_wcc_data(pd, offset, fd, tree, "file_wcc");
3277 /* 1 missing functions */
3280 /* proc number, "proc name", dissect_request, dissect_reply */
3281 /* NULL as function pointer means: take the generic one. */
3282 const vsff nfs3_proc[] = {
3283 { 0, "NULL", /* OK */
3285 { 1, "GETATTR", /* OK */
3286 dissect_nfs3_getattr_call, dissect_nfs3_getattr_reply },
3287 { 2, "SETATTR", /* OK */
3288 dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply },
3289 { 3, "LOOKUP", /* OK */
3290 dissect_nfs3_lookup_call, dissect_nfs3_lookup_reply },
3291 { 4, "ACCESS", /* OK */
3292 dissect_nfs3_access_call, dissect_nfs3_access_reply },
3293 { 5, "READLINK", /* OK */
3294 dissect_nfs3_nfs_fh3_call, dissect_nfs3_readlink_reply },
3295 { 6, "READ", /* OK */
3296 dissect_nfs3_read_call, dissect_nfs3_read_reply },
3297 { 7, "WRITE", /* OK */
3298 dissect_nfs3_write_call, dissect_nfs3_write_reply },
3299 { 8, "CREATE", /* OK */
3300 dissect_nfs3_create_call, dissect_nfs3_create_reply },
3301 { 9, "MKDIR", /* OK */
3302 dissect_nfs3_mkdir_call, dissect_nfs3_create_reply },
3303 { 10, "SYMLINK", /* OK */
3304 dissect_nfs3_symlink_call, dissect_nfs3_create_reply },
3305 { 11, "MKNOD", /* OK */
3306 dissect_nfs3_mknod_call, dissect_nfs3_create_reply },
3307 { 12, "REMOVE", /* OK */
3308 dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply },
3309 { 13, "RMDIR", /* OK */
3310 dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply },
3311 { 14, "RENAME", /* OK */
3312 dissect_nfs3_rename_call, dissect_nfs3_rename_reply },
3313 { 15, "LINK", /* OK */
3314 dissect_nfs3_link_call, dissect_nfs3_link_reply },
3315 { 16, "READDIR", /* OK */
3316 dissect_nfs3_readdir_call, dissect_nfs3_readdir_reply },
3317 { 17, "READDIRPLUS", /* OK */
3318 dissect_nfs3_readdirplus_call, dissect_nfs3_readdirplus_reply },
3319 { 18, "FSSTAT", /* OK */
3320 dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsstat_reply },
3321 { 19, "FSINFO", /* OK */
3322 dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsinfo_reply },
3323 { 20, "PATHCONF", /* OK */
3324 dissect_nfs3_nfs_fh3_call, dissect_nfs3_pathconf_reply },
3325 { 21, "COMMIT", /* OK */
3326 dissect_nfs3_commit_call, dissect_nfs3_commit_reply },
3327 { 0,NULL,NULL,NULL }
3329 /* end of NFS Version 3 */
3332 static struct true_false_string yesno = { "Yes", "No" };
3336 proto_register_nfs(void)
3338 static hf_register_info hf[] = {
3339 { &hf_nfs_fh_fsid_major, {
3340 "major", "nfs.fh.fsid.major", FT_UINT32, BASE_DEC,
3341 NULL, 0, "major file system ID" }},
3342 { &hf_nfs_fh_fsid_minor, {
3343 "minor", "nfs.fh.fsid.minor", FT_UINT32, BASE_DEC,
3344 NULL, 0, "minor file system ID" }},
3345 { &hf_nfs_fh_xfsid_major, {
3346 "exported major", "nfs.fh.xfsid.major", FT_UINT32, BASE_DEC,
3347 NULL, 0, "exported major file system ID" }},
3348 { &hf_nfs_fh_xfsid_minor, {
3349 "exported minor", "nfs.fh.xfsid.minor", FT_UINT32, BASE_DEC,
3350 NULL, 0, "exported minor file system ID" }},
3351 { &hf_nfs_fh_fstype, {
3352 "file system type", "nfs.fh.fstype", FT_UINT32, BASE_DEC,
3353 NULL, 0, "file system type" }},
3355 "file number", "nfs.fh.fn", FT_UINT32, BASE_DEC,
3356 NULL, 0, "file number" }},
3357 { &hf_nfs_fh_fn_len, {
3358 "length", "nfs.fh.fn.len", FT_UINT32, BASE_DEC,
3359 NULL, 0, "file number length" }},
3360 { &hf_nfs_fh_fn_inode, {
3361 "inode", "nfs.fh.fn.inode", FT_UINT32, BASE_DEC,
3362 NULL, 0, "file number inode" }},
3363 { &hf_nfs_fh_fn_generation, {
3364 "generation", "nfs.fh.fn.generation", FT_UINT32, BASE_DEC,
3365 NULL, 0, "file number generation" }},
3367 "exported file number", "nfs.fh.xfn", FT_UINT32, BASE_DEC,
3368 NULL, 0, "exported file number" }},
3369 { &hf_nfs_fh_xfn_len, {
3370 "length", "nfs.fh.xfn.len", FT_UINT32, BASE_DEC,
3371 NULL, 0, "exported file number length" }},
3372 { &hf_nfs_fh_xfn_inode, {
3373 "exported inode", "nfs.fh.xfn.inode", FT_UINT32, BASE_DEC,
3374 NULL, 0, "exported file number inode" }},
3375 { &hf_nfs_fh_xfn_generation, {
3376 "generation", "nfs.fh.xfn.generation", FT_UINT32, BASE_DEC,
3377 NULL, 0, "exported file number generation" }},
3378 { &hf_nfs_fh_dentry, {
3379 "dentry", "nfs.fh.dentry", FT_UINT32, BASE_HEX,
3380 NULL, 0, "dentry (cookie)" }},
3382 "device", "nfs.fh.dev", FT_UINT32, BASE_DEC,
3383 NULL, 0, "device" }},
3384 { &hf_nfs_fh_xdev, {
3385 "exported device", "nfs.fh.xdev", FT_UINT32, BASE_DEC,
3386 NULL, 0, "exported device" }},
3387 { &hf_nfs_fh_dirinode, {
3388 "directory inode", "nfs.fh.dirinode", FT_UINT32, BASE_DEC,
3389 NULL, 0, "directory inode" }},
3390 { &hf_nfs_fh_pinode, {
3391 "pseudo inode", "nfs.fh.pinode", FT_UINT32, BASE_HEX,
3392 NULL, 0, "pseudo inode" }},
3393 { &hf_nfs_fh_hp_len, {
3394 "length", "nfs.fh.hp.len", FT_UINT32, BASE_DEC,
3395 NULL, 0, "hash path length" }},
3397 "Status", "nfs.status2", FT_UINT32, BASE_DEC,
3398 VALS(names_nfs_stat), 0, "Reply status" }},
3400 "Name", "nfs.name", FT_STRING, BASE_DEC,
3402 { &hf_nfs_readlink_data, {
3403 "Data", "nfs.readlink.data", FT_STRING, BASE_DEC,
3404 NULL, 0, "Symbolic Link Data" }},
3405 { &hf_nfs_read_offset, {
3406 "Offset", "nfs.read.offset", FT_UINT32, BASE_DEC,
3407 NULL, 0, "Read Offset" }},
3408 { &hf_nfs_read_count, {
3409 "Count", "nfs.read.count", FT_UINT32, BASE_DEC,
3410 NULL, 0, "Read Count" }},
3411 { &hf_nfs_read_totalcount, {
3412 "Total Count", "nfs.read.totalcount", FT_UINT32, BASE_DEC,
3413 NULL, 0, "Total Count (obsolete)" }},
3415 "Data", "nfs.data", FT_STRING, BASE_DEC,
3417 { &hf_nfs_write_beginoffset, {
3418 "Begin Offset", "nfs.write.beginoffset", FT_UINT32, BASE_DEC,
3419 NULL, 0, "Begin offset (obsolete)" }},
3420 { &hf_nfs_write_offset, {
3421 "Offset", "nfs.write.offset", FT_UINT32, BASE_DEC,
3422 NULL, 0, "Offset" }},
3423 { &hf_nfs_write_totalcount, {
3424 "Total Count", "nfs.write.totalcount", FT_UINT32, BASE_DEC,
3425 NULL, 0, "Total Count (obsolete)" }},
3426 { &hf_nfs_symlink_to, {
3427 "To", "nfs.symlink.to", FT_STRING, BASE_DEC,
3428 NULL, 0, "Symbolic link destination name" }},
3429 { &hf_nfs_readdir_cookie, {
3430 "Cookie", "nfs.readdir.cookie", FT_UINT32, BASE_DEC,
3431 NULL, 0, "Directory Cookie" }},
3432 { &hf_nfs_readdir_count, {
3433 "Count", "nfs.readdir.count", FT_UINT32, BASE_DEC,
3434 NULL, 0, "Directory Count" }},
3435 { &hf_nfs_readdir_entry, {
3436 "Entry", "nfs.readdir.entry", FT_NONE, 0,
3437 NULL, 0, "Directory Entry" }},
3438 { &hf_nfs_readdir_entry_fileid, {
3439 "File ID", "nfs.readdir.entry.fileid", FT_UINT32, BASE_DEC,
3440 NULL, 0, "File ID" }},
3441 { &hf_nfs_readdir_entry_name, {
3442 "Name", "nfs.readdir.entry.name", FT_STRING, BASE_DEC,
3444 { &hf_nfs_readdirplus_entry_name, {
3445 "Name", "nfs.readdirplus.entry.name", FT_STRING, BASE_DEC,
3447 { &hf_nfs_readdir_entry_cookie, {
3448 "Cookie", "nfs.readdir.entry.cookie", FT_UINT32, BASE_DEC,
3449 NULL, 0, "Directory Cookie" }},
3450 { &hf_nfs_readdir_eof, {
3451 "EOF", "nfs.readdir.eof", FT_UINT32, BASE_DEC,
3453 { &hf_nfs_statfs_tsize, {
3454 "Transfer Size", "nfs.statfs.tsize", FT_UINT32, BASE_DEC,
3455 NULL, 0, "Transfer Size" }},
3456 { &hf_nfs_statfs_bsize, {
3457 "Block Size", "nfs.statfs.bsize", FT_UINT32, BASE_DEC,
3458 NULL, 0, "Block Size" }},
3459 { &hf_nfs_statfs_blocks, {
3460 "Total Blocks", "nfs.statfs.blocks", FT_UINT32, BASE_DEC,
3461 NULL, 0, "Total Blocks" }},
3462 { &hf_nfs_statfs_bfree, {
3463 "Free Blocks", "nfs.statfs.bfree", FT_UINT32, BASE_DEC,
3464 NULL, 0, "Free Blocks" }},
3465 { &hf_nfs_statfs_bavail, {
3466 "Available Blocks", "nfs.statfs.bavail", FT_UINT32, BASE_DEC,
3467 NULL, 0, "Available Blocks" }},
3469 "Type", "nfs.type", FT_UINT32, BASE_DEC,
3470 VALS(names_nfs_ftype3), 0, "File Type" }},
3471 { &hf_nfs_nfsstat3, {
3472 "Status", "nfs.status", FT_UINT32, BASE_DEC,
3473 VALS(names_nfs_nfsstat3), 0, "Reply status" }},
3474 { &hf_nfs_read_eof, {
3475 "EOF", "nfs.read.eof", FT_BOOLEAN, BASE_NONE,
3476 &yesno, 0, "EOF" }},
3477 { &hf_nfs_write_stable, {
3478 "Stable", "nfs.write.stable", FT_UINT32, BASE_DEC,
3479 VALS(names_stable_how), 0, "Stable" }},
3480 { &hf_nfs_write_committed, {
3481 "Committed", "nfs.write.committed", FT_UINT32, BASE_DEC,
3482 VALS(names_stable_how), 0, "Committed" }},
3483 { &hf_nfs_createmode3, {
3484 "Create Mode", "nfs.createmode", FT_UINT32, BASE_DEC,
3485 VALS(names_createmode3), 0, "Create Mode" }},
3486 { &hf_nfs_fsstat_invarsec, {
3487 "invarsec", "nfs.fsstat.invarsec", FT_UINT32, BASE_DEC,
3488 NULL, 0, "probable number of seconds of file system invariance" }},
3489 { &hf_nfs_fsinfo_rtmax, {
3490 "rtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC,
3491 NULL, 0, "maximum READ request" }},
3492 { &hf_nfs_fsinfo_rtpref, {
3493 "rtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC,
3494 NULL, 0, "preferred READ request" }},
3495 { &hf_nfs_fsinfo_rtmult, {
3496 "rtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC,
3497 NULL, 0, "suggested READ multiple" }},
3498 { &hf_nfs_fsinfo_wtmax, {
3499 "wtmax", "nfs.fsinfo.wtmax", FT_UINT32, BASE_DEC,
3500 NULL, 0, "maximum WRITE request" }},
3501 { &hf_nfs_fsinfo_wtpref, {
3502 "wtpref", "nfs.fsinfo.wtpref", FT_UINT32, BASE_DEC,
3503 NULL, 0, "preferred WRITE request" }},
3504 { &hf_nfs_fsinfo_wtmult, {
3505 "wtmult", "nfs.fsinfo.wtmult", FT_UINT32, BASE_DEC,
3506 NULL, 0, "suggested WRITE multiple" }},
3507 { &hf_nfs_fsinfo_dtpref, {
3508 "dtpref", "nfs.fsinfo.dtpref", FT_UINT32, BASE_DEC,
3509 NULL, 0, "preferred READDIR request" }},
3510 { &hf_nfs_fsinfo_properties, {
3511 "Properties", "nfs.fsinfo.propeties", FT_UINT32, BASE_HEX,
3512 NULL, 0, "File System Properties" }},
3513 { &hf_nfs_pathconf_linkmax, {
3514 "linkmax", "nfs.pathconf.linkmax", FT_UINT32, BASE_DEC,
3515 NULL, 0, "Maximum number of hard links" }},
3516 { &hf_nfs_pathconf_name_max, {
3517 "name_max", "nfs.pathconf.name_max", FT_UINT32, BASE_DEC,
3518 NULL, 0, "Maximum file name length" }},
3519 { &hf_nfs_pathconf_no_trunc, {
3520 "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE,
3521 &yesno, 0, "No long file name truncation" }},
3522 { &hf_nfs_pathconf_chown_restricted, {
3523 "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, BASE_NONE,
3524 &yesno, 0, "chown is restricted to root" }},
3525 { &hf_nfs_pathconf_case_insensitive, {
3526 "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, BASE_NONE,
3527 &yesno, 0, "file names are treated case insensitive" }},
3528 { &hf_nfs_pathconf_case_preserving, {
3529 "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, BASE_NONE,
3530 &yesno, 0, "file name cases are preserved" }}
3533 static gint *ett[] = {
3546 &ett_nfs_readdir_entry,
3552 &ett_nfs_post_op_fh3,
3554 &ett_nfs_diropargs3,
3555 &ett_nfs_sattrguard3,
3562 &ett_nfs_pre_op_attr,
3563 &ett_nfs_post_op_attr,
3567 &ett_nfs_fsinfo_properties
3569 proto_nfs = proto_register_protocol("Network File System", "nfs");
3570 proto_register_field_array(proto_nfs, hf, array_length(hf));
3571 proto_register_subtree_array(ett, array_length(ett));
3575 proto_reg_handoff_nfs(void)
3577 /* Register the protocol as RPC */
3578 rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs);
3579 /* Register the procedure tables */
3580 rpc_init_proc_table(NFS_PROGRAM, 2, nfs2_proc);
3581 rpc_init_proc_table(NFS_PROGRAM, 3, nfs3_proc);