2 * Routines for nfs dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
5 * $Id: packet-nfs.c,v 1.16 1999/12/14 11:53:19 girlich Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
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;
45 static int hf_nfs_stat = -1;
46 static int hf_nfs_name = -1;
47 static int hf_nfs_readlink_data = -1;
48 static int hf_nfs_read_offset = -1;
49 static int hf_nfs_read_count = -1;
50 static int hf_nfs_read_totalcount = -1;
51 static int hf_nfs_data = -1;
52 static int hf_nfs_write_beginoffset = -1;
53 static int hf_nfs_write_offset = -1;
54 static int hf_nfs_write_totalcount = -1;
55 static int hf_nfs_symlink_to = -1;
56 static int hf_nfs_readdir_cookie = -1;
57 static int hf_nfs_readdir_count = -1;
58 static int hf_nfs_readdir_value_follows = -1;
59 static int hf_nfs_readdir_entry = -1;
60 static int hf_nfs_readdir_entry_fileid = -1;
61 static int hf_nfs_readdir_entry_name = -1;
62 static int hf_nfs_readdir_entry_cookie = -1;
63 static int hf_nfs_readdir_eof = -1;
64 static int hf_nfs_statfs_tsize = -1;
65 static int hf_nfs_statfs_bsize = -1;
66 static int hf_nfs_statfs_blocks = -1;
67 static int hf_nfs_statfs_bfree = -1;
68 static int hf_nfs_statfs_bavail = -1;
69 static int hf_nfs_nfsstat3 = -1;
70 static int hf_nfs_read_eof = -1;
71 static int hf_nfs_write_stable = -1;
72 static int hf_nfs_write_committed = -1;
73 static int hf_nfs_createmode3 = -1;
74 static int hf_nfs_fsstat_invarsec = -1;
75 static int hf_nfs_fsinfo_rtmax = -1;
76 static int hf_nfs_fsinfo_rtpref = -1;
77 static int hf_nfs_fsinfo_rtmult = -1;
78 static int hf_nfs_fsinfo_wtmax = -1;
79 static int hf_nfs_fsinfo_wtpref = -1;
80 static int hf_nfs_fsinfo_wtmult = -1;
81 static int hf_nfs_fsinfo_dtpref = -1;
82 static int hf_nfs_fsinfo_properties = -1;
83 static int hf_nfs_pathconf_linkmax = -1;
84 static int hf_nfs_pathconf_name_max = -1;
85 static int hf_nfs_pathconf_no_trunc = -1;
86 static int hf_nfs_pathconf_chown_restricted = -1;
87 static int hf_nfs_pathconf_case_insensitive = -1;
88 static int hf_nfs_pathconf_case_preserving = -1;
91 static gint ett_nfs = -1;
92 static gint ett_nfs_fhandle = -1;
93 static gint ett_nfs_timeval = -1;
94 static gint ett_nfs_mode = -1;
95 static gint ett_nfs_fattr = -1;
96 static gint ett_nfs_sattr = -1;
97 static gint ett_nfs_diropargs = -1;
98 static gint ett_nfs_readdir_entry = -1;
99 static gint ett_nfs_mode3 = -1;
100 static gint ett_nfs_specdata3 = -1;
101 static gint ett_nfs_fh3 = -1;
102 static gint ett_nfs_nfstime3 = -1;
103 static gint ett_nfs_fattr3 = -1;
104 static gint ett_nfs_post_op_fh3 = -1;
105 static gint ett_nfs_sattr3 = -1;
106 static gint ett_nfs_diropargs3 = -1;
107 static gint ett_nfs_sattrguard3 = -1;
108 static gint ett_nfs_set_mode3 = -1;
109 static gint ett_nfs_set_uid3 = -1;
110 static gint ett_nfs_set_gid3 = -1;
111 static gint ett_nfs_set_size3 = -1;
112 static gint ett_nfs_set_atime = -1;
113 static gint ett_nfs_set_mtime = -1;
114 static gint ett_nfs_pre_op_attr = -1;
115 static gint ett_nfs_post_op_attr = -1;
116 static gint ett_nfs_wcc_attr = -1;
117 static gint ett_nfs_wcc_data = -1;
118 static gint ett_nfs_access = -1;
119 static gint ett_nfs_fsinfo_properties = -1;
122 /***************************/
123 /* NFS Version 2, RFC 1094 */
124 /***************************/
127 /* base 32 bit type for NFS v2 */
129 dissect_unsigned_int(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
132 offset = dissect_rpc_uint32(pd,offset,fd,tree,name,"unsigned int");
137 /* RFC 1094, Page 12..14 */
138 const value_string names_nfs_stat[] =
148 { 20, "ERR_NOTDIR" },
153 { 63, "ERR_NAMETOOLONG" },
154 { 66, "ERR_NOTEMPTY" },
157 { 99, "ERR_WFLUSH" },
162 /* RFC 1094, Page 12..14 */
164 dissect_stat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
169 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
170 stat = EXTRACT_UINT(pd, offset+0);
173 /* this gives the right NFSv2 number<->message relation */
174 /* and makes it searchable via "nfs.status" */
175 proto_tree_add_item_format(tree, hf_nfs_nfsstat3,
176 offset+0, 4, stat, "Status: %s (%u)",
177 val_to_str(stat,names_nfs_stat,"%u"), stat);
186 /* RFC 1094, Page 12..14 */
188 dissect_nfs2_stat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
192 offset = dissect_stat(pd, offset, fd, tree, &status);
198 /* RFC 1094, Page 15 */
200 dissect_ftype(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
204 char* ftype_name = NULL;
206 const value_string nfs2_ftype[] =
209 { 1, "Regular File" },
211 { 3, "Block Special Device" },
212 { 4, "Character Special Device" },
213 { 5, "Symbolic Link" },
217 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
218 ftype = EXTRACT_UINT(pd, offset+0);
219 ftype_name = val_to_str(ftype, nfs2_ftype, "%u");
222 proto_tree_add_text(tree, offset, 4,
223 "%s: %s (%u)", name, ftype_name, ftype);
231 /* RFC 1094, Page 15 */
233 dissect_fhandle(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
236 proto_tree* ftree = NULL;
239 fitem = proto_tree_add_text(tree, offset, FHSIZE,
242 ftree = proto_item_add_subtree(fitem, ett_nfs_fhandle);
246 proto_tree_add_text(ftree,offset+0,FHSIZE,
247 "file handle (opaque data)");
255 /* RFC 1094, Page 15 */
257 dissect_nfs2_fhandle_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
259 offset = dissect_fhandle(pd, offset, fd, tree, "object");
265 /* RFC 1094, Page 15 */
267 dissect_timeval(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
272 proto_item* time_item;
273 proto_tree* time_tree = NULL;
275 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
276 seconds = EXTRACT_UINT(pd, offset+0);
277 mseconds = EXTRACT_UINT(pd, offset+4);
280 time_item = proto_tree_add_text(tree, offset, 8,
281 "%s: %u.%06u", name, seconds, mseconds);
283 time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval);
287 proto_tree_add_text(time_tree,offset+0,4,
288 "seconds: %u", seconds);
289 proto_tree_add_text(time_tree,offset+4,4,
290 "micro seconds: %u", mseconds);
297 /* RFC 1094, Page 16 */
298 const value_string nfs2_mode_names[] = {
299 { 0040000, "Directory" },
300 { 0020000, "Character Special Device" },
301 { 0060000, "Block Special Device" },
302 { 0100000, "Regular File" },
303 { 0120000, "Symbolic Link" },
304 { 0140000, "Named Socket" },
309 dissect_mode(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
313 proto_item* mode_item = NULL;
314 proto_tree* mode_tree = NULL;
316 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
317 mode = EXTRACT_UINT(pd, offset+0);
320 mode_item = proto_tree_add_text(tree, offset, 4,
321 "%s: 0%o", name, mode);
323 mode_tree = proto_item_add_subtree(mode_item, ett_nfs_mode);
327 proto_tree_add_text(mode_tree, offset, 4, "%s",
328 decode_enumerated_bitfield(mode, 0160000, 16,
329 nfs2_mode_names, "%s"));
330 proto_tree_add_text(mode_tree, offset, 4, "%s",
331 decode_boolean_bitfield(mode, 04000, 16, "Set user id on exec", "not SUID"));
332 proto_tree_add_text(mode_tree, offset, 4, "%s",
333 decode_boolean_bitfield(mode, 02000, 16, "Set group id on exec", "not SGID"));
334 proto_tree_add_text(mode_tree, offset, 4, "%s",
335 decode_boolean_bitfield(mode, 01000, 16, "Save swapped text even after use", "not save swapped text"));
336 proto_tree_add_text(mode_tree, offset, 4, "%s",
337 decode_boolean_bitfield(mode, 0400, 16, "Read permission for owner", "no Read permission for owner"));
338 proto_tree_add_text(mode_tree, offset, 4, "%s",
339 decode_boolean_bitfield(mode, 0200, 16, "Write permission for owner", "no Write permission for owner"));
340 proto_tree_add_text(mode_tree, offset, 4, "%s",
341 decode_boolean_bitfield(mode, 0100, 16, "Execute permission for owner", "no Execute permission for owner"));
342 proto_tree_add_text(mode_tree, offset, 4, "%s",
343 decode_boolean_bitfield(mode, 040, 16, "Read permission for group", "no Read permission for group"));
344 proto_tree_add_text(mode_tree, offset, 4, "%s",
345 decode_boolean_bitfield(mode, 020, 16, "Write permission for group", "no Write permission for group"));
346 proto_tree_add_text(mode_tree, offset, 4, "%s",
347 decode_boolean_bitfield(mode, 010, 16, "Execute permission for group", "no Execute permission for group"));
348 proto_tree_add_text(mode_tree, offset, 4, "%s",
349 decode_boolean_bitfield(mode, 04, 16, "Read permission for others", "no Read permission for others"));
350 proto_tree_add_text(mode_tree, offset, 4, "%s",
351 decode_boolean_bitfield(mode, 02, 16, "Write permission for others", "no Write permission for others"));
352 proto_tree_add_text(mode_tree, offset, 4, "%s",
353 decode_boolean_bitfield(mode, 01, 16, "Execute permission for others", "no Execute permission for others"));
361 /* RFC 1094, Page 15 */
363 dissect_fattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
365 proto_item* fattr_item = NULL;
366 proto_tree* fattr_tree = NULL;
367 int old_offset = offset;
370 fattr_item = proto_tree_add_text(tree, offset,
371 END_OF_FRAME, "%s", name);
373 fattr_tree = proto_item_add_subtree(fattr_item, ett_nfs_fattr);
376 offset = dissect_ftype (pd,offset,fd,fattr_tree,"type");
377 offset = dissect_mode (pd,offset,fd,fattr_tree,"mode");
378 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"nlink");
379 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"uid");
380 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"gid");
381 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"size");
382 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"blocksize");
383 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"rdev");
384 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"blocks");
385 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"fsid");
386 offset = dissect_unsigned_int (pd,offset,fd,fattr_tree,"fileid");
387 offset = dissect_timeval (pd,offset,fd,fattr_tree,"atime");
388 offset = dissect_timeval (pd,offset,fd,fattr_tree,"mtime");
389 offset = dissect_timeval (pd,offset,fd,fattr_tree,"ctime");
391 /* now we know, that fattr is shorter */
393 proto_item_set_len(fattr_item, offset - old_offset);
400 /* RFC 1094, Page 17 */
402 dissect_sattr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
404 proto_item* sattr_item = NULL;
405 proto_tree* sattr_tree = NULL;
406 int old_offset = offset;
409 sattr_item = proto_tree_add_text(tree, offset,
410 END_OF_FRAME, "%s", name);
412 sattr_tree = proto_item_add_subtree(sattr_item, ett_nfs_sattr);
415 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
416 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
417 offset = dissect_mode (pd,offset,fd,sattr_tree,"mode");
419 proto_tree_add_text(sattr_tree, offset, 4, "mode: no value");
423 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
424 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
425 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"uid");
427 proto_tree_add_text(sattr_tree, offset, 4, "uid: no value");
431 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
432 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
433 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"gid");
435 proto_tree_add_text(sattr_tree, offset, 4, "gid: no value");
439 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
440 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
441 offset = dissect_unsigned_int (pd,offset,fd,sattr_tree,"size");
443 proto_tree_add_text(sattr_tree, offset, 4, "size: no value");
447 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
448 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
449 offset = dissect_timeval (pd,offset,fd,sattr_tree,"atime");
451 proto_tree_add_text(sattr_tree, offset, 8, "atime: no value");
455 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
456 if (EXTRACT_UINT(pd, offset+0) != 0xffffffff)
457 offset = dissect_timeval (pd,offset,fd,sattr_tree,"mtime");
459 proto_tree_add_text(sattr_tree, offset, 8, "mtime: no value");
463 /* now we know, that sattr is shorter */
465 proto_item_set_len(sattr_item, offset - old_offset);
472 /* RFC 1094, Page 17 */
474 dissect_filename(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
476 offset = dissect_rpc_string(pd,offset,fd,tree,hf);
481 /* RFC 1094, Page 17 */
483 dissect_path(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
485 offset = dissect_rpc_string(pd,offset,fd,tree,hf);
490 /* RFC 1094, Page 17,18 */
492 dissect_attrstat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree){
495 offset = dissect_stat(pd, offset, fd, tree, &status);
498 offset = dissect_fattr(pd, offset, fd, tree, "attributes");
509 /* RFC 1094, Page 17,18 */
511 dissect_nfs2_attrstat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
513 offset = dissect_attrstat(pd, offset, fd, tree);
519 /* RFC 1094, Page 18 */
521 dissect_diropargs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
523 proto_item* diropargs_item = NULL;
524 proto_tree* diropargs_tree = NULL;
525 int old_offset = offset;
528 diropargs_item = proto_tree_add_text(tree, offset,
529 END_OF_FRAME, "%s", name);
531 diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs);
534 offset = dissect_fhandle (pd,offset,fd,diropargs_tree,"dir");
535 offset = dissect_filename(pd,offset,fd,diropargs_tree,hf_nfs_name);
537 /* now we know, that diropargs is shorter */
538 if (diropargs_item) {
539 proto_item_set_len(diropargs_item, offset - old_offset);
546 /* RFC 1094, Page 18 */
548 dissect_nfs2_diropargs_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
550 offset = dissect_diropargs(pd, offset, fd, tree, "where");
556 /* RFC 1094, Page 18 */
558 dissect_diropres(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
562 offset = dissect_stat(pd, offset, fd, tree, &status);
565 offset = dissect_fhandle(pd, offset, fd, tree, "file");
566 offset = dissect_fattr (pd, offset, fd, tree, "attributes");
577 /* nfsdata is simply a RPC string (length, data, fill bytes) */
579 dissect_nfsdata(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
582 offset = dissect_rpc_data(pd,offset,fd,tree,hf);
588 /* RFC 1094, Page 18 */
590 dissect_nfs2_diropres_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
592 offset = dissect_diropres(pd, offset, fd, tree);
598 /* RFC 1094, Page 6 */
600 dissect_nfs2_setattr_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
602 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
603 offset = dissect_sattr (pd, offset, fd, tree, "attributes");
609 /* RFC 1094, Page 6 */
611 dissect_nfs2_readlink_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
615 offset = dissect_stat(pd, offset, fd, tree, &status);
618 offset = dissect_path(pd, offset, fd, tree, hf_nfs_readlink_data);
629 /* RFC 1094, Page 7 */
631 dissect_nfs2_read_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
633 guint32 offset_value;
637 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
638 if (!BYTES_ARE_IN_FRAME(offset,12)) return offset;
639 offset_value = EXTRACT_UINT(pd, offset+0);
640 count = EXTRACT_UINT(pd, offset+4);
641 totalcount = EXTRACT_UINT(pd, offset+8);
643 proto_tree_add_item(tree, hf_nfs_read_offset,
644 offset+0, 4, offset_value);
645 proto_tree_add_item(tree, hf_nfs_read_count,
647 proto_tree_add_item(tree, hf_nfs_read_totalcount,
648 offset+8, 4, totalcount);
656 /* RFC 1094, Page 7 */
658 dissect_nfs2_read_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
662 offset = dissect_stat(pd, offset, fd, tree, &status);
665 offset = dissect_fattr(pd, offset, fd, tree, "attributes");
666 offset = dissect_nfsdata(pd, offset, fd, tree, hf_nfs_data);
677 /* RFC 1094, Page 8 */
679 dissect_nfs2_write_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
682 guint32 offset_value;
685 offset = dissect_fhandle(pd, offset, fd, tree, "file" );
686 if (!BYTES_ARE_IN_FRAME(offset,12)) return offset;
687 beginoffset = EXTRACT_UINT(pd, offset+0);
688 offset_value = EXTRACT_UINT(pd, offset+4);
689 totalcount = EXTRACT_UINT(pd, offset+8);
691 proto_tree_add_item(tree, hf_nfs_write_beginoffset,
692 offset+0, 4, beginoffset);
693 proto_tree_add_item(tree, hf_nfs_write_offset,
694 offset+4, 4, offset_value);
695 proto_tree_add_item(tree, hf_nfs_write_totalcount,
696 offset+8, 4, totalcount);
700 offset = dissect_nfsdata(pd, offset, fd, tree, hf_nfs_data);
706 /* RFC 1094, Page 8 */
708 dissect_nfs2_createargs_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
710 offset = dissect_diropargs(pd, offset, fd, tree, "where" );
711 offset = dissect_sattr (pd, offset, fd, tree, "attributes");
717 /* RFC 1094, Page 9 */
719 dissect_nfs2_rename_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
721 offset = dissect_diropargs(pd, offset, fd, tree, "from");
722 offset = dissect_diropargs(pd, offset, fd, tree, "to" );
728 /* RFC 1094, Page 9 */
730 dissect_nfs2_link_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
732 offset = dissect_fhandle (pd, offset, fd, tree, "from");
733 offset = dissect_diropargs(pd, offset, fd, tree, "to" );
739 /* RFC 1094, Page 10 */
741 dissect_nfs2_symlink_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
743 offset = dissect_diropargs(pd, offset, fd, tree, "from" );
744 offset = dissect_path (pd, offset, fd, tree, hf_nfs_symlink_to);
745 offset = dissect_sattr (pd, offset, fd, tree, "attributes" );
751 /* RFC 1094, Page 11 */
753 dissect_nfs2_readdir_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
758 offset = dissect_fhandle (pd, offset, fd, tree, "dir");
759 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
760 cookie = EXTRACT_UINT(pd, offset+ 0);
761 count = EXTRACT_UINT(pd, offset+ 4);
763 proto_tree_add_item(tree, hf_nfs_readdir_cookie,
764 offset+ 0, 4, cookie);
765 proto_tree_add_item(tree, hf_nfs_readdir_count,
766 offset+ 4, 4, count);
774 /* RFC 1094, Page 11 */
776 dissect_readdir_entry(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
778 proto_item* entry_item = NULL;
779 proto_tree* entry_tree = NULL;
780 int old_offset = offset;
785 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry,
786 offset+0, END_OF_FRAME, NULL);
788 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
791 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
792 fileid = EXTRACT_UINT(pd, offset + 0);
794 proto_tree_add_item(entry_tree, hf_nfs_readdir_entry_fileid,
795 offset+0, 4, fileid);
798 offset = dissect_filename(pd, offset, fd, entry_tree, hf_nfs_readdir_entry_name);
800 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
801 cookie = EXTRACT_UINT(pd, offset + 0);
803 proto_tree_add_item(entry_tree, hf_nfs_readdir_entry_cookie,
804 offset+0, 4, cookie);
807 /* now we know, that a readdir entry is shorter */
809 proto_item_set_len(entry_item, offset - old_offset);
815 /* RFC 1094, Page 11 */
817 dissect_nfs2_readdir_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
820 guint32 value_follows;
823 offset = dissect_stat(pd, offset, fd, tree, &status);
827 if (!BYTES_ARE_IN_FRAME(offset,4)) break;
828 value_follows = EXTRACT_UINT(pd, offset+0);
829 proto_tree_add_item(tree,hf_nfs_readdir_value_follows,
830 offset+0, 4, value_follows);
832 if (value_follows == 1) {
833 offset = dissect_readdir_entry(pd, offset, fd, tree);
839 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
840 eof_value = EXTRACT_UINT(pd, offset+0);
842 proto_tree_add_item(tree, hf_nfs_readdir_eof,
843 offset+ 0, 4, eof_value);
855 /* RFC 1094, Page 12 */
857 dissect_nfs2_statfs_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
866 offset = dissect_stat(pd, offset, fd, tree, &status);
869 if (!BYTES_ARE_IN_FRAME(offset,5 * 4)) return offset;
870 tsize = EXTRACT_UINT(pd, offset+ 0);
871 bsize = EXTRACT_UINT(pd, offset+ 4);
872 blocks = EXTRACT_UINT(pd, offset+ 8);
873 bfree = EXTRACT_UINT(pd, offset+12);
874 bavail = EXTRACT_UINT(pd, offset+16);
876 proto_tree_add_item(tree, hf_nfs_statfs_tsize,
877 offset+ 0, 4, tsize);
878 proto_tree_add_item(tree, hf_nfs_statfs_bsize,
879 offset+ 4, 4, bsize);
880 proto_tree_add_item(tree, hf_nfs_statfs_blocks,
881 offset+ 8, 4, blocks);
882 proto_tree_add_item(tree, hf_nfs_statfs_bfree,
883 offset+12, 4, bfree);
884 proto_tree_add_item(tree, hf_nfs_statfs_bavail,
885 offset+16, 4, bavail);
898 /* proc number, "proc name", dissect_request, dissect_reply */
899 /* NULL as function pointer means: take the generic one. */
900 const vsff nfs2_proc[] = {
901 { 0, "NULL", /* OK */
903 { 1, "GETATTR", /* OK */
904 dissect_nfs2_fhandle_call, dissect_nfs2_attrstat_reply },
905 { 2, "SETATTR", /* OK */
906 dissect_nfs2_setattr_call, dissect_nfs2_attrstat_reply },
907 { 3, "ROOT", /* OK */
909 { 4, "LOOKUP", /* OK */
910 dissect_nfs2_diropargs_call, dissect_nfs2_diropres_reply },
911 { 5, "READLINK", /* OK */
912 dissect_nfs2_fhandle_call, dissect_nfs2_readlink_reply },
913 { 6, "READ", /* OK */
914 dissect_nfs2_read_call, dissect_nfs2_read_reply },
915 { 7, "WRITECACHE", /* OK */
917 { 8, "WRITE", /* OK */
918 dissect_nfs2_write_call, dissect_nfs2_attrstat_reply },
919 { 9, "CREATE", /* OK */
920 dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply },
921 { 10, "REMOVE", /* OK */
922 dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply },
923 { 11, "RENAME", /* OK */
924 dissect_nfs2_rename_call, dissect_nfs2_stat_reply },
925 { 12, "LINK", /* OK */
926 dissect_nfs2_link_call, dissect_nfs2_stat_reply },
927 { 13, "SYMLINK", /* OK */
928 dissect_nfs2_symlink_call, dissect_nfs2_stat_reply },
929 { 14, "MKDIR", /* OK */
930 dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply },
931 { 15, "RMDIR", /* OK */
932 dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply },
933 { 16, "READDIR", /* OK */
934 dissect_nfs2_readdir_call, dissect_nfs2_readdir_reply },
935 { 17, "STATFS", /* OK */
936 dissect_nfs2_fhandle_call, dissect_nfs2_statfs_reply },
939 /* end of NFS Version 2 */
942 /***************************/
943 /* NFS Version 3, RFC 1813 */
944 /***************************/
947 /* RFC 1813, Page 15 */
949 dissect_uint64(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
952 offset = dissect_rpc_uint64(pd,offset,fd,tree,name,"uint64");
957 /* RFC 1813, Page 15 */
959 dissect_uint32(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
962 offset = dissect_rpc_uint32(pd,offset,fd,tree,name,"uint32");
967 /* RFC 1813, Page 15 */
969 dissect_filename3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
971 offset = dissect_rpc_string(pd,offset,fd,tree,hf);
976 /* RFC 1813, Page 15 */
978 dissect_nfspath3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int hf)
980 offset = dissect_rpc_string(pd,offset,fd,tree,hf);
985 /* RFC 1813, Page 15 */
987 dissect_fileid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
990 offset = dissect_rpc_uint64(pd,offset,fd,tree,name,"fileid3");
995 /* RFC 1813, Page 16 */
997 dissect_createverf3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
999 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1000 proto_tree_add_text(tree, offset, NFS3_CREATEVERFSIZE,
1001 "Verifier: Opaque Data");
1002 offset += NFS3_CREATEVERFSIZE;
1007 /* RFC 1813, Page 16 */
1009 dissect_writeverf3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1011 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1012 proto_tree_add_text(tree, offset, NFS3_WRITEVERFSIZE,
1013 "Verifier: Opaque Data");
1014 offset += NFS3_WRITEVERFSIZE;
1019 /* RFC 1813, Page 16 */
1021 dissect_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1024 offset = dissect_rpc_uint32(pd,offset,fd,tree,name,"uid3");
1029 /* RFC 1813, Page 16 */
1031 dissect_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1034 offset = dissect_rpc_uint32(pd,offset,fd,tree,name,"gid3");
1039 /* RFC 1813, Page 16 */
1041 dissect_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1044 offset = dissect_rpc_uint64(pd,offset,fd,tree,name,"size3");
1049 /* RFC 1813, Page 16 */
1051 dissect_offset3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1054 offset = dissect_rpc_uint64(pd,offset,fd,tree,name,"offset3");
1059 /* RFC 1813, Page 16 */
1061 dissect_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1065 proto_item* mode3_item = NULL;
1066 proto_tree* mode3_tree = NULL;
1068 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1069 mode3 = EXTRACT_UINT(pd, offset+0);
1072 mode3_item = proto_tree_add_text(tree, offset, 4,
1073 "%s: 0%o", name, mode3);
1075 mode3_tree = proto_item_add_subtree(mode3_item, ett_nfs_mode3);
1078 /* RFC 1813, Page 23 */
1080 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1081 decode_boolean_bitfield(mode3, 0x800, 12, "Set user id on exec", "not SUID"));
1082 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1083 decode_boolean_bitfield(mode3, 0x400, 12, "Set group id on exec", "not SGID"));
1084 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1085 decode_boolean_bitfield(mode3, 0x200, 12, "Save swapped text even after use", "not save swapped text"));
1086 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1087 decode_boolean_bitfield(mode3, 0x100, 12, "Read permission for owner", "no Read permission for owner"));
1088 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1089 decode_boolean_bitfield(mode3, 0x80, 12, "Write permission for owner", "no Write permission for owner"));
1090 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1091 decode_boolean_bitfield(mode3, 0x40, 12, "Execute permission for owner", "no Execute permission for owner"));
1092 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1093 decode_boolean_bitfield(mode3, 0x20, 12, "Read permission for group", "no Read permission for group"));
1094 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1095 decode_boolean_bitfield(mode3, 0x10, 12, "Write permission for group", "no Write permission for group"));
1096 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1097 decode_boolean_bitfield(mode3, 0x8, 12, "Execute permission for group", "no Execute permission for group"));
1098 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1099 decode_boolean_bitfield(mode3, 0x4, 12, "Read permission for others", "no Read permission for others"));
1100 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1101 decode_boolean_bitfield(mode3, 0x2, 12, "Write permission for others", "no Write permission for others"));
1102 proto_tree_add_text(mode3_tree, offset, 4, "%s",
1103 decode_boolean_bitfield(mode3, 0x1, 12, "Execute permission for others", "no Execute permission for others"));
1111 /* RFC 1813, Page 16 */
1113 dissect_count3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1116 offset = dissect_rpc_uint32(pd,offset,fd,tree,name,"count3");
1121 /* RFC 1813, Page 16,17 */
1122 const value_string names_nfs_nfsstat3[] =
1129 { 13, "ERR_ACCES" },
1130 { 17, "ERR_EXIST" },
1132 { 19, "ERR_NODEV" },
1133 { 20, "ERR_NOTDIR" },
1134 { 21, "ERR_ISDIR" },
1135 { 22, "ERR_INVAL" },
1137 { 28, "ERR_NOSPC" },
1139 { 31, "ERR_MLINK" },
1140 { 63, "ERR_NAMETOOLONG" },
1141 { 66, "ERR_NOTEMPTY" },
1142 { 69, "ERR_DQUOT" },
1143 { 70, "ERR_STALE" },
1144 { 71, "ERR_REMOTE" },
1145 { 10001, "ERR_BADHANDLE" },
1146 { 10002, "ERR_NOT_SYNC" },
1147 { 10003, "ERR_BAD_COOKIE" },
1148 { 10004, "ERR_NOTSUPP" },
1149 { 10005, "ERR_TOOSMALL" },
1150 { 10006, "ERR_SERVERFAULT" },
1151 { 10007, "ERR_BADTYPE" },
1152 { 10008, "ERR_JUKEBOX" },
1157 /* RFC 1813, Page 16 */
1159 dissect_nfsstat3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,guint32 *status)
1163 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1164 nfsstat3 = EXTRACT_UINT(pd, offset+0);
1167 proto_tree_add_item(tree, hf_nfs_nfsstat3,
1168 offset, 4, nfsstat3);
1177 /* RFC 1813, Page 17, 18, 19, 20: error explanations */
1180 /* RFC 1813, Page 20 */
1182 dissect_ftype3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
1186 char* ftype3_name = NULL;
1188 const value_string nfs3_ftype3[] =
1190 { 1, "Regular File" },
1192 { 3, "Block Special Device" },
1193 { 4, "Character Special Device" },
1194 { 5, "Symbolic Link" },
1196 { 7, "Named Pipe" },
1200 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1201 ftype3 = EXTRACT_UINT(pd, offset+0);
1202 ftype3_name = val_to_str(ftype3, nfs3_ftype3, "%u");
1205 proto_tree_add_text(tree, offset, 4,
1206 "%s: %s (%u)", name, ftype3_name, ftype3);
1214 /* RFC 1813, Page 20 */
1216 dissect_specdata3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1221 proto_item* specdata3_item;
1222 proto_tree* specdata3_tree = NULL;
1224 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1225 specdata1 = EXTRACT_UINT(pd, offset+0);
1226 specdata2 = EXTRACT_UINT(pd, offset+4);
1229 specdata3_item = proto_tree_add_text(tree, offset, 8,
1230 "%s: %u,%u", name, specdata1, specdata2);
1232 specdata3_tree = proto_item_add_subtree(specdata3_item,
1236 if (specdata3_tree) {
1237 proto_tree_add_text(specdata3_tree,offset+0,4,
1238 "specdata1: %u", specdata1);
1239 proto_tree_add_text(specdata3_tree,offset+4,4,
1240 "specdata2: %u", specdata2);
1248 /* RFC 1813, Page 21 */
1250 dissect_nfs_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1256 proto_tree* ftree = NULL;
1258 fh3_len = EXTRACT_UINT(pd, offset+0);
1259 fh3_len_full = rpc_roundup(fh3_len);
1260 fh3_fill = fh3_len_full - fh3_len;
1263 fitem = proto_tree_add_text(tree, offset, 4+fh3_len_full,
1266 ftree = proto_item_add_subtree(fitem, ett_nfs_fh3);
1270 proto_tree_add_text(ftree,offset+0,4,
1271 "length: %u", fh3_len);
1272 proto_tree_add_text(ftree,offset+4,fh3_len,
1273 "file handle (opaque data)");
1275 proto_tree_add_text(ftree,offset+4+fh3_len,fh3_fill,
1278 offset += 4 + fh3_len_full;
1283 /* RFC 1813, Page 21 */
1285 dissect_nfstime3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,char* name)
1290 proto_item* time_item;
1291 proto_tree* time_tree = NULL;
1293 if (!BYTES_ARE_IN_FRAME(offset,8)) return offset;
1294 seconds = EXTRACT_UINT(pd, offset+0);
1295 nseconds = EXTRACT_UINT(pd, offset+4);
1298 time_item = proto_tree_add_text(tree, offset, 8,
1299 "%s: %u.%09u", name, seconds, nseconds);
1301 time_tree = proto_item_add_subtree(time_item, ett_nfs_nfstime3);
1305 proto_tree_add_text(time_tree,offset+0,4,
1306 "seconds: %u", seconds);
1307 proto_tree_add_text(time_tree,offset+4,4,
1308 "nano seconds: %u", nseconds);
1315 /* RFC 1813, Page 22 */
1317 dissect_fattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1319 proto_item* fattr3_item = NULL;
1320 proto_tree* fattr3_tree = NULL;
1321 int old_offset = offset;
1324 fattr3_item = proto_tree_add_text(tree, offset,
1325 END_OF_FRAME, "%s", name);
1327 fattr3_tree = proto_item_add_subtree(fattr3_item, ett_nfs_fattr3);
1330 offset = dissect_ftype3 (pd,offset,fd,fattr3_tree,"type");
1331 offset = dissect_mode3 (pd,offset,fd,fattr3_tree,"mode");
1332 offset = dissect_uint32 (pd,offset,fd,fattr3_tree,"nlink");
1333 offset = dissect_uid3 (pd,offset,fd,fattr3_tree,"uid");
1334 offset = dissect_gid3 (pd,offset,fd,fattr3_tree,"gid");
1335 offset = dissect_size3 (pd,offset,fd,fattr3_tree,"size");
1336 offset = dissect_size3 (pd,offset,fd,fattr3_tree,"used");
1337 offset = dissect_specdata3(pd,offset,fd,fattr3_tree,"rdev");
1338 offset = dissect_uint64 (pd,offset,fd,fattr3_tree,"fsid");
1339 offset = dissect_fileid3 (pd,offset,fd,fattr3_tree,"fileid");
1340 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"atime");
1341 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"mtime");
1342 offset = dissect_nfstime3 (pd,offset,fd,fattr3_tree,"ctime");
1344 /* now we know, that fattr3 is shorter */
1346 proto_item_set_len(fattr3_item, offset - old_offset);
1353 const value_string value_follows[] =
1356 { 1, "value follows"},
1361 /* RFC 1813, Page 23 */
1363 dissect_post_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1365 proto_item* post_op_attr_item = NULL;
1366 proto_tree* post_op_attr_tree = NULL;
1367 int old_offset = offset;
1368 guint32 attributes_follow;
1371 post_op_attr_item = proto_tree_add_text(tree, offset,
1372 END_OF_FRAME, "%s", name);
1373 if (post_op_attr_item)
1374 post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, ett_nfs_post_op_attr);
1377 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1378 attributes_follow = EXTRACT_UINT(pd, offset+0);
1379 proto_tree_add_text(post_op_attr_tree, offset, 4,
1380 "attributes_follow: %s (%u)",
1381 val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
1383 switch (attributes_follow) {
1385 offset = dissect_fattr3(pd, offset, fd, post_op_attr_tree,
1393 /* now we know, that post_op_attr_tree is shorter */
1394 if (post_op_attr_item) {
1395 proto_item_set_len(post_op_attr_item, offset - old_offset);
1402 /* RFC 1813, Page 24 */
1404 dissect_wcc_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1406 proto_item* wcc_attr_item = NULL;
1407 proto_tree* wcc_attr_tree = NULL;
1408 int old_offset = offset;
1411 wcc_attr_item = proto_tree_add_text(tree, offset,
1412 END_OF_FRAME, "%s", name);
1414 wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, ett_nfs_wcc_attr);
1417 offset = dissect_size3 (pd, offset, fd, wcc_attr_tree, "size" );
1418 offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "mtime");
1419 offset = dissect_nfstime3(pd, offset, fd, wcc_attr_tree, "ctime");
1421 /* now we know, that wcc_attr_tree is shorter */
1422 if (wcc_attr_item) {
1423 proto_item_set_len(wcc_attr_item, offset - old_offset);
1430 /* RFC 1813, Page 24 */
1432 dissect_pre_op_attr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1434 proto_item* pre_op_attr_item = NULL;
1435 proto_tree* pre_op_attr_tree = NULL;
1436 int old_offset = offset;
1437 guint32 attributes_follow;
1440 pre_op_attr_item = proto_tree_add_text(tree, offset,
1441 END_OF_FRAME, "%s", name);
1442 if (pre_op_attr_item)
1443 pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, ett_nfs_pre_op_attr);
1446 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1447 attributes_follow = EXTRACT_UINT(pd, offset+0);
1448 proto_tree_add_text(pre_op_attr_tree, offset, 4,
1449 "attributes_follow: %s (%u)",
1450 val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
1452 switch (attributes_follow) {
1454 offset = dissect_wcc_attr(pd, offset, fd, pre_op_attr_tree,
1462 /* now we know, that pre_op_attr_tree is shorter */
1463 if (pre_op_attr_item) {
1464 proto_item_set_len(pre_op_attr_item, offset - old_offset);
1471 /* RFC 1813, Page 24 */
1473 dissect_wcc_data(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1475 proto_item* wcc_data_item = NULL;
1476 proto_tree* wcc_data_tree = NULL;
1477 int old_offset = offset;
1480 wcc_data_item = proto_tree_add_text(tree, offset,
1481 END_OF_FRAME, "%s", name);
1483 wcc_data_tree = proto_item_add_subtree(wcc_data_item, ett_nfs_wcc_data);
1486 offset = dissect_pre_op_attr (pd, offset, fd, wcc_data_tree, "before");
1487 offset = dissect_post_op_attr(pd, offset, fd, wcc_data_tree, "after" );
1489 /* now we know, that wcc_data is shorter */
1490 if (wcc_data_item) {
1491 proto_item_set_len(wcc_data_item, offset - old_offset);
1498 /* RFC 1813, Page 25 */
1500 dissect_post_op_fh3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1502 proto_item* post_op_fh3_item = NULL;
1503 proto_tree* post_op_fh3_tree = NULL;
1504 int old_offset = offset;
1505 guint32 handle_follows;
1508 post_op_fh3_item = proto_tree_add_text(tree, offset,
1509 END_OF_FRAME, "%s", name);
1510 if (post_op_fh3_item)
1511 post_op_fh3_tree = proto_item_add_subtree(post_op_fh3_item, ett_nfs_post_op_fh3);
1514 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1515 handle_follows = EXTRACT_UINT(pd, offset+0);
1516 proto_tree_add_text(post_op_fh3_tree, offset, 4,
1517 "handle_follows: %s (%u)",
1518 val_to_str(handle_follows,value_follows,"Unknown"), handle_follows);
1520 switch (handle_follows) {
1522 offset = dissect_nfs_fh3(pd, offset, fd, post_op_fh3_tree,
1530 /* now we know, that post_op_fh3_tree is shorter */
1531 if (post_op_fh3_item) {
1532 proto_item_set_len(post_op_fh3_item, offset - old_offset);
1539 /* RFC 1813, Page 25 */
1541 dissect_set_mode3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1543 proto_item* set_mode3_item = NULL;
1544 proto_tree* set_mode3_tree = NULL;
1545 int old_offset = offset;
1549 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1550 set_it = EXTRACT_UINT(pd, offset+0);
1551 set_it_name = val_to_str(set_it,value_follows,"Unknown");
1554 set_mode3_item = proto_tree_add_text(tree, offset,
1555 END_OF_FRAME, "%s: %s", name, set_it_name);
1557 set_mode3_tree = proto_item_add_subtree(set_mode3_item, ett_nfs_set_mode3);
1561 proto_tree_add_text(set_mode3_tree, offset, 4,
1562 "set_it: %s (%u)", set_it_name, set_it);
1568 offset = dissect_mode3(pd, offset, fd, set_mode3_tree,
1576 /* now we know, that set_mode3 is shorter */
1577 if (set_mode3_item) {
1578 proto_item_set_len(set_mode3_item, offset - old_offset);
1585 /* RFC 1813, Page 26 */
1587 dissect_set_uid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1589 proto_item* set_uid3_item = NULL;
1590 proto_tree* set_uid3_tree = NULL;
1591 int old_offset = offset;
1595 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1596 set_it = EXTRACT_UINT(pd, offset+0);
1597 set_it_name = val_to_str(set_it,value_follows,"Unknown");
1600 set_uid3_item = proto_tree_add_text(tree, offset,
1601 END_OF_FRAME, "%s: %s", name, set_it_name);
1603 set_uid3_tree = proto_item_add_subtree(set_uid3_item, ett_nfs_set_uid3);
1607 proto_tree_add_text(set_uid3_tree, offset, 4,
1608 "set_it: %s (%u)", set_it_name, set_it);
1614 offset = dissect_uid3(pd, offset, fd, set_uid3_tree,
1622 /* now we know, that set_uid3 is shorter */
1623 if (set_uid3_item) {
1624 proto_item_set_len(set_uid3_item, offset - old_offset);
1631 /* RFC 1813, Page 26 */
1633 dissect_set_gid3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1635 proto_item* set_gid3_item = NULL;
1636 proto_tree* set_gid3_tree = NULL;
1637 int old_offset = offset;
1641 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1642 set_it = EXTRACT_UINT(pd, offset+0);
1643 set_it_name = val_to_str(set_it,value_follows,"Unknown");
1646 set_gid3_item = proto_tree_add_text(tree, offset,
1647 END_OF_FRAME, "%s: %s", name, set_it_name);
1649 set_gid3_tree = proto_item_add_subtree(set_gid3_item, ett_nfs_set_gid3);
1653 proto_tree_add_text(set_gid3_tree, offset, 4,
1654 "set_it: %s (%u)", set_it_name, set_it);
1660 offset = dissect_gid3(pd, offset, fd, set_gid3_tree,
1668 /* now we know, that set_gid3 is shorter */
1669 if (set_gid3_item) {
1670 proto_item_set_len(set_gid3_item, offset - old_offset);
1677 /* RFC 1813, Page 26 */
1679 dissect_set_size3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1681 proto_item* set_size3_item = NULL;
1682 proto_tree* set_size3_tree = NULL;
1683 int old_offset = offset;
1687 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1688 set_it = EXTRACT_UINT(pd, offset+0);
1689 set_it_name = val_to_str(set_it,value_follows,"Unknown");
1692 set_size3_item = proto_tree_add_text(tree, offset,
1693 END_OF_FRAME, "%s: %s", name, set_it_name);
1695 set_size3_tree = proto_item_add_subtree(set_size3_item, ett_nfs_set_size3);
1699 proto_tree_add_text(set_size3_tree, offset, 4,
1700 "set_it: %s (%u)", set_it_name, set_it);
1706 offset = dissect_size3(pd, offset, fd, set_size3_tree,
1714 /* now we know, that set_size3 is shorter */
1715 if (set_size3_item) {
1716 proto_item_set_len(set_size3_item, offset - old_offset);
1723 /* RFC 1813, Page 25 */
1724 #define DONT_CHANGE 0
1725 #define SET_TO_SERVER_TIME 1
1726 #define SET_TO_CLIENT_TIME 2
1728 const value_string time_how[] =
1730 { DONT_CHANGE, "don't change" },
1731 { SET_TO_SERVER_TIME, "set to server time" },
1732 { SET_TO_CLIENT_TIME, "set to client time" },
1737 /* RFC 1813, Page 26 */
1739 dissect_set_atime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1741 proto_item* set_atime_item = NULL;
1742 proto_tree* set_atime_tree = NULL;
1743 int old_offset = offset;
1747 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1748 set_it = EXTRACT_UINT(pd, offset+0);
1749 set_it_name = val_to_str(set_it,time_how,"Unknown");
1752 set_atime_item = proto_tree_add_text(tree, offset,
1753 END_OF_FRAME, "%s: %s",
1754 name, set_it_name, set_it);
1756 set_atime_tree = proto_item_add_subtree(set_atime_item, ett_nfs_set_atime);
1760 proto_tree_add_text(set_atime_tree, offset, 4,
1761 "set_it: %s (%u)", set_it_name, set_it);
1766 case SET_TO_CLIENT_TIME:
1768 offset = dissect_nfstime3(pd, offset, fd, set_atime_tree,
1776 /* now we know, that set_atime is shorter */
1777 if (set_atime_item) {
1778 proto_item_set_len(set_atime_item, offset - old_offset);
1785 /* RFC 1813, Page 26 */
1787 dissect_set_mtime(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1789 proto_item* set_mtime_item = NULL;
1790 proto_tree* set_mtime_tree = NULL;
1791 int old_offset = offset;
1795 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1796 set_it = EXTRACT_UINT(pd, offset+0);
1797 set_it_name = val_to_str(set_it,time_how,"Unknown");
1800 set_mtime_item = proto_tree_add_text(tree, offset,
1801 END_OF_FRAME, "%s: %s",
1802 name, set_it_name, set_it);
1804 set_mtime_tree = proto_item_add_subtree(set_mtime_item, ett_nfs_set_mtime);
1808 proto_tree_add_text(set_mtime_tree, offset, 4,
1809 "set_it: %s (%u)", set_it_name, set_it);
1814 case SET_TO_CLIENT_TIME:
1816 offset = dissect_nfstime3(pd, offset, fd, set_mtime_tree,
1824 /* now we know, that set_mtime is shorter */
1825 if (set_mtime_item) {
1826 proto_item_set_len(set_mtime_item, offset - old_offset);
1833 /* RFC 1813, Page 25..27 */
1835 dissect_sattr3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1837 proto_item* sattr3_item = NULL;
1838 proto_tree* sattr3_tree = NULL;
1839 int old_offset = offset;
1842 sattr3_item = proto_tree_add_text(tree, offset,
1843 END_OF_FRAME, "%s", name);
1845 sattr3_tree = proto_item_add_subtree(sattr3_item, ett_nfs_sattr3);
1848 offset = dissect_set_mode3(pd, offset, fd, sattr3_tree, "mode");
1849 offset = dissect_set_uid3 (pd, offset, fd, sattr3_tree, "uid");
1850 offset = dissect_set_gid3 (pd, offset, fd, sattr3_tree, "gid");
1851 offset = dissect_set_size3(pd, offset, fd, sattr3_tree, "size");
1852 offset = dissect_set_atime(pd, offset, fd, sattr3_tree, "atime");
1853 offset = dissect_set_mtime(pd, offset, fd, sattr3_tree, "mtime");
1855 /* now we know, that sattr3 is shorter */
1857 proto_item_set_len(sattr3_item, offset - old_offset);
1864 /* RFC 1813, Page 27 */
1866 dissect_diropargs3(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1868 proto_item* diropargs3_item = NULL;
1869 proto_tree* diropargs3_tree = NULL;
1870 int old_offset = offset;
1873 diropargs3_item = proto_tree_add_text(tree, offset,
1874 END_OF_FRAME, "%s", name);
1875 if (diropargs3_item)
1876 diropargs3_tree = proto_item_add_subtree(diropargs3_item, ett_nfs_diropargs3);
1879 offset = dissect_nfs_fh3 (pd, offset, fd, diropargs3_tree, "dir");
1880 offset = dissect_filename3(pd, offset, fd, diropargs3_tree, hf_nfs_name);
1882 /* now we know, that diropargs3 is shorter */
1883 if (diropargs3_item) {
1884 proto_item_set_len(diropargs3_item, offset - old_offset);
1891 /* RFC 1813, Page 27 */
1893 dissect_nfs3_diropargs3_call(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1895 offset = dissect_diropargs3(pd, offset, fd, tree, "object");
1901 /* RFC 1813, Page 40 */
1903 dissect_access(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, char* name)
1906 proto_item* access_item = NULL;
1907 proto_tree* access_tree = NULL;
1909 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
1910 access = EXTRACT_UINT(pd, offset+0);
1913 access_item = proto_tree_add_text(tree, offset, 4,
1914 "%s: 0x%02x", name, access);
1916 access_tree = proto_item_add_subtree(access_item, ett_nfs_access);
1920 proto_tree_add_text(access_tree, offset, 4, "%s READ",
1921 decode_boolean_bitfield(access, 0x001, 6, "allow", "not allow"));
1922 proto_tree_add_text(access_tree, offset, 4, "%s LOOKUP",
1923 decode_boolean_bitfield(access, 0x002, 6, "allow", "not allow"));
1924 proto_tree_add_text(access_tree, offset, 4, "%s MODIFY",
1925 decode_boolean_bitfield(access, 0x004, 6, "allowed", "not allow"));
1926 proto_tree_add_text(access_tree, offset, 4, "%s EXTEND",
1927 decode_boolean_bitfield(access, 0x008, 6, "allow", "not allow"));
1928 proto_tree_add_text(access_tree, offset, 4, "%s DELETE",
1929 decode_boolean_bitfield(access, 0x010, 6, "allow", "not allow"));
1930 proto_tree_add_text(access_tree, offset, 4, "%s EXECUTE",
1931 decode_boolean_bitfield(access, 0x020, 6, "allow", "not allow"));
1939 /* NFS3 file handle dissector */
1941 dissect_nfs3_nfs_fh3_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1943 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
1948 /* generic NFS3 reply dissector */
1950 dissect_nfs3_any_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1954 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
1961 /* RFC 1813, Page 32,33 */
1963 dissect_nfs3_getattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1965 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
1970 /* RFC 1813, Page 32,33 */
1972 dissect_nfs3_getattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
1976 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
1979 offset = dissect_fattr3(pd, offset, fd, tree, "obj_attributes");
1990 /* RFC 1813, Page 33 */
1992 dissect_sattrguard3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, char *name)
1994 proto_item* sattrguard3_item = NULL;
1995 proto_tree* sattrguard3_tree = NULL;
1996 int old_offset = offset;
2000 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2001 check = EXTRACT_UINT(pd, offset+0);
2002 check_name = val_to_str(check,value_follows,"Unknown");
2005 sattrguard3_item = proto_tree_add_text(tree, offset,
2006 END_OF_FRAME, "%s: %s", name, check_name);
2007 if (sattrguard3_item)
2008 sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, ett_nfs_sattrguard3);
2011 if (sattrguard3_tree)
2012 proto_tree_add_text(sattrguard3_tree, offset, 4,
2013 "check: %s (%u)", check_name, check);
2019 offset = dissect_nfstime3(pd, offset, fd, sattrguard3_tree,
2027 /* now we know, that sattrguard3 is shorter */
2028 if (sattrguard3_item) {
2029 proto_item_set_len(sattrguard3_item, offset - old_offset);
2036 /* RFC 1813, Page 33..36 */
2038 dissect_nfs3_setattr_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2040 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object");
2041 offset = dissect_sattr3 (pd, offset, fd, tree, "new_attributes");
2042 offset = dissect_sattrguard3(pd, offset, fd, tree, "guard");
2047 /* RFC 1813, Page 33..36 */
2049 dissect_nfs3_setattr_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2053 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2056 offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc");
2059 offset = dissect_wcc_data(pd, offset, fd, tree, "obj_wcc");
2067 /* RFC 1813, Page 37..39 */
2069 dissect_nfs3_lookup_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2071 offset = dissect_diropargs3 (pd, offset, fd, tree, "what");
2076 /* RFC 1813, Page 37..39 */
2078 dissect_nfs3_lookup_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2082 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2085 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "object");
2086 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2087 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2090 offset = dissect_post_op_attr(pd, offset, fd, tree, "dir_attributes");
2098 /* RFC 1813, Page 40..43 */
2100 dissect_nfs3_access_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2102 offset = dissect_nfs_fh3(pd, offset, fd, tree, "object");
2103 offset = dissect_access (pd, offset, fd, tree, "access");
2109 /* RFC 1813, Page 40..43 */
2111 dissect_nfs3_access_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2115 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2118 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2119 offset = dissect_access (pd, offset, fd, tree, "access");
2122 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2130 /* RFC 1813, Page 44,45 */
2132 dissect_nfs3_readlink_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2136 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2139 offset = dissect_post_op_attr(pd, offset, fd, tree, "symlink_attributes");
2140 offset = dissect_nfspath3 (pd, offset, fd, tree, hf_nfs_readlink_data);
2143 offset = dissect_post_op_attr(pd, offset, fd, tree, "symlink_attributes");
2151 /* RFC 1813, Page 46..48 */
2153 dissect_nfs3_read_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2155 offset = dissect_nfs_fh3(pd, offset, fd, tree, "file");
2156 offset = dissect_offset3(pd, offset, fd, tree, "offset");
2157 offset = dissect_count3 (pd, offset, fd, tree, "count");
2163 /* RFC 1813, Page 46..48 */
2165 dissect_nfs3_read_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2169 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2172 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2173 offset = dissect_count3 (pd, offset, fd, tree, "count");
2174 offset = dissect_rpc_bool (pd, offset, fd, tree, hf_nfs_read_eof);
2175 offset = dissect_nfsdata (pd, offset, fd, tree, hf_nfs_data);
2178 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2186 /* RFC 1813, Page 49 */
2187 static const value_string names_stable_how[] = {
2188 { UNSTABLE, "UNSTABLE" },
2189 { DATA_SYNC, "DATA_SYNC" },
2190 { FILE_SYNC, "FILE_SYNC" },
2195 /* RFC 1813, Page 49 */
2197 dissect_stable_how(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, int hfindex)
2201 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2202 stable_how = EXTRACT_UINT(pd,offset+0);
2204 proto_tree_add_item(tree, hfindex,
2205 offset, 4, stable_how);
2213 /* RFC 1813, Page 49..54 */
2215 dissect_nfs3_write_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2217 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "file");
2218 offset = dissect_offset3 (pd, offset, fd, tree, "offset");
2219 offset = dissect_count3 (pd, offset, fd, tree, "count");
2220 offset = dissect_stable_how(pd, offset, fd, tree, hf_nfs_write_stable);
2221 offset = dissect_nfsdata (pd, offset, fd, tree, hf_nfs_data);
2227 /* RFC 1813, Page 49..54 */
2229 dissect_nfs3_write_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2233 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2236 offset = dissect_wcc_data (pd, offset, fd, tree, "file_wcc");
2237 offset = dissect_count3 (pd, offset, fd, tree, "count");
2238 offset = dissect_stable_how(pd, offset, fd, tree, hf_nfs_write_committed);
2239 offset = dissect_writeverf3(pd, offset, fd, tree);
2242 offset = dissect_wcc_data(pd, offset, fd, tree, "file_wcc");
2250 /* RFC 1813, Page 54 */
2251 static const value_string names_createmode3[] = {
2252 { UNCHECKED, "UNCHECKED" },
2253 { GUARDED, "GUARDED" },
2254 { EXCLUSIVE, "EXCLUSIVE" },
2259 /* RFC 1813, Page 54 */
2261 dissect_createmode3(const u_char* pd, int offset, frame_data* fd, proto_tree* tree, guint32* mode)
2265 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
2266 mode_value = EXTRACT_UINT(pd, offset + 0);
2268 proto_tree_add_item(tree, hf_nfs_createmode3,
2269 offset+0, 4, mode_value);
2278 /* RFC 1813, Page 54..58 */
2280 dissect_nfs3_create_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2284 offset = dissect_diropargs3 (pd, offset, fd, tree, "where");
2285 offset = dissect_createmode3(pd, offset, fd, tree, &mode);
2289 offset = dissect_sattr3 (pd, offset, fd, tree, "obj_attributes");
2292 offset = dissect_createverf3(pd, offset, fd, tree);
2300 /* RFC 1813, Page 54..58 */
2302 dissect_nfs3_create_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2306 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2309 offset = dissect_post_op_fh3 (pd, offset, fd, tree, "obj");
2310 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2311 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2314 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2322 /* RFC 1813, Page 58..60 */
2324 dissect_nfs3_mkdir_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2326 offset = dissect_diropargs3(pd, offset, fd, tree, "where");
2327 offset = dissect_sattr3 (pd, offset, fd, tree, "attributes");
2333 /* RFC 1813, Page 61..63 */
2335 dissect_nfs3_symlink_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2337 offset = dissect_diropargs3(pd, offset, fd, tree, "where");
2338 offset = dissect_sattr3 (pd, offset, fd, tree, "symlink_attributes");
2339 offset = dissect_nfspath3 (pd, offset, fd, tree, hf_nfs_symlink_to);
2345 /* RFC 1813, Page 67..69 */
2347 dissect_nfs3_remove_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2351 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2354 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2357 offset = dissect_wcc_data (pd, offset, fd, tree, "dir_wcc");
2365 /* RFC 1813, Page 71..74 */
2367 dissect_nfs3_rename_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2369 offset = dissect_diropargs3(pd, offset, fd, tree, "from");
2370 offset = dissect_diropargs3(pd, offset, fd, tree, "to");
2376 /* RFC 1813, Page 71..74 */
2378 dissect_nfs3_rename_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2382 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2385 offset = dissect_wcc_data(pd, offset, fd, tree, "fromdir_wcc");
2386 offset = dissect_wcc_data(pd, offset, fd, tree, "todir_wcc");
2389 offset = dissect_wcc_data(pd, offset, fd, tree, "fromdir_wcc");
2390 offset = dissect_wcc_data(pd, offset, fd, tree, "todir_wcc");
2398 /* RFC 1813, Page 74..76 */
2400 dissect_nfs3_link_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2402 offset = dissect_nfs_fh3 (pd, offset, fd, tree, "file");
2403 offset = dissect_diropargs3(pd, offset, fd, tree, "link");
2409 /* RFC 1813, Page 74..76 */
2411 dissect_nfs3_link_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2415 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2418 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2419 offset = dissect_wcc_data (pd, offset, fd, tree, "linkdir_wcc");
2422 offset = dissect_post_op_attr(pd, offset, fd, tree, "file_attributes");
2423 offset = dissect_wcc_data (pd, offset, fd, tree, "linkdir_wcc");
2431 /* RFC 1813, Page 84..86 */
2433 dissect_nfs3_fsstat_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2438 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2441 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2442 offset = dissect_size3 (pd, offset, fd, tree, "tbytes");
2443 offset = dissect_size3 (pd, offset, fd, tree, "fbytes");
2444 offset = dissect_size3 (pd, offset, fd, tree, "abytes");
2445 offset = dissect_size3 (pd, offset, fd, tree, "tfiles");
2446 offset = dissect_size3 (pd, offset, fd, tree, "ffiles");
2447 offset = dissect_size3 (pd, offset, fd, tree, "afiles");
2448 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
2449 invarsec = EXTRACT_UINT(pd, offset + 0);
2451 proto_tree_add_item(tree, hf_nfs_fsstat_invarsec,
2452 offset+0, 4, invarsec);
2456 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2464 #define FSF3_LINK 0x0001
2465 #define FSF3_SYMLINK 0x0002
2466 #define FSF3_HOMOGENEOUS 0x0008
2467 #define FSF3_CANSETTIME 0x0010
2470 /* RFC 1813, Page 86..90 */
2472 dissect_nfs3_fsinfo_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2483 proto_item* properties_item = NULL;
2484 proto_tree* properties_tree = NULL;
2486 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2489 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2490 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2491 rtmax = EXTRACT_UINT(pd, offset+0);
2493 proto_tree_add_item(tree, hf_nfs_fsinfo_rtmax,
2494 offset+0, 4, rtmax);
2496 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2497 rtpref = EXTRACT_UINT(pd, offset+0);
2499 proto_tree_add_item(tree, hf_nfs_fsinfo_rtpref,
2500 offset+0, 4, rtpref);
2502 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2503 rtmult = EXTRACT_UINT(pd, offset+0);
2505 proto_tree_add_item(tree, hf_nfs_fsinfo_rtmult,
2506 offset+0, 4, rtmult);
2508 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2509 wtmax = EXTRACT_UINT(pd, offset+0);
2511 proto_tree_add_item(tree, hf_nfs_fsinfo_wtmax,
2512 offset+0, 4, wtmax);
2514 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2515 wtpref = EXTRACT_UINT(pd, offset+0);
2517 proto_tree_add_item(tree, hf_nfs_fsinfo_wtpref,
2518 offset+0, 4, wtpref);
2520 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2521 wtmult = EXTRACT_UINT(pd, offset+0);
2523 proto_tree_add_item(tree, hf_nfs_fsinfo_wtmult,
2524 offset+0, 4, wtmult);
2526 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2527 dtpref = EXTRACT_UINT(pd, offset+0);
2529 proto_tree_add_item(tree, hf_nfs_fsinfo_dtpref,
2530 offset+0, 4, dtpref);
2533 offset = dissect_size3 (pd, offset, fd, tree, "maxfilesize");
2534 offset = dissect_nfstime3(pd, offset, fd, tree, "time_delta");
2535 if (!BYTES_ARE_IN_FRAME(offset,4)) return offset;
2536 properties = EXTRACT_UINT(pd, offset+0);
2538 properties_item = proto_tree_add_item(tree,
2539 hf_nfs_fsinfo_properties,
2540 offset+0, 4, properties);
2541 if (properties_item)
2542 properties_tree = proto_item_add_subtree(properties_item, ett_nfs_fsinfo_properties);
2543 if (properties_tree) {
2544 proto_tree_add_text(properties_tree,
2546 decode_boolean_bitfield(properties,
2548 "SETATTR can set time on server",
2549 "SETATTR can't set time on server"));
2551 proto_tree_add_text(properties_tree,
2553 decode_boolean_bitfield(properties,
2555 "PATHCONF is valid for all files",
2556 "PATHCONF should be get for every single file"));
2558 proto_tree_add_text(properties_tree,
2560 decode_boolean_bitfield(properties,
2562 "File System supports symbolic links",
2563 "File System does not symbolic hard links"));
2565 proto_tree_add_text(properties_tree,
2567 decode_boolean_bitfield(properties,
2569 "File System supports hard links",
2570 "File System does not support hard links"));
2576 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2584 /* RFC 1813, Page 90..92 */
2586 dissect_nfs3_pathconf_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
2592 offset = dissect_nfsstat3(pd, offset, fd, tree, &status);
2595 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2596 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
2597 linkmax = EXTRACT_UINT(pd, offset + 0);
2599 proto_tree_add_item(tree, hf_nfs_pathconf_linkmax,
2600 offset+0, 4, linkmax);
2602 if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
2603 name_max = EXTRACT_UINT(pd, offset + 0);
2605 proto_tree_add_item(tree, hf_nfs_pathconf_name_max,
2606 offset+0, 4, name_max);
2608 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_no_trunc);
2609 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_chown_restricted);
2610 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_case_insensitive);
2611 offset = dissect_rpc_bool(pd, offset, fd, tree, hf_nfs_pathconf_case_preserving);
2614 offset = dissect_post_op_attr(pd, offset, fd, tree, "obj_attributes");
2622 /* 7 missing functions */
2625 /* proc number, "proc name", dissect_request, dissect_reply */
2626 /* NULL as function pointer means: take the generic one. */
2627 const vsff nfs3_proc[] = {
2628 { 0, "NULL", /* OK */
2630 { 1, "GETATTR", /* OK */
2631 dissect_nfs3_getattr_call, dissect_nfs3_getattr_reply },
2632 { 2, "SETATTR", /* OK */
2633 dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply },
2634 { 3, "LOOKUP", /* OK */
2635 dissect_nfs3_lookup_call, dissect_nfs3_lookup_reply },
2636 { 4, "ACCESS", /* OK */
2637 dissect_nfs3_access_call, dissect_nfs3_access_reply },
2638 { 5, "READLINK", /* OK */
2639 dissect_nfs3_nfs_fh3_call, dissect_nfs3_readlink_reply },
2640 { 6, "READ", /* OK */
2641 dissect_nfs3_read_call, dissect_nfs3_read_reply },
2642 { 7, "WRITE", /* OK */
2643 dissect_nfs3_write_call, dissect_nfs3_write_reply },
2644 { 8, "CREATE", /* OK */
2645 dissect_nfs3_create_call, dissect_nfs3_create_reply },
2646 { 9, "MKDIR", /* OK */
2647 dissect_nfs3_mkdir_call, dissect_nfs3_create_reply },
2648 { 10, "SYMLINK", /* OK */
2649 dissect_nfs3_symlink_call, dissect_nfs3_create_reply },
2650 { 11, "MKNOD", /* todo: call */
2651 dissect_nfs3_nfs_fh3_call, dissect_nfs3_create_reply },
2652 { 12, "REMOVE", /* OK */
2653 dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply },
2654 { 13, "RMDIR", /* OK */
2655 dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply },
2656 { 14, "RENAME", /* OK */
2657 dissect_nfs3_rename_call, dissect_nfs3_rename_reply },
2658 { 15, "LINK", /* OK */
2659 dissect_nfs3_link_call, dissect_nfs3_link_reply },
2660 { 16, "READDIR", /* todo: call, reply */
2661 dissect_nfs3_nfs_fh3_call, dissect_nfs3_any_reply },
2662 { 17, "READDIRPLUS", /* todo: call, reply */
2663 dissect_nfs3_nfs_fh3_call, dissect_nfs3_any_reply },
2664 { 18, "FSSTAT", /* OK */
2665 dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsstat_reply },
2666 { 19, "FSINFO", /* OK */
2667 dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsinfo_reply },
2668 { 20, "PATHCONF", /* OK */
2669 dissect_nfs3_nfs_fh3_call, dissect_nfs3_pathconf_reply },
2670 { 21, "COMMIT", /* todo: call, reply */
2671 dissect_nfs3_nfs_fh3_call, dissect_nfs3_any_reply },
2672 { 0,NULL,NULL,NULL }
2674 /* end of NFS Version 3 */
2677 static struct true_false_string yesno = { "Yes", "No" };
2681 proto_register_nfs(void)
2683 static hf_register_info hf[] = {
2685 "Status", "nfs.status2", FT_UINT32, BASE_DEC,
2686 VALS(names_nfs_stat), 0, "Reply status" }},
2688 "Name", "nfs.name", FT_STRING, BASE_DEC,
2690 { &hf_nfs_readlink_data, {
2691 "Data", "nfs.readlink.data", FT_STRING, BASE_DEC,
2692 NULL, 0, "Symbolic Link Data" }},
2693 { &hf_nfs_read_offset, {
2694 "Offset", "nfs.read.offset", FT_UINT32, BASE_DEC,
2695 NULL, 0, "Read Offset" }},
2696 { &hf_nfs_read_count, {
2697 "Count", "nfs.read.count", FT_UINT32, BASE_DEC,
2698 NULL, 0, "Read Count" }},
2699 { &hf_nfs_read_totalcount, {
2700 "Total Count", "nfs.read.totalcount", FT_UINT32, BASE_DEC,
2701 NULL, 0, "Total Count (obsolete)" }},
2703 "Data", "nfs.data", FT_STRING, BASE_DEC,
2705 { &hf_nfs_write_beginoffset, {
2706 "Begin Offset", "nfs.write.beginoffset", FT_UINT32, BASE_DEC,
2707 NULL, 0, "Begin offset (obsolete)" }},
2708 { &hf_nfs_write_offset, {
2709 "Offset", "nfs.write.offset", FT_UINT32, BASE_DEC,
2710 NULL, 0, "Offset" }},
2711 { &hf_nfs_write_totalcount, {
2712 "Total Count", "nfs.write.totalcount", FT_UINT32, BASE_DEC,
2713 NULL, 0, "Total Count (obsolete)" }},
2714 { &hf_nfs_symlink_to, {
2715 "To", "nfs.symlink.to", FT_STRING, BASE_DEC,
2716 NULL, 0, "Symbolic link destination name" }},
2717 { &hf_nfs_readdir_cookie, {
2718 "Cookie", "nfs.readdir.cookie", FT_UINT32, BASE_DEC,
2719 NULL, 0, "Directory Cookie" }},
2720 { &hf_nfs_readdir_count, {
2721 "Count", "nfs.readdir.count", FT_UINT32, BASE_DEC,
2722 NULL, 0, "Directory Count" }},
2723 { &hf_nfs_readdir_value_follows, {
2724 "Value Follows", "nfs.readdir.value_follows", FT_BOOLEAN, BASE_NONE,
2725 &yesno, 0, "Value Follows" }},
2726 { &hf_nfs_readdir_entry, {
2727 "Entry", "nfs.readdir.entry", FT_NONE, 0,
2728 NULL, 0, "Directory Entry" }},
2729 { &hf_nfs_readdir_entry_fileid, {
2730 "File ID", "nfs.readdir.entry.fileid", FT_UINT32, BASE_DEC,
2731 NULL, 0, "File ID" }},
2732 { &hf_nfs_readdir_entry_name, {
2733 "Name", "nfs.readdir.entry.name", FT_STRING, BASE_DEC,
2735 { &hf_nfs_readdir_entry_cookie, {
2736 "Cookie", "nfs.readdir.entry.cookie", FT_UINT32, BASE_DEC,
2737 NULL, 0, "Directory Cookie" }},
2738 { &hf_nfs_readdir_eof, {
2739 "EOF", "nfs.readdir.eof", FT_UINT32, BASE_DEC,
2741 { &hf_nfs_statfs_tsize, {
2742 "Transfer Size", "nfs.statfs.tsize", FT_UINT32, BASE_DEC,
2743 NULL, 0, "Transfer Size" }},
2744 { &hf_nfs_statfs_bsize, {
2745 "Block Size", "nfs.statfs.bsize", FT_UINT32, BASE_DEC,
2746 NULL, 0, "Block Size" }},
2747 { &hf_nfs_statfs_blocks, {
2748 "Total Blocks", "nfs.statfs.blocks", FT_UINT32, BASE_DEC,
2749 NULL, 0, "Total Blocks" }},
2750 { &hf_nfs_statfs_bfree, {
2751 "Free Blocks", "nfs.statfs.bfree", FT_UINT32, BASE_DEC,
2752 NULL, 0, "Free Blocks" }},
2753 { &hf_nfs_statfs_bavail, {
2754 "Available Blocks", "nfs.statfs.bavail", FT_UINT32, BASE_DEC,
2755 NULL, 0, "Available Blocks" }},
2756 { &hf_nfs_nfsstat3, {
2757 "Status", "nfs.status", FT_UINT32, BASE_DEC,
2758 VALS(names_nfs_nfsstat3), 0, "Reply status" }},
2759 { &hf_nfs_read_eof, {
2760 "EOF", "nfs.read.eof", FT_BOOLEAN, BASE_NONE,
2761 &yesno, 0, "EOF" }},
2762 { &hf_nfs_write_stable, {
2763 "Stable", "nfs.write.stable", FT_UINT32, BASE_DEC,
2764 VALS(names_stable_how), 0, "Stable" }},
2765 { &hf_nfs_write_committed, {
2766 "Committed", "nfs.write.committed", FT_UINT32, BASE_DEC,
2767 VALS(names_stable_how), 0, "Committed" }},
2768 { &hf_nfs_createmode3, {
2769 "Create Mode", "nfs.createmode", FT_UINT32, BASE_DEC,
2770 VALS(names_createmode3), 0, "Create Mode" }},
2771 { &hf_nfs_fsstat_invarsec, {
2772 "invarsec", "nfs.fsstat.invarsec", FT_UINT32, BASE_DEC,
2773 NULL, 0, "probable number of seconds of file system invariance" }},
2774 { &hf_nfs_fsinfo_rtmax, {
2775 "rtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC,
2776 NULL, 0, "maximum READ request" }},
2777 { &hf_nfs_fsinfo_rtpref, {
2778 "rtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC,
2779 NULL, 0, "preferred READ request" }},
2780 { &hf_nfs_fsinfo_rtmult, {
2781 "rtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC,
2782 NULL, 0, "suggested READ multiple" }},
2783 { &hf_nfs_fsinfo_wtmax, {
2784 "wtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC,
2785 NULL, 0, "maximum WRITE request" }},
2786 { &hf_nfs_fsinfo_wtpref, {
2787 "wtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC,
2788 NULL, 0, "preferred WRITE request" }},
2789 { &hf_nfs_fsinfo_wtmult, {
2790 "wtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC,
2791 NULL, 0, "suggested WRITE multiple" }},
2792 { &hf_nfs_fsinfo_dtpref, {
2793 "dtpref", "nfs.fsinfo.dtpref", FT_UINT32, BASE_DEC,
2794 NULL, 0, "preferred READDIR request" }},
2795 { &hf_nfs_fsinfo_properties, {
2796 "Properties", "nfs.fsinfo.propeties", FT_UINT32, BASE_HEX,
2797 NULL, 0, "File System Properties" }},
2798 { &hf_nfs_pathconf_linkmax, {
2799 "linkmax", "nfs.pathconf.linkmax", FT_UINT32, BASE_DEC,
2800 NULL, 0, "Maximum number of hard links" }},
2801 { &hf_nfs_pathconf_name_max, {
2802 "name_max", "nfs.pathconf.name_max", FT_UINT32, BASE_DEC,
2803 NULL, 0, "Maximum file name length" }},
2804 { &hf_nfs_pathconf_no_trunc, {
2805 "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE,
2806 &yesno, 0, "No long file name truncation" }},
2807 { &hf_nfs_pathconf_chown_restricted, {
2808 "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, BASE_NONE,
2809 &yesno, 0, "chown is restricted to root" }},
2810 { &hf_nfs_pathconf_case_insensitive, {
2811 "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, BASE_NONE,
2812 &yesno, 0, "file names are treated case insensitive" }},
2813 { &hf_nfs_pathconf_case_preserving, {
2814 "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, BASE_NONE,
2815 &yesno, 0, "file name cases are preserved" }}
2818 static gint *ett[] = {
2826 &ett_nfs_readdir_entry,
2832 &ett_nfs_post_op_fh3,
2834 &ett_nfs_diropargs3,
2835 &ett_nfs_sattrguard3,
2842 &ett_nfs_pre_op_attr,
2843 &ett_nfs_post_op_attr,
2847 &ett_nfs_fsinfo_properties
2849 proto_nfs = proto_register_protocol("Network File System", "nfs");
2850 proto_register_field_array(proto_nfs, hf, array_length(hf));
2851 proto_register_subtree_array(ett, array_length(ett));
2853 /* Register the protocol as RPC */
2854 rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs);
2855 /* Register the procedure tables */
2856 rpc_init_proc_table(NFS_PROGRAM, 2, nfs2_proc);
2857 rpc_init_proc_table(NFS_PROGRAM, 3, nfs3_proc);