/* packet-nfs.c * Routines for nfs dissection * Copyright 1999, Uwe Girlich * Copyright 2000-2001, Mike Frisch (NFSv4 decoding) * * $Id: packet-nfs.c,v 1.56 2001/06/19 08:33:00 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * Copied from packet-smb.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_TYPES_H #include #endif #include #include "packet-rpc.h" #include "packet-nfs.h" static int proto_nfs = -1; static int hf_nfs_fh_length = -1; static int hf_nfs_fh_fsid_major = -1; static int hf_nfs_fh_fsid_minor = -1; static int hf_nfs_fh_fsid_inode = -1; static int hf_nfs_fh_xfsid_major = -1; static int hf_nfs_fh_xfsid_minor = -1; static int hf_nfs_fh_fstype = -1; static int hf_nfs_fh_fn = -1; static int hf_nfs_fh_fn_len = -1; static int hf_nfs_fh_fn_inode = -1; static int hf_nfs_fh_fn_generation = -1; static int hf_nfs_fh_xfn = -1; static int hf_nfs_fh_xfn_len = -1; static int hf_nfs_fh_xfn_inode = -1; static int hf_nfs_fh_xfn_generation = -1; static int hf_nfs_fh_dentry = -1; static int hf_nfs_fh_dev = -1; static int hf_nfs_fh_xdev = -1; static int hf_nfs_fh_dirinode = -1; static int hf_nfs_fh_pinode = -1; static int hf_nfs_fh_hp_len = -1; static int hf_nfs_fh_version = -1; static int hf_nfs_fh_auth_type = -1; static int hf_nfs_fh_fsid_type = -1; static int hf_nfs_fh_fileid_type = -1; static int hf_nfs_stat = -1; static int hf_nfs_name = -1; static int hf_nfs_readlink_data = -1; static int hf_nfs_read_offset = -1; static int hf_nfs_read_count = -1; static int hf_nfs_read_totalcount = -1; static int hf_nfs_data = -1; static int hf_nfs_write_beginoffset = -1; static int hf_nfs_write_offset = -1; static int hf_nfs_write_totalcount = -1; static int hf_nfs_symlink_to = -1; static int hf_nfs_readdir_cookie = -1; static int hf_nfs_readdir_count = -1; static int hf_nfs_readdir_entry = -1; static int hf_nfs_readdir_entry_fileid = -1; static int hf_nfs_readdir_entry_name = -1; static int hf_nfs_readdir_entry_cookie = -1; static int hf_nfs_readdir_entry3_fileid = -1; static int hf_nfs_readdir_entry3_name = -1; static int hf_nfs_readdir_entry3_cookie = -1; static int hf_nfs_readdirplus_entry_fileid = -1; static int hf_nfs_readdirplus_entry_name = -1; static int hf_nfs_readdirplus_entry_cookie = -1; static int hf_nfs_readdir_eof = -1; static int hf_nfs_statfs_tsize = -1; static int hf_nfs_statfs_bsize = -1; static int hf_nfs_statfs_blocks = -1; static int hf_nfs_statfs_bfree = -1; static int hf_nfs_statfs_bavail = -1; static int hf_nfs_ftype3 = -1; static int hf_nfs_nfsstat3 = -1; static int hf_nfs_read_eof = -1; static int hf_nfs_write_stable = -1; static int hf_nfs_write_committed = -1; static int hf_nfs_createmode3 = -1; static int hf_nfs_fsstat_invarsec = -1; static int hf_nfs_fsinfo_rtmax = -1; static int hf_nfs_fsinfo_rtpref = -1; static int hf_nfs_fsinfo_rtmult = -1; static int hf_nfs_fsinfo_wtmax = -1; static int hf_nfs_fsinfo_wtpref = -1; static int hf_nfs_fsinfo_wtmult = -1; static int hf_nfs_fsinfo_dtpref = -1; static int hf_nfs_fsinfo_maxfilesize = -1; static int hf_nfs_fsinfo_properties = -1; static int hf_nfs_pathconf_linkmax = -1; static int hf_nfs_pathconf_name_max = -1; static int hf_nfs_pathconf_no_trunc = -1; static int hf_nfs_pathconf_chown_restricted = -1; static int hf_nfs_pathconf_case_insensitive = -1; static int hf_nfs_pathconf_case_preserving = -1; static int hf_nfs_data_follows = -1; static int hf_nfs_fattr_type = -1; static int hf_nfs_fattr_nlink = -1; static int hf_nfs_fattr_uid = -1; static int hf_nfs_fattr_gid = -1; static int hf_nfs_fattr_size = -1; static int hf_nfs_fattr_blocksize = -1; static int hf_nfs_fattr_rdev = -1; static int hf_nfs_fattr_blocks = -1; static int hf_nfs_fattr_fsid = -1; static int hf_nfs_fattr_fileid = -1; static int hf_nfs_fattr3_type = -1; static int hf_nfs_fattr3_nlink = -1; static int hf_nfs_fattr3_uid = -1; static int hf_nfs_fattr3_gid = -1; static int hf_nfs_fattr3_size = -1; static int hf_nfs_fattr3_used = -1; static int hf_nfs_fattr3_rdev = -1; static int hf_nfs_fattr3_fsid = -1; static int hf_nfs_fattr3_fileid = -1; static int hf_nfs_wcc_attr_size = -1; static int hf_nfs_set_size3_size = -1; static int hf_nfs_cookie3 = -1; static int hf_nfs_fsstat3_resok_tbytes = -1; static int hf_nfs_fsstat3_resok_fbytes = -1; static int hf_nfs_fsstat3_resok_abytes = -1; static int hf_nfs_fsstat3_resok_tfiles = -1; static int hf_nfs_fsstat3_resok_ffiles = -1; static int hf_nfs_fsstat3_resok_afiles = -1; static int hf_nfs_uid3 = -1; static int hf_nfs_gid3 = -1; static int hf_nfs_offset3 = -1; static int hf_nfs_count3 = -1; static int hf_nfs_count3_maxcount = -1; static int hf_nfs_count3_dircount= -1; /* NFSv4 */ static int hf_nfs_argop4 = -1; static int hf_nfs_resop4 = -1; static int hf_nfs_linktext4 = -1; static int hf_nfs_tag4 = -1; static int hf_nfs_component4 = -1; static int hf_nfs_clientid4 = -1; static int hf_nfs_clientid4_verifier = -1; static int hf_nfs_ace4 = -1; static int hf_nfs_recall = -1; static int hf_nfs_open_claim_type4 = -1; static int hf_nfs_opentype4 = -1; static int hf_nfs_limit_by4 = -1; static int hf_nfs_open_delegation_type4 = -1; static int hf_nfs_ftype4 = -1; static int hf_nfs_change_info4_atomic = -1; static int hf_nfs_open4_share_access = -1; static int hf_nfs_open4_share_deny = -1; static int hf_nfs_seqid4 = -1; static int hf_nfs_mand_attr = -1; static int hf_nfs_recc_attr = -1; static int hf_nfs_time_how4 = -1; static int hf_nfs_attrlist4 = -1; static int hf_nfs_fattr4_expire_type = -1; static int hf_nfs_fattr4_link_support = -1; static int hf_nfs_fattr4_symlink_support = -1; static int hf_nfs_fattr4_named_attr = -1; static int hf_nfs_fattr4_unique_handles = -1; static int hf_nfs_fattr4_archive = -1; static int hf_nfs_fattr4_cansettime = -1; static int hf_nfs_fattr4_case_insensitive = -1; static int hf_nfs_fattr4_case_preserving = -1; static int hf_nfs_fattr4_chown_restricted = -1; static int hf_nfs_fattr4_hidden = -1; static int hf_nfs_fattr4_homogeneous = -1; static int hf_nfs_fattr4_mimetype = -1; static int hf_nfs_fattr4_no_trunc = -1; static int hf_nfs_fattr4_system = -1; static int hf_nfs_fattr4_owner = -1; static int hf_nfs_fattr4_owner_group = -1; static int hf_nfs_fattr4_size = -1; static int hf_nfs_fattr4_aclsupport = -1; static int hf_nfs_fattr4_lease_time = -1; static int hf_nfs_fattr4_fileid = -1; static int hf_nfs_fattr4_files_avail = -1; static int hf_nfs_fattr4_files_free = -1; static int hf_nfs_fattr4_files_total = -1; static int hf_nfs_fattr4_maxfilesize = -1; static int hf_nfs_fattr4_maxlink = -1; static int hf_nfs_fattr4_maxname = -1; static int hf_nfs_fattr4_numlinks = -1; static int hf_nfs_fattr4_maxread = -1; static int hf_nfs_fattr4_maxwrite = -1; static int hf_nfs_fattr4_quota_hard = -1; static int hf_nfs_fattr4_quota_soft = -1; static int hf_nfs_fattr4_quota_used = -1; static int hf_nfs_fattr4_space_avail = -1; static int hf_nfs_fattr4_space_free = -1; static int hf_nfs_fattr4_space_total = -1; static int hf_nfs_fattr4_space_used = -1; static int hf_nfs_who = -1; static int hf_nfs_server = -1; static int hf_nfs_stable_how4 = -1; static int hf_nfs_dirlist4_eof = -1; static int hf_nfs_stateid4 = -1; static int hf_nfs_offset4 = -1; static int hf_nfs_specdata1 = -1; static int hf_nfs_specdata2 = -1; static int hf_nfs_locktype4 = -1; static int hf_nfs_reclaim4 = -1; static int hf_nfs_length4 = -1; static int hf_nfs_changeid4 = -1; static int hf_nfs_nfstime4_seconds = -1; static int hf_nfs_nfstime4_nseconds = -1; static int hf_nfs_fsid4_major = -1; static int hf_nfs_fsid4_minor = -1; static int hf_nfs_acetype4 = -1; static int hf_nfs_aceflag4 = -1; static int hf_nfs_acemask4 = -1; static int hf_nfs_delegate_type = -1; static int hf_nfs_secinfo_flavor = -1; static int hf_nfs_num_blocks = -1; static int hf_nfs_bytes_per_block = -1; static int hf_nfs_eof = -1; static int hf_nfs_stateid4_delegate_stateid = -1; static int hf_nfs_verifier4 = -1; static int hf_nfs_cookie4 = -1; static int hf_nfs_cookieverf4 = -1; static int hf_nfs_cb_program = -1; static int hf_nfs_cb_location = -1; static int hf_nfs_recall4 = -1; static int hf_nfs_filesize = -1; static int hf_nfs_count4 = -1; static int hf_nfs_count4_dircount = -1; static int hf_nfs_count4_maxcount = -1; static int hf_nfs_minorversion = -1; static gint ett_nfs = -1; static gint ett_nfs_fh_encoding = -1; static gint ett_nfs_fh_fsid = -1; static gint ett_nfs_fh_xfsid = -1; static gint ett_nfs_fh_fn = -1; static gint ett_nfs_fh_xfn = -1; static gint ett_nfs_fh_hp = -1; static gint ett_nfs_fh_auth = -1; static gint ett_nfs_fhandle = -1; static gint ett_nfs_timeval = -1; static gint ett_nfs_mode = -1; static gint ett_nfs_fattr = -1; static gint ett_nfs_sattr = -1; static gint ett_nfs_diropargs = -1; static gint ett_nfs_readdir_entry = -1; static gint ett_nfs_mode3 = -1; static gint ett_nfs_specdata3 = -1; static gint ett_nfs_fh3 = -1; static gint ett_nfs_nfstime3 = -1; static gint ett_nfs_fattr3 = -1; static gint ett_nfs_post_op_fh3 = -1; static gint ett_nfs_sattr3 = -1; static gint ett_nfs_diropargs3 = -1; static gint ett_nfs_sattrguard3 = -1; static gint ett_nfs_set_mode3 = -1; static gint ett_nfs_set_uid3 = -1; static gint ett_nfs_set_gid3 = -1; static gint ett_nfs_set_size3 = -1; static gint ett_nfs_set_atime = -1; static gint ett_nfs_set_mtime = -1; static gint ett_nfs_pre_op_attr = -1; static gint ett_nfs_post_op_attr = -1; static gint ett_nfs_wcc_attr = -1; static gint ett_nfs_wcc_data = -1; static gint ett_nfs_access = -1; static gint ett_nfs_fsinfo_properties = -1; /* NFSv4 */ static gint ett_nfs_compound_call4 = -1; static gint ett_nfs_utf8string = -1; static gint ett_nfs_argop4 = -1; static gint ett_nfs_resop4 = -1; static gint ett_nfs_access4 = -1; static gint ett_nfs_close4 = -1; static gint ett_nfs_commit4 = -1; static gint ett_nfs_create4 = -1; static gint ett_nfs_delegpurge4 = -1; static gint ett_nfs_delegreturn4 = -1; static gint ett_nfs_getattr4 = -1; static gint ett_nfs_getfh4 = -1; static gint ett_nfs_link4 = -1; static gint ett_nfs_lock4 = -1; static gint ett_nfs_lockt4 = -1; static gint ett_nfs_locku4 = -1; static gint ett_nfs_lookup4 = -1; static gint ett_nfs_lookupp4 = -1; static gint ett_nfs_nverify4 = -1; static gint ett_nfs_open4 = -1; static gint ett_nfs_openattr4 = -1; static gint ett_nfs_open_confirm4 = -1; static gint ett_nfs_open_downgrade4 = -1; static gint ett_nfs_putfh4 = -1; static gint ett_nfs_putpubfh4 = -1; static gint ett_nfs_putrootfh4 = -1; static gint ett_nfs_read4 = -1; static gint ett_nfs_readdir4 = -1; static gint ett_nfs_readlink4 = -1; static gint ett_nfs_remove4 = -1; static gint ett_nfs_rename4 = -1; static gint ett_nfs_renew4 = -1; static gint ett_nfs_restorefh4 = -1; static gint ett_nfs_savefh4 = -1; static gint ett_nfs_secinfo4 = -1; static gint ett_nfs_setattr4 = -1; static gint ett_nfs_setclientid4 = -1; static gint ett_nfs_setclientid_confirm4 = -1; static gint ett_nfs_verify4 = -1; static gint ett_nfs_write4 = -1; static gint ett_nfs_verifier4 = -1; static gint ett_nfs_opaque = -1; static gint ett_nfs_dirlist4 = -1; static gint ett_nfs_pathname4 = -1; static gint ett_nfs_change_info4 = -1; static gint ett_nfs_open_delegation4 = -1; static gint ett_nfs_open_claim4 = -1; static gint ett_nfs_opentype4 = -1; static gint ett_nfs_lockowner4 = -1; static gint ett_nfs_cb_client4 = -1; static gint ett_nfs_client_id4 = -1; static gint ett_nfs_bitmap4 = -1; static gint ett_nfs_fattr4 = -1; static gint ett_nfs_fsid4 = -1; static gint ett_nfs_fs_locations4 = -1; static gint ett_nfs_fs_location4 = -1; static gint ett_nfs_open4_result_flags = -1; /* file handle dissection */ #define FHT_UNKNOWN 0 #define FHT_SVR4 1 #define FHT_LINUX_KNFSD_LE 2 #define FHT_LINUX_NFSD_LE 3 #define FHT_LINUX_KNFSD_NEW 4 static const value_string names_fhtype[] = { { FHT_UNKNOWN, "unknown" }, { FHT_SVR4, "System V R4" }, { FHT_LINUX_KNFSD_LE, "Linux knfsd (little-endian)" }, { FHT_LINUX_NFSD_LE, "Linux user-land nfsd (little-endian)" }, { FHT_LINUX_KNFSD_NEW, "Linux knfsd (new)" }, { 0, NULL } }; /* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45) */ static void dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree, int fhlen) { guint32 nof = offset; /* file system id */ { guint32 fsid_O; guint32 fsid_L; guint32 temp; guint32 fsid_major; guint32 fsid_minor; fsid_O = nof; fsid_L = 4; temp = tvb_get_ntohl(tvb, fsid_O); fsid_major = ( temp>>18 ) & 0x3fff; /* 14 bits */ fsid_minor = ( temp ) & 0x3ffff; /* 18 bits */ if (tree) { proto_item* fsid_item = NULL; proto_tree* fsid_tree = NULL; fsid_item = proto_tree_add_text(tree, tvb, fsid_O, fsid_L, "file system ID: %d,%d", fsid_major, fsid_minor); if (fsid_item) { fsid_tree = proto_item_add_subtree(fsid_item, ett_nfs_fh_fsid); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major, tvb, fsid_O, 2, fsid_major); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor, tvb, fsid_O+1, 3, fsid_minor); } } nof = fsid_O + fsid_L; } /* file system type */ { guint32 fstype_O; guint32 fstype_L; guint32 fstype; fstype_O = nof; fstype_L = 4; fstype = tvb_get_ntohl(tvb, fstype_O); if (tree) { proto_tree_add_uint(tree, hf_nfs_fh_fstype, tvb, fstype_O, fstype_L, fstype); } nof = fstype_O + fstype_L; } /* file number */ { guint32 fn_O; guint32 fn_len_O; guint32 fn_len_L; guint32 fn_len; guint32 fn_data_O; guint32 fn_data_inode_O; guint32 fn_data_inode_L; guint32 inode; guint32 fn_data_gen_O; guint32 fn_data_gen_L; guint32 gen; guint32 fn_L; fn_O = nof; fn_len_O = fn_O; fn_len_L = 2; fn_len = tvb_get_ntohs(tvb, fn_len_O); fn_data_O = fn_O + fn_len_L; fn_data_inode_O = fn_data_O + 2; fn_data_inode_L = 4; inode = tvb_get_ntohl(tvb, fn_data_inode_O); fn_data_gen_O = fn_data_inode_O + fn_data_inode_L; fn_data_gen_L = 4; gen = tvb_get_ntohl(tvb, fn_data_gen_O); fn_L = fn_len_L + fn_len; if (tree) { proto_item* fn_item = NULL; proto_tree* fn_tree = NULL; fn_item = proto_tree_add_uint(tree, hf_nfs_fh_fn, tvb, fn_O, fn_L, inode); if (fn_item) { fn_tree = proto_item_add_subtree(fn_item, ett_nfs_fh_fn); proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_len, tvb, fn_len_O, fn_len_L, fn_len); proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_inode, tvb, fn_data_inode_O, fn_data_inode_L, inode); proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_generation, tvb, fn_data_gen_O, fn_data_gen_L, gen); } } nof = fn_O + fn_len_L + fn_len; } /* exported file number */ { guint32 xfn_O; guint32 xfn_len_O; guint32 xfn_len_L; guint32 xfn_len; guint32 xfn_data_O; guint32 xfn_data_inode_O; guint32 xfn_data_inode_L; guint32 xinode; guint32 xfn_data_gen_O; guint32 xfn_data_gen_L; guint32 xgen; guint32 xfn_L; xfn_O = nof; xfn_len_O = xfn_O; xfn_len_L = 2; xfn_len = tvb_get_ntohs(tvb, xfn_len_O); xfn_data_O = xfn_O + xfn_len_L; xfn_data_inode_O = xfn_data_O + 2; xfn_data_inode_L = 4; xinode = tvb_get_ntohl(tvb, xfn_data_inode_O); xfn_data_gen_O = xfn_data_inode_O + xfn_data_inode_L; xfn_data_gen_L = 4; xgen = tvb_get_ntohl(tvb, xfn_data_gen_O); xfn_L = xfn_len_L + xfn_len; if (tree) { proto_item* xfn_item = NULL; proto_tree* xfn_tree = NULL; xfn_item = proto_tree_add_uint(tree, hf_nfs_fh_xfn, tvb, xfn_O, xfn_L, xinode); if (xfn_item) { xfn_tree = proto_item_add_subtree(xfn_item, ett_nfs_fh_xfn); proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_len, tvb, xfn_len_O, xfn_len_L, xfn_len); proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_inode, tvb, xfn_data_inode_O, xfn_data_inode_L, xinode); proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_generation, tvb, xfn_data_gen_O, xfn_data_gen_L, xgen); } } } } /* Checked with RedHat Linux 6.2 (kernel 2.2.14 knfsd) */ static void dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree, int fhlen) { guint32 dentry; guint32 inode; guint32 dirinode; guint32 temp; guint32 fsid_major; guint32 fsid_minor; guint32 xfsid_major; guint32 xfsid_minor; guint32 xinode; guint32 gen; dentry = tvb_get_letohl(tvb, offset+0); inode = tvb_get_letohl(tvb, offset+4); dirinode = tvb_get_letohl(tvb, offset+8); temp = tvb_get_letohs (tvb,offset+12); fsid_major = (temp >> 8) & 0xff; fsid_minor = (temp ) & 0xff; temp = tvb_get_letohs(tvb,offset+16); xfsid_major = (temp >> 8) & 0xff; xfsid_minor = (temp ) & 0xff; xinode = tvb_get_letohl(tvb,offset+20); gen = tvb_get_letohl(tvb,offset+24); if (tree) { proto_tree_add_uint(tree, hf_nfs_fh_dentry, tvb, offset+0, 4, dentry); proto_tree_add_uint(tree, hf_nfs_fh_fn_inode, tvb, offset+4, 4, inode); proto_tree_add_uint(tree, hf_nfs_fh_dirinode, tvb, offset+8, 4, dirinode); /* file system id (device) */ { proto_item* fsid_item = NULL; proto_tree* fsid_tree = NULL; fsid_item = proto_tree_add_text(tree, tvb, offset+12, 4, "file system ID: %d,%d", fsid_major, fsid_minor); if (fsid_item) { fsid_tree = proto_item_add_subtree(fsid_item, ett_nfs_fh_fsid); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major, tvb, offset+13, 1, fsid_major); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor, tvb, offset+12, 1, fsid_minor); } } /* exported file system id (device) */ { proto_item* xfsid_item = NULL; proto_tree* xfsid_tree = NULL; xfsid_item = proto_tree_add_text(tree, tvb, offset+16, 4, "exported file system ID: %d,%d", xfsid_major, xfsid_minor); if (xfsid_item) { xfsid_tree = proto_item_add_subtree(xfsid_item, ett_nfs_fh_xfsid); proto_tree_add_uint(xfsid_tree, hf_nfs_fh_xfsid_major, tvb, offset+17, 1, xfsid_major); proto_tree_add_uint(xfsid_tree, hf_nfs_fh_xfsid_minor, tvb, offset+16, 1, xfsid_minor); } } proto_tree_add_uint(tree, hf_nfs_fh_xfn_inode, tvb, offset+20, 4, xinode); proto_tree_add_uint(tree, hf_nfs_fh_fn_generation, tvb, offset+24, 4, gen); } } /* Checked with RedHat Linux 5.2 (nfs-server 2.2beta47 user-land nfsd) */ void dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree, int fhlen) { /* pseudo inode */ { guint32 pinode; pinode = tvb_get_letohl(tvb, offset+0); if (tree) { proto_tree_add_uint(tree, hf_nfs_fh_pinode, tvb, offset+0, 4, pinode); } } /* hash path */ { guint32 hashlen; hashlen = tvb_get_guint8(tvb, offset+4); if (tree) { proto_item* hash_item = NULL; proto_tree* hash_tree = NULL; hash_item = proto_tree_add_text(tree, tvb, offset+4, hashlen + 1, "hash path: %s", tvb_bytes_to_str(tvb,offset+5,hashlen)); if (hash_item) { hash_tree = proto_item_add_subtree(hash_item, ett_nfs_fh_hp); if (hash_tree) { proto_tree_add_uint(hash_tree, hf_nfs_fh_hp_len, tvb, offset+4, 1, hashlen); proto_tree_add_text(hash_tree, tvb, offset+5, hashlen, "key: %s", tvb_bytes_to_str(tvb,offset+5,hashlen)); } } } } } /* Checked with SuSE 7.1 (kernel 2.4.0 knfsd) */ /* read linux-2.4.5/include/linux/nfsd/nfsfh.h for more details */ #define AUTH_TYPE_NONE 0 static const value_string auth_type_names[] = { { AUTH_TYPE_NONE, "no authentication" }, {0,NULL} }; #define FSID_TYPE_MAJOR_MINOR_INODE 0 static const value_string fsid_type_names[] = { { FSID_TYPE_MAJOR_MINOR_INODE, "major/minor/inode" }, {0,NULL} }; #define FILEID_TYPE_ROOT 0 #define FILEID_TYPE_INODE_GENERATION 1 #define FILEID_TYPE_INODE_GENERATION_PARENT 2 static const value_string fileid_type_names[] = { { FILEID_TYPE_ROOT, "root" }, { FILEID_TYPE_INODE_GENERATION, "inode/generation" }, { FILEID_TYPE_INODE_GENERATION_PARENT, "inode/generation/parent" }, {0,NULL} }; static void dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, int offset, proto_tree *tree, int fhlen) { guint8 version; guint8 auth_type; guint8 fsid_type; guint8 fileid_type; version = tvb_get_guint8(tvb, offset + 0); if (tree) { proto_tree_add_uint(tree, hf_nfs_fh_version, tvb, offset+0, 1, version); } switch (version) { case 1: { auth_type = tvb_get_guint8(tvb, offset + 1); fsid_type = tvb_get_guint8(tvb, offset + 2); fileid_type = tvb_get_guint8(tvb, offset + 3); if (tree) { proto_item* encoding_item = proto_tree_add_text(tree, tvb, offset + 1, 3, "encoding: %u %u %u", auth_type, fsid_type, fileid_type); if (encoding_item) { proto_tree* encoding_tree = proto_item_add_subtree(encoding_item, ett_nfs_fh_encoding); if (encoding_tree) { proto_tree_add_uint(encoding_tree, hf_nfs_fh_auth_type, tvb, offset+1, 1, auth_type); proto_tree_add_uint(encoding_tree, hf_nfs_fh_fsid_type, tvb, offset+2, 1, fsid_type); proto_tree_add_uint(encoding_tree, hf_nfs_fh_fileid_type, tvb, offset+3, 1, fileid_type); } } } offset += 4; } break; default: { /* unknown version */ goto out; } } switch (auth_type) { case 0: { /* no authentication */ if (tree) { proto_tree_add_text(tree, tvb, offset + 0, 0, "authentication: none"); } } break; default: { /* unknown authentication type */ goto out; } } switch (fsid_type) { case 0: { guint16 fsid_major; guint16 fsid_minor; guint32 fsid_inode; fsid_major = tvb_get_ntohs(tvb, offset + 0); fsid_minor = tvb_get_ntohs(tvb, offset + 2); fsid_inode = tvb_get_letohl(tvb, offset + 4); if (tree) { proto_item* fsid_item = proto_tree_add_text(tree, tvb, offset+0, 8, "file system ID: %u,%u (inode %u)", fsid_major, fsid_minor, fsid_inode); if (fsid_item) { proto_tree* fsid_tree = proto_item_add_subtree(fsid_item, ett_nfs_fh_fsid); if (fsid_tree) { proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major, tvb, offset+0, 2, fsid_major); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor, tvb, offset+2, 2, fsid_minor); proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_inode, tvb, offset+4, 4, fsid_inode); } } } offset += 8; } break; default: { /* unknown fsid type */ goto out; } } switch (fileid_type) { case 0: { if (tree) { proto_tree_add_text(tree, tvb, offset+0, 0, "file ID: root inode"); } } break; case 1: { guint32 inode; guint32 generation; inode = tvb_get_letohl(tvb, offset + 0); generation = tvb_get_letohl(tvb, offset + 4); if (tree) { proto_item* fileid_item = proto_tree_add_text(tree, tvb, offset+0, 8, "file ID: %u (%u)", inode, generation); if (fileid_item) { proto_tree* fileid_tree = proto_item_add_subtree( fileid_item, ett_nfs_fh_fn); if (fileid_tree) { proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode, tvb, offset+0, 4, inode); proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation, tvb, offset+4, 4, generation); } } } offset += 8; } break; case 2: { guint32 inode; guint32 generation; guint32 parent_inode; inode = tvb_get_letohl(tvb, offset + 0); generation = tvb_get_letohl(tvb, offset + 4); parent_inode = tvb_get_letohl(tvb, offset + 8); if (tree) { proto_item* fileid_item = proto_tree_add_text(tree, tvb, offset+0, 8, "file ID: %u (%u)", inode, generation); if (fileid_item) { proto_tree* fileid_tree = proto_item_add_subtree( fileid_item, ett_nfs_fh_fn); if (fileid_tree) { proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode, tvb, offset+0, 4, inode); proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation, tvb, offset+4, 4, generation); proto_tree_add_uint(fileid_tree, hf_nfs_fh_dirinode, tvb, offset+8, 4, parent_inode); } } } offset += 12; } break; default: { /* unknown fileid type */ goto out; } } out: ; } static void dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree, int fhlen) { int sublen; int bytes_left; gboolean first_line; bytes_left = fhlen; first_line = TRUE; while (bytes_left != 0) { sublen = 16; if (sublen > bytes_left) sublen = bytes_left; proto_tree_add_text(tree, tvb, offset, sublen, "%s%s", first_line ? "data: " : " ", tvb_bytes_to_str(tvb,offset,sublen)); bytes_left -= sublen; offset += sublen; first_line = FALSE; } } static void dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, unsigned int fhlen) { unsigned int fhtype = FHT_UNKNOWN; /* filehandle too long */ if (fhlen>64) goto type_ready; /* Not all bytes there. Any attempt to deduce the type would be senseless. */ if (!tvb_bytes_exist(tvb,offset,fhlen)) goto type_ready; /* calculate (heuristically) fhtype */ switch (fhlen) { case 12: { if (tvb_get_ntohl(tvb,offset) == 0x01000000) { fhtype=FHT_LINUX_KNFSD_NEW; } } break; case 20: { if (tvb_get_ntohl(tvb,offset) == 0x01000001) { fhtype=FHT_LINUX_KNFSD_NEW; } } break; case 24: { if (tvb_get_ntohl(tvb,offset) == 0x01000002) { fhtype=FHT_LINUX_KNFSD_NEW; } } break; case 32: { guint32 len1; guint32 len2; if (tvb_get_ntohs(tvb,offset+4) == 0) { len1=tvb_get_ntohs(tvb,offset+8); if (tvb_bytes_exist(tvb,offset+10+len1,2)) { len2=tvb_get_ntohs(tvb, offset+10+len1); if (fhlen==12+len1+len2) { fhtype=FHT_SVR4; goto type_ready; } } } len1 = tvb_get_guint8(tvb,offset+4); if (len1<28 && tvb_bytes_exist(tvb,offset+5,len1)) { int wrong=0; for (len2=5+len1;len2<32;len2++) { if (tvb_get_guint8(tvb,offset+len2)) { wrong=1; break; } } if (!wrong) { fhtype=FHT_LINUX_NFSD_LE; goto type_ready; } } if (tvb_get_ntohl(tvb,offset+28) == 0) { if (tvb_get_ntohs(tvb,offset+14) == 0) { if (tvb_get_ntohs(tvb,offset+18) == 0) { fhtype=FHT_LINUX_KNFSD_LE; goto type_ready; } } } } break; } type_ready: proto_tree_add_text(tree, tvb, offset, 0, "type: %s", val_to_str(fhtype, names_fhtype, "Unknown")); switch (fhtype) { case FHT_SVR4: dissect_fhandle_data_SVR4 (tvb, offset, tree, fhlen); break; case FHT_LINUX_KNFSD_LE: dissect_fhandle_data_LINUX_KNFSD_LE(tvb, offset, tree, fhlen); break; case FHT_LINUX_NFSD_LE: dissect_fhandle_data_LINUX_NFSD_LE (tvb, offset, tree, fhlen); break; case FHT_LINUX_KNFSD_NEW: dissect_fhandle_data_LINUX_KNFSD_NEW (tvb, offset, tree, fhlen); break; case FHT_UNKNOWN: default: dissect_fhandle_data_unknown(tvb, offset, tree, fhlen); break; } } /***************************/ /* NFS Version 2, RFC 1094 */ /***************************/ /* RFC 1094, Page 12..14 */ const value_string names_nfs_stat[] = { { 0, "OK" }, { 1, "ERR_PERM" }, { 2, "ERR_NOENT" }, { 5, "ERR_IO" }, { 6, "ERR_NX_IO" }, { 13, "ERR_ACCES" }, { 17, "ERR_EXIST" }, { 18, "ERR_XDEV" }, /* not in spec, but can happen */ { 19, "ERR_NODEV" }, { 20, "ERR_NOTDIR" }, { 21, "ERR_ISDIR" }, { 22, "ERR_INVAL" }, /* not in spec, but I think it can happen */ { 26, "ERR_TXTBSY" }, /* not in spec, but I think it can happen */ { 27, "ERR_FBIG" }, { 28, "ERR_NOSPC" }, { 30, "ERR_ROFS" }, { 31, "ERR_MLINK" }, /* not in spec, but can happen */ { 45, "ERR_OPNOTSUPP" }, /* not in spec, but I think it can happen */ { 63, "ERR_NAMETOOLONG" }, { 66, "ERR_NOTEMPTY" }, { 69, "ERR_DQUOT" }, { 70, "ERR_STALE" }, { 99, "ERR_WFLUSH" }, { 0, NULL } }; /* NFSv4 Draft Specification, Page 198-199 */ const value_string names_nfs_stat4[] = { { 0, "NFS4_OK" }, { 1, "NFS4ERR_PERM" }, { 2, "NFS4ERR_NOENT" }, { 5, "NFS4ERR_IO" }, { 6, "NFS4ERR_NXIO" }, { 13, "NFS4ERR_ACCES" }, { 17, "NFS4ERR_EXIST" }, { 18, "NFS4ERR_XDEV" }, { 19, "NFS4ERR_NODEV" }, { 20, "NFS4ERR_NOTDIR" }, { 21, "NFS4ERR_ISDIR" }, { 22, "NFS4ERR_INVAL" }, { 27, "NFS4ERR_FBIG" }, { 28, "NFS4ERR_NOSPC" }, { 30, "NFS4ERR_ROFS" }, { 31, "NFS4ERR_MLINK" }, { 63, "NFS4ERR_NAMETOOLONG" }, { 66, "NFS4ERR_NOTEMPTY" }, { 69, "NFS4ERR_DQUOT" }, { 70, "NFS4ERR_STALE" }, { 10001, "NFS4ERR_BADHANDLE" }, { 10003, "NFS4ERR_BAD_COOKIE" }, { 10004, "NFS4ERR_NOTSUPP" }, { 10005, "NFS4ERR_TOOSMALL" }, { 10006, "NFS4ERR_SERVERFAULT" }, { 10007, "NFS4ERR_BADTYPE" }, { 10008, "NFS4ERR_DELAY" }, { 10009, "NFS4ERR_SAME" }, { 10010, "NFS4ERR_DENIED" }, { 10011, "NFS4ERR_EXPIRED" }, { 10012, "NFS4ERR_LOCKED" }, { 10013, "NFS4ERR_GRACE" }, { 10014, "NFS4ERR_FHEXPIRED" }, { 10015, "NFS4ERR_SHARE_DENIED" }, { 10016, "NFS4ERR_WRONGSEC" }, { 10017, "NFS4ERR_CLID_INUSE" }, { 10018, "NFS4ERR_RESOURCE" }, { 10019, "NFS4ERR_MOVED" }, { 10020, "NFS4ERR_NOFILEHANDLE" }, { 10021, "NFS4ERR_MINOR_VERS_MISMATCH" }, { 10022, "NFS4ERR_STALE_CLIENTID" }, { 10023, "NFS4ERR_STALE_STATEID" }, { 10024, "NFS4ERR_OLD_STATEID" }, { 10025, "NFS4ERR_BAD_STATEID" }, { 10026, "NFS4ERR_BAD_SEQID" }, { 10027, "NFS4ERR_NOT_SAME" }, { 10028, "NFS4ERR_LOCK_RANGE" }, { 10029, "NFS4ERR_SYMLINK" }, { 10030, "NFS4ERR_READDIR_NOSPC" }, { 10031, "NFS4ERR_LEASE_MOVED" }, { 0, NULL } }; /* This function has been modified to support NFSv4 style error codes as * well as being backwards compatible with NFSv2 and NFSv3. */ int dissect_stat_internal(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32* status, int nfsvers) { guint32 stat; stat = tvb_get_ntohl(tvb, offset+0); if (tree) { /* this gives the right NFSv2 number<->message relation */ /* and makes it searchable via "nfs.status" */ proto_tree_add_uint_format(tree, hf_nfs_nfsstat3, tvb, offset+0, 4, stat, "Status: %s (%u)", val_to_str(stat, (nfsvers != 4)? names_nfs_stat: names_nfs_stat4,"%u"), stat); } offset += 4; *status = stat; return offset; } /* RFC 1094, Page 12..14 */ int dissect_stat(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 *status) { return dissect_stat_internal(tvb, offset, pinfo, tree, status, !4); } /* RFC 1094, Page 12..14 */ int dissect_nfs2_stat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_stat(tvb, offset, pinfo, tree, &status); return offset; } int dissect_nfs_nfsstat4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 *status) { return dissect_stat_internal(tvb, offset, pinfo, tree, status, 4); } /* RFC 1094, Page 15 */ int dissect_ftype(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 ftype; char* ftype_name = NULL; const value_string nfs2_ftype[] = { { 0, "Non-File" }, { 1, "Regular File" }, { 2, "Directory" }, { 3, "Block Special Device" }, { 4, "Character Special Device" }, { 5, "Symbolic Link" }, { 0, NULL } }; ftype = tvb_get_ntohl(tvb, offset+0); ftype_name = val_to_str(ftype, nfs2_ftype, "%u"); if (tree) { proto_tree_add_text(tree, tvb, offset, 4, "%s: %s (%u)", name, ftype_name, ftype); } offset += 4; return offset; } /* RFC 1094, Page 15 */ int dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { proto_item* fitem; proto_tree* ftree = NULL; if (tree) { fitem = proto_tree_add_text(tree, tvb, offset, FHSIZE, "%s", name); if (fitem) ftree = proto_item_add_subtree(fitem, ett_nfs_fhandle); } if (ftree) dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE); offset += FHSIZE; return offset; } /* RFC 1094, Page 15 */ int dissect_nfs2_fhandle_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_fhandle(tvb, offset, pinfo, tree, "object"); return offset; } /* RFC 1094, Page 15 */ int dissect_timeval(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 seconds; guint32 mseconds; proto_item* time_item; proto_tree* time_tree = NULL; seconds = tvb_get_ntohl(tvb, offset+0); mseconds = tvb_get_ntohl(tvb, offset+4); if (tree) { time_item = proto_tree_add_text(tree, tvb, offset, 8, "%s: %u.%06u", name, seconds, mseconds); if (time_item) time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval); } if (time_tree) { proto_tree_add_text(time_tree, tvb,offset+0,4, "seconds: %u", seconds); proto_tree_add_text(time_tree, tvb,offset+4,4, "micro seconds: %u", mseconds); } offset += 8; return offset; } /* RFC 1094, Page 16 */ const value_string nfs2_mode_names[] = { { 0040000, "Directory" }, { 0020000, "Character Special Device" }, { 0060000, "Block Special Device" }, { 0100000, "Regular File" }, { 0120000, "Symbolic Link" }, { 0140000, "Named Socket" }, { 0000000, NULL }, }; int dissect_mode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 mode; proto_item* mode_item = NULL; proto_tree* mode_tree = NULL; mode = tvb_get_ntohl(tvb, offset+0); if (tree) { mode_item = proto_tree_add_text(tree, tvb, offset, 4, "%s: 0%o", name, mode); if (mode_item) mode_tree = proto_item_add_subtree(mode_item, ett_nfs_mode); } if (mode_tree) { proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_enumerated_bitfield(mode, 0160000, 16, nfs2_mode_names, "%s")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 04000, 16, "Set user id on exec", "not SUID")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 02000, 16, "Set group id on exec", "not SGID")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 01000, 16, "Save swapped text even after use", "not save swapped text")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 0400, 16, "Read permission for owner", "no Read permission for owner")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 0200, 16, "Write permission for owner", "no Write permission for owner")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 0100, 16, "Execute permission for owner", "no Execute permission for owner")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 040, 16, "Read permission for group", "no Read permission for group")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 020, 16, "Write permission for group", "no Write permission for group")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 010, 16, "Execute permission for group", "no Execute permission for group")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 04, 16, "Read permission for others", "no Read permission for others")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 02, 16, "Write permission for others", "no Write permission for others")); proto_tree_add_text(mode_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode, 01, 16, "Execute permission for others", "no Execute permission for others")); } offset += 4; return offset; } /* RFC 1094, Page 15 */ int dissect_fattr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* fattr_item = NULL; proto_tree* fattr_tree = NULL; int old_offset = offset; if (tree) { fattr_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); fattr_tree = proto_item_add_subtree(fattr_item, ett_nfs_fattr); } offset = dissect_ftype(tvb, offset, pinfo, fattr_tree, "type"); offset = dissect_mode(tvb, offset, pinfo, fattr_tree, "mode"); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_nlink, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_uid, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_gid, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_size, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_blocksize, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_rdev, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_blocks, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_fsid, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr_tree, hf_nfs_fattr_fileid, offset); offset = dissect_timeval(tvb, offset, pinfo, fattr_tree, "atime"); offset = dissect_timeval(tvb, offset, pinfo, fattr_tree, "mtime"); offset = dissect_timeval(tvb, offset, pinfo, fattr_tree, "ctime"); /* now we know, that fattr is shorter */ if (fattr_item) { proto_item_set_len(fattr_item, offset - old_offset); } return offset; } /* RFC 1094, Page 17 */ int dissect_sattr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* sattr_item = NULL; proto_tree* sattr_tree = NULL; int old_offset = offset; if (tree) { sattr_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); sattr_tree = proto_item_add_subtree(sattr_item, ett_nfs_sattr); } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_mode(tvb, offset, pinfo, sattr_tree, "mode"); else { proto_tree_add_text(sattr_tree, tvb, offset, 4, "mode: no value"); offset += 4; } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_rpc_uint32(tvb, pinfo, sattr_tree, hf_nfs_fattr_uid, offset); else { proto_tree_add_text(sattr_tree, tvb, offset, 4, "uid: no value"); offset += 4; } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_rpc_uint32(tvb, pinfo, sattr_tree, hf_nfs_fattr_gid, offset); else { proto_tree_add_text(sattr_tree, tvb, offset, 4, "gid: no value"); offset += 4; } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_rpc_uint32(tvb, pinfo, sattr_tree, hf_nfs_fattr_size, offset); else { proto_tree_add_text(sattr_tree, tvb, offset, 4, "size: no value"); offset += 4; } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_timeval(tvb, offset, pinfo, sattr_tree, "atime"); else { proto_tree_add_text(sattr_tree, tvb, offset, 8, "atime: no value"); offset += 8; } if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) offset = dissect_timeval(tvb, offset, pinfo, sattr_tree, "mtime"); else { proto_tree_add_text(sattr_tree, tvb, offset, 8, "mtime: no value"); offset += 8; } /* now we know, that sattr is shorter */ if (sattr_item) { proto_item_set_len(sattr_item, offset - old_offset); } return offset; } /* RFC 1094, Page 17 */ int dissect_filename(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf, char **string_ret) { offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret); return offset; } /* RFC 1094, Page 17 */ int dissect_path(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf) { offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, NULL); return offset; } /* RFC 1094, Page 17,18 */ int dissect_attrstat(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree){ guint32 status; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_fattr(tvb, offset, pinfo, tree, "attributes"); break; default: /* do nothing */ break; } return offset; } /* RFC 1094, Page 17,18 */ int dissect_nfs2_attrstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_attrstat(tvb, offset, pinfo, tree); return offset; } /* RFC 1094, Page 18 */ int dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* diropargs_item = NULL; proto_tree* diropargs_tree = NULL; int old_offset = offset; if (tree) { diropargs_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs); } offset = dissect_fhandle (tvb,offset,pinfo,diropargs_tree,"dir"); offset = dissect_filename(tvb,offset,pinfo,diropargs_tree,hf_nfs_name,NULL); /* now we know, that diropargs is shorter */ if (diropargs_item) { proto_item_set_len(diropargs_item, offset - old_offset); } return offset; } /* RFC 1094, Page 18 */ int dissect_nfs2_diropargs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_diropargs(tvb, offset, pinfo, tree, "where"); return offset; } /* RFC 1094, Page 18 */ int dissect_diropres(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 status; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_fhandle(tvb, offset, pinfo, tree, "file"); offset = dissect_fattr (tvb, offset, pinfo, tree, "attributes"); break; default: /* do nothing */ break; } return offset; } /* nfsdata is simply a chunk of RPC opaque data (length, data, fill bytes) */ int dissect_nfsdata(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf) { offset = dissect_rpc_data(tvb, pinfo, tree, hf, offset); return offset; } /* RFC 1094, Page 18 */ int dissect_nfs2_diropres_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_diropres(tvb, offset, pinfo, tree); return offset; } /* RFC 1094, Page 6 */ int dissect_nfs2_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_fhandle(tvb, offset, pinfo, tree, "file" ); offset = dissect_sattr (tvb, offset, pinfo, tree, "attributes"); return offset; } /* RFC 1094, Page 6 */ int dissect_nfs2_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 status; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_path(tvb, offset, pinfo, tree, hf_nfs_readlink_data); break; default: /* do nothing */ break; } return offset; } /* RFC 1094, Page 7 */ int dissect_nfs2_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 offset_value; guint32 count; guint32 totalcount; offset = dissect_fhandle(tvb, offset, pinfo, tree, "file" ); offset_value = tvb_get_ntohl(tvb, offset+0); count = tvb_get_ntohl(tvb, offset+4); totalcount = tvb_get_ntohl(tvb, offset+8); if (tree) { proto_tree_add_uint(tree, hf_nfs_read_offset, tvb, offset+0, 4, offset_value); proto_tree_add_uint(tree, hf_nfs_read_count, tvb, offset+4, 4, count); proto_tree_add_uint(tree, hf_nfs_read_totalcount, tvb, offset+8, 4, totalcount); } offset += 12; return offset; } /* RFC 1094, Page 7 */ int dissect_nfs2_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_fattr(tvb, offset, pinfo, tree, "attributes"); offset = dissect_nfsdata(tvb, offset, pinfo, tree, hf_nfs_data); break; default: /* do nothing */ break; } return offset; } /* RFC 1094, Page 8 */ int dissect_nfs2_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 beginoffset; guint32 offset_value; guint32 totalcount; offset = dissect_fhandle(tvb, offset, pinfo, tree, "file" ); beginoffset = tvb_get_ntohl(tvb, offset+0); offset_value = tvb_get_ntohl(tvb, offset+4); totalcount = tvb_get_ntohl(tvb, offset+8); if (tree) { proto_tree_add_uint(tree, hf_nfs_write_beginoffset, tvb, offset+0, 4, beginoffset); proto_tree_add_uint(tree, hf_nfs_write_offset, tvb, offset+4, 4, offset_value); proto_tree_add_uint(tree, hf_nfs_write_totalcount, tvb, offset+8, 4, totalcount); } offset += 12; offset = dissect_nfsdata(tvb, offset, pinfo, tree, hf_nfs_data); return offset; } /* RFC 1094, Page 8 */ int dissect_nfs2_createargs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_diropargs(tvb, offset, pinfo, tree, "where" ); offset = dissect_sattr (tvb, offset, pinfo, tree, "attributes"); return offset; } /* RFC 1094, Page 9 */ int dissect_nfs2_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_diropargs(tvb, offset, pinfo, tree, "from"); offset = dissect_diropargs(tvb, offset, pinfo, tree, "to" ); return offset; } /* RFC 1094, Page 9 */ int dissect_nfs2_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_fhandle (tvb, offset, pinfo, tree, "from"); offset = dissect_diropargs(tvb, offset, pinfo, tree, "to" ); return offset; } /* RFC 1094, Page 10 */ int dissect_nfs2_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_diropargs(tvb, offset, pinfo, tree, "from" ); offset = dissect_path (tvb, offset, pinfo, tree, hf_nfs_symlink_to); offset = dissect_sattr (tvb, offset, pinfo, tree, "attributes" ); return offset; } /* RFC 1094, Page 11 */ int dissect_nfs2_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 cookie; guint32 count; offset = dissect_fhandle (tvb, offset, pinfo, tree, "dir"); cookie = tvb_get_ntohl(tvb, offset+ 0); count = tvb_get_ntohl(tvb, offset+ 4); if (tree) { proto_tree_add_uint(tree, hf_nfs_readdir_cookie, tvb, offset+ 0, 4, cookie); proto_tree_add_uint(tree, hf_nfs_readdir_count, tvb, offset+ 4, 4, count); } offset += 8; return offset; } /* RFC 1094, Page 11 */ int dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { proto_item* entry_item = NULL; proto_tree* entry_tree = NULL; int old_offset = offset; guint32 fileid; guint32 cookie; char *name; if (tree) { entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, tvb_length_remaining(tvb, offset), FALSE); entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry); } fileid = tvb_get_ntohl(tvb, offset + 0); if (entry_tree) proto_tree_add_uint(entry_tree, hf_nfs_readdir_entry_fileid, tvb, offset+0, 4, fileid); offset += 4; offset = dissect_filename(tvb, offset, pinfo, entry_tree, hf_nfs_readdir_entry_name, &name); if (entry_item) proto_item_set_text(entry_item, "Entry: file ID %u, name %s", fileid, name); g_free(name); cookie = tvb_get_ntohl(tvb, offset + 0); if (entry_tree) proto_tree_add_uint(entry_tree, hf_nfs_readdir_entry_cookie, tvb, offset+0, 4, cookie); offset += 4; /* now we know, that a readdir entry is shorter */ if (entry_item) { proto_item_set_len(entry_item, offset - old_offset); } return offset; } /* RFC 1094, Page 11 */ int dissect_nfs2_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 eof_value; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_rpc_list(tvb, pinfo, tree, offset, dissect_readdir_entry); eof_value = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_readdir_eof, tvb, offset+ 0, 4, eof_value); offset += 4; break; default: /* do nothing */ break; } return offset; } /* RFC 1094, Page 12 */ int dissect_nfs2_statfs_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 tsize; guint32 bsize; guint32 blocks; guint32 bfree; guint32 bavail; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: tsize = tvb_get_ntohl(tvb, offset+ 0); bsize = tvb_get_ntohl(tvb, offset+ 4); blocks = tvb_get_ntohl(tvb, offset+ 8); bfree = tvb_get_ntohl(tvb, offset+12); bavail = tvb_get_ntohl(tvb, offset+16); if (tree) { proto_tree_add_uint(tree, hf_nfs_statfs_tsize, tvb, offset+ 0, 4, tsize); proto_tree_add_uint(tree, hf_nfs_statfs_bsize, tvb, offset+ 4, 4, bsize); proto_tree_add_uint(tree, hf_nfs_statfs_blocks, tvb, offset+ 8, 4, blocks); proto_tree_add_uint(tree, hf_nfs_statfs_bfree, tvb, offset+12, 4, bfree); proto_tree_add_uint(tree, hf_nfs_statfs_bavail, tvb, offset+16, 4, bavail); } offset += 20; break; default: /* do nothing */ break; } return offset; } /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: type of arguments is "void". */ static const vsff nfs2_proc[] = { { 0, "NULL", /* OK */ NULL, NULL }, { 1, "GETATTR", /* OK */ dissect_nfs2_fhandle_call, dissect_nfs2_attrstat_reply }, { 2, "SETATTR", /* OK */ dissect_nfs2_setattr_call, dissect_nfs2_attrstat_reply }, { 3, "ROOT", /* OK */ NULL, NULL }, { 4, "LOOKUP", /* OK */ dissect_nfs2_diropargs_call, dissect_nfs2_diropres_reply }, { 5, "READLINK", /* OK */ dissect_nfs2_fhandle_call, dissect_nfs2_readlink_reply }, { 6, "READ", /* OK */ dissect_nfs2_read_call, dissect_nfs2_read_reply }, { 7, "WRITECACHE", /* OK */ NULL, NULL }, { 8, "WRITE", /* OK */ dissect_nfs2_write_call, dissect_nfs2_attrstat_reply }, { 9, "CREATE", /* OK */ dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply }, { 10, "REMOVE", /* OK */ dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply }, { 11, "RENAME", /* OK */ dissect_nfs2_rename_call, dissect_nfs2_stat_reply }, { 12, "LINK", /* OK */ dissect_nfs2_link_call, dissect_nfs2_stat_reply }, { 13, "SYMLINK", /* OK */ dissect_nfs2_symlink_call, dissect_nfs2_stat_reply }, { 14, "MKDIR", /* OK */ dissect_nfs2_createargs_call, dissect_nfs2_diropres_reply }, { 15, "RMDIR", /* OK */ dissect_nfs2_diropargs_call, dissect_nfs2_stat_reply }, { 16, "READDIR", /* OK */ dissect_nfs2_readdir_call, dissect_nfs2_readdir_reply }, { 17, "STATFS", /* OK */ dissect_nfs2_fhandle_call, dissect_nfs2_statfs_reply }, { 0,NULL,NULL,NULL } }; /* end of NFS Version 2 */ /***************************/ /* NFS Version 3, RFC 1813 */ /***************************/ /* RFC 1813, Page 15 */ int dissect_filename3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf, char **string_ret) { offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret); return offset; } /* RFC 1813, Page 15 */ int dissect_nfspath3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf) { offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, NULL); return offset; } /* RFC 1813, Page 15 */ int dissect_cookieverf3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree_add_text(tree, tvb, offset, NFS3_COOKIEVERFSIZE, "Verifier: Opaque Data"); offset += NFS3_COOKIEVERFSIZE; return offset; } /* RFC 1813, Page 16 */ int dissect_createverf3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree_add_text(tree, tvb, offset, NFS3_CREATEVERFSIZE, "Verifier: Opaque Data"); offset += NFS3_CREATEVERFSIZE; return offset; } /* RFC 1813, Page 16 */ int dissect_writeverf3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree_add_text(tree, tvb, offset, NFS3_WRITEVERFSIZE, "Verifier: Opaque Data"); offset += NFS3_WRITEVERFSIZE; return offset; } /* RFC 1813, Page 16 */ int dissect_mode3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 mode3; proto_item* mode3_item = NULL; proto_tree* mode3_tree = NULL; mode3 = tvb_get_ntohl(tvb, offset+0); if (tree) { mode3_item = proto_tree_add_text(tree, tvb, offset, 4, "%s: 0%o", name, mode3); if (mode3_item) mode3_tree = proto_item_add_subtree(mode3_item, ett_nfs_mode3); } /* RFC 1813, Page 23 */ if (mode3_tree) { proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x800, 12, "Set user id on exec", "not SUID")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x400, 12, "Set group id on exec", "not SGID")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x200, 12, "Save swapped text even after use", "not save swapped text")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x100, 12, "Read permission for owner", "no Read permission for owner")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x80, 12, "Write permission for owner", "no Write permission for owner")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x40, 12, "Execute permission for owner", "no Execute permission for owner")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x20, 12, "Read permission for group", "no Read permission for group")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x10, 12, "Write permission for group", "no Write permission for group")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x8, 12, "Execute permission for group", "no Execute permission for group")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x4, 12, "Read permission for others", "no Read permission for others")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x2, 12, "Write permission for others", "no Write permission for others")); proto_tree_add_text(mode3_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(mode3, 0x1, 12, "Execute permission for others", "no Execute permission for others")); } offset += 4; return offset; } /* RFC 1813, Page 16,17 */ const value_string names_nfs_nfsstat3[] = { { 0, "OK" }, { 1, "ERR_PERM" }, { 2, "ERR_NOENT" }, { 5, "ERR_IO" }, { 6, "ERR_NX_IO" }, { 13, "ERR_ACCES" }, { 17, "ERR_EXIST" }, { 18, "ERR_XDEV" }, { 19, "ERR_NODEV" }, { 20, "ERR_NOTDIR" }, { 21, "ERR_ISDIR" }, { 22, "ERR_INVAL" }, { 27, "ERR_FBIG" }, { 28, "ERR_NOSPC" }, { 30, "ERR_ROFS" }, { 31, "ERR_MLINK" }, { 63, "ERR_NAMETOOLONG" }, { 66, "ERR_NOTEMPTY" }, { 69, "ERR_DQUOT" }, { 70, "ERR_STALE" }, { 71, "ERR_REMOTE" }, { 10001, "ERR_BADHANDLE" }, { 10002, "ERR_NOT_SYNC" }, { 10003, "ERR_BAD_COOKIE" }, { 10004, "ERR_NOTSUPP" }, { 10005, "ERR_TOOSMALL" }, { 10006, "ERR_SERVERFAULT" }, { 10007, "ERR_BADTYPE" }, { 10008, "ERR_JUKEBOX" }, { 0, NULL } }; /* RFC 1813, Page 16 */ int dissect_nfsstat3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,guint32 *status) { guint32 nfsstat3; nfsstat3 = tvb_get_ntohl(tvb, offset+0); if (tree) { proto_tree_add_uint(tree, hf_nfs_nfsstat3, tvb, offset, 4, nfsstat3); } offset += 4; *status = nfsstat3; return offset; } const value_string names_nfs_ftype3[] = { { NF3REG, "Regular File" }, { NF3DIR, "Directory" }, { NF3BLK, "Block Special Device" }, { NF3CHR, "Character Special Device" }, { NF3LNK, "Symbolic Link" }, { NF3SOCK,"Socket" }, { NF3FIFO,"Named Pipe" }, { 0, NULL } }; /* RFC 1813, Page 20 */ int dissect_ftype3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf, guint32* ftype3) { guint32 type; type = tvb_get_ntohl(tvb, offset+0); if (tree) { proto_tree_add_uint(tree, hf, tvb, offset, 4, type); } offset += 4; *ftype3 = type; return offset; } /* RFC 1813, Page 20 */ int dissect_specdata3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 specdata1; guint32 specdata2; proto_item* specdata3_item; proto_tree* specdata3_tree = NULL; specdata1 = tvb_get_ntohl(tvb, offset+0); specdata2 = tvb_get_ntohl(tvb, offset+4); if (tree) { specdata3_item = proto_tree_add_text(tree, tvb, offset, 8, "%s: %u,%u", name, specdata1, specdata2); if (specdata3_item) specdata3_tree = proto_item_add_subtree(specdata3_item, ett_nfs_specdata3); } if (specdata3_tree) { proto_tree_add_text(specdata3_tree, tvb,offset+0,4, "specdata1: %u", specdata1); proto_tree_add_text(specdata3_tree, tvb,offset+4,4, "specdata2: %u", specdata2); } offset += 8; return offset; } /* RFC 1813, Page 21 */ int dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { guint fh3_len; guint fh3_len_full; guint fh3_fill; proto_item* fitem; proto_tree* ftree = NULL; fh3_len = tvb_get_ntohl(tvb, offset+0); fh3_len_full = rpc_roundup(fh3_len); fh3_fill = fh3_len_full - fh3_len; if (tree) { fitem = proto_tree_add_text(tree, tvb, offset, 4+fh3_len_full, "%s", name); if (fitem) ftree = proto_item_add_subtree(fitem, ett_nfs_fh3); } if (ftree) { proto_tree_add_uint(ftree, hf_nfs_fh_length, tvb, offset+0, 4, fh3_len); dissect_fhandle_data(tvb, offset+4, pinfo, ftree, fh3_len); } offset += 4 + fh3_len_full; return offset; } /* RFC 1813, Page 21 */ int dissect_nfstime3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,char* name) { guint32 seconds; guint32 nseconds; proto_item* time_item; proto_tree* time_tree = NULL; seconds = tvb_get_ntohl(tvb, offset+0); nseconds = tvb_get_ntohl(tvb, offset+4); if (tree) { time_item = proto_tree_add_text(tree, tvb, offset, 8, "%s: %u.%09u", name, seconds, nseconds); if (time_item) time_tree = proto_item_add_subtree(time_item, ett_nfs_nfstime3); } if (time_tree) { proto_tree_add_text(time_tree, tvb,offset+0,4, "seconds: %u", seconds); proto_tree_add_text(time_tree, tvb,offset+4,4, "nano seconds: %u", nseconds); } offset += 8; return offset; } /* RFC 1813, Page 22 */ int dissect_fattr3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* fattr3_item = NULL; proto_tree* fattr3_tree = NULL; int old_offset = offset; guint32 type; if (tree) { fattr3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); fattr3_tree = proto_item_add_subtree(fattr3_item, ett_nfs_fattr3); } offset = dissect_ftype3(tvb,offset,pinfo,fattr3_tree,hf_nfs_fattr3_type,&type); offset = dissect_mode3(tvb,offset,pinfo,fattr3_tree,"mode"); offset = dissect_rpc_uint32(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_nlink, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_uid, offset); offset = dissect_rpc_uint32(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_gid, offset); offset = dissect_rpc_uint64(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_size, offset); offset = dissect_rpc_uint64(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_used, offset); offset = dissect_specdata3(tvb,offset,pinfo,fattr3_tree,"rdev"); offset = dissect_rpc_uint64(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_fsid, offset); offset = dissect_rpc_uint64(tvb, pinfo, fattr3_tree, hf_nfs_fattr3_fileid, offset); offset = dissect_nfstime3 (tvb,offset,pinfo,fattr3_tree,"atime"); offset = dissect_nfstime3 (tvb,offset,pinfo,fattr3_tree,"mtime"); offset = dissect_nfstime3 (tvb,offset,pinfo,fattr3_tree,"ctime"); /* now we know, that fattr3 is shorter */ if (fattr3_item) { proto_item_set_len(fattr3_item, offset - old_offset); } return offset; } const value_string value_follows[] = { { 0, "no value" }, { 1, "value follows"}, { 0, NULL } }; /* RFC 1813, Page 23 */ int dissect_post_op_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* post_op_attr_item = NULL; proto_tree* post_op_attr_tree = NULL; int old_offset = offset; guint32 attributes_follow; if (tree) { post_op_attr_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, ett_nfs_post_op_attr); } attributes_follow = tvb_get_ntohl(tvb, offset+0); proto_tree_add_text(post_op_attr_tree, tvb, offset, 4, "attributes_follow: %s (%u)", val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow); offset += 4; switch (attributes_follow) { case TRUE: offset = dissect_fattr3(tvb, offset, pinfo, post_op_attr_tree, "attributes"); break; case FALSE: /* void */ break; } /* now we know, that post_op_attr_tree is shorter */ if (post_op_attr_item) { proto_item_set_len(post_op_attr_item, offset - old_offset); } return offset; } /* RFC 1813, Page 24 */ int dissect_wcc_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* wcc_attr_item = NULL; proto_tree* wcc_attr_tree = NULL; int old_offset = offset; if (tree) { wcc_attr_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, ett_nfs_wcc_attr); } offset = dissect_rpc_uint64(tvb, pinfo, wcc_attr_tree, hf_nfs_wcc_attr_size, offset); offset = dissect_nfstime3(tvb, offset, pinfo, wcc_attr_tree, "mtime"); offset = dissect_nfstime3(tvb, offset, pinfo, wcc_attr_tree, "ctime"); /* now we know, that wcc_attr_tree is shorter */ if (wcc_attr_item) { proto_item_set_len(wcc_attr_item, offset - old_offset); } return offset; } /* RFC 1813, Page 24 */ int dissect_pre_op_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* pre_op_attr_item = NULL; proto_tree* pre_op_attr_tree = NULL; int old_offset = offset; guint32 attributes_follow; if (tree) { pre_op_attr_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, ett_nfs_pre_op_attr); } attributes_follow = tvb_get_ntohl(tvb, offset+0); proto_tree_add_text(pre_op_attr_tree, tvb, offset, 4, "attributes_follow: %s (%u)", val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow); offset += 4; switch (attributes_follow) { case TRUE: offset = dissect_wcc_attr(tvb, offset, pinfo, pre_op_attr_tree, "attributes"); break; case FALSE: /* void */ break; } /* now we know, that pre_op_attr_tree is shorter */ if (pre_op_attr_item) { proto_item_set_len(pre_op_attr_item, offset - old_offset); } return offset; } /* RFC 1813, Page 24 */ int dissect_wcc_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* wcc_data_item = NULL; proto_tree* wcc_data_tree = NULL; int old_offset = offset; if (tree) { wcc_data_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); wcc_data_tree = proto_item_add_subtree(wcc_data_item, ett_nfs_wcc_data); } offset = dissect_pre_op_attr (tvb, offset, pinfo, wcc_data_tree, "before"); offset = dissect_post_op_attr(tvb, offset, pinfo, wcc_data_tree, "after" ); /* now we know, that wcc_data is shorter */ if (wcc_data_item) { proto_item_set_len(wcc_data_item, offset - old_offset); } return offset; } /* RFC 1813, Page 25 */ int dissect_post_op_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* post_op_fh3_item = NULL; proto_tree* post_op_fh3_tree = NULL; int old_offset = offset; guint32 handle_follows; if (tree) { post_op_fh3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); post_op_fh3_tree = proto_item_add_subtree(post_op_fh3_item, ett_nfs_post_op_fh3); } handle_follows = tvb_get_ntohl(tvb, offset+0); proto_tree_add_text(post_op_fh3_tree, tvb, offset, 4, "handle_follows: %s (%u)", val_to_str(handle_follows,value_follows,"Unknown"), handle_follows); offset += 4; switch (handle_follows) { case TRUE: offset = dissect_nfs_fh3(tvb, offset, pinfo, post_op_fh3_tree, "handle"); break; case FALSE: /* void */ break; } /* now we know, that post_op_fh3_tree is shorter */ if (post_op_fh3_item) { proto_item_set_len(post_op_fh3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 25 */ int dissect_set_mode3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_mode3_item = NULL; proto_tree* set_mode3_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,value_follows,"Unknown"); if (tree) { set_mode3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_mode3_tree = proto_item_add_subtree(set_mode3_item, ett_nfs_set_mode3); } if (set_mode3_tree) proto_tree_add_text(set_mode3_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case 1: offset = dissect_mode3(tvb, offset, pinfo, set_mode3_tree, "mode"); break; default: /* void */ break; } /* now we know, that set_mode3 is shorter */ if (set_mode3_item) { proto_item_set_len(set_mode3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 26 */ int dissect_set_uid3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_uid3_item = NULL; proto_tree* set_uid3_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,value_follows,"Unknown"); if (tree) { set_uid3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_uid3_tree = proto_item_add_subtree(set_uid3_item, ett_nfs_set_uid3); } if (set_uid3_tree) proto_tree_add_text(set_uid3_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case 1: offset = dissect_rpc_uint32(tvb, pinfo, set_uid3_tree, hf_nfs_uid3, offset); break; default: /* void */ break; } /* now we know, that set_uid3 is shorter */ if (set_uid3_item) { proto_item_set_len(set_uid3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 26 */ int dissect_set_gid3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_gid3_item = NULL; proto_tree* set_gid3_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,value_follows,"Unknown"); if (tree) { set_gid3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_gid3_tree = proto_item_add_subtree(set_gid3_item, ett_nfs_set_gid3); } if (set_gid3_tree) proto_tree_add_text(set_gid3_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case 1: offset = dissect_rpc_uint32(tvb, pinfo, set_gid3_tree, hf_nfs_gid3, offset); break; default: /* void */ break; } /* now we know, that set_gid3 is shorter */ if (set_gid3_item) { proto_item_set_len(set_gid3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 26 */ int dissect_set_size3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_size3_item = NULL; proto_tree* set_size3_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,value_follows,"Unknown"); if (tree) { set_size3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_size3_tree = proto_item_add_subtree(set_size3_item, ett_nfs_set_size3); } if (set_size3_tree) proto_tree_add_text(set_size3_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case 1: offset = dissect_rpc_uint64(tvb, pinfo, set_size3_tree, hf_nfs_set_size3_size, offset); break; default: /* void */ break; } /* now we know, that set_size3 is shorter */ if (set_size3_item) { proto_item_set_len(set_size3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 25 */ #define DONT_CHANGE 0 #define SET_TO_SERVER_TIME 1 #define SET_TO_CLIENT_TIME 2 const value_string time_how[] = { { DONT_CHANGE, "don't change" }, { SET_TO_SERVER_TIME, "set to server time" }, { SET_TO_CLIENT_TIME, "set to client time" }, { 0, NULL } }; /* RFC 1813, Page 26 */ int dissect_set_atime(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_atime_item = NULL; proto_tree* set_atime_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,time_how,"Unknown"); if (tree) { set_atime_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_atime_tree = proto_item_add_subtree(set_atime_item, ett_nfs_set_atime); } if (set_atime_tree) proto_tree_add_text(set_atime_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case SET_TO_CLIENT_TIME: if (set_atime_item) offset = dissect_nfstime3(tvb, offset, pinfo, set_atime_tree, "atime"); break; default: /* void */ break; } /* now we know, that set_atime is shorter */ if (set_atime_item) { proto_item_set_len(set_atime_item, offset - old_offset); } return offset; } /* RFC 1813, Page 26 */ int dissect_set_mtime(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* set_mtime_item = NULL; proto_tree* set_mtime_tree = NULL; int old_offset = offset; guint32 set_it; char* set_it_name; set_it = tvb_get_ntohl(tvb, offset+0); set_it_name = val_to_str(set_it,time_how,"Unknown"); if (tree) { set_mtime_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, set_it_name); set_mtime_tree = proto_item_add_subtree(set_mtime_item, ett_nfs_set_mtime); } if (set_mtime_tree) proto_tree_add_text(set_mtime_tree, tvb, offset, 4, "set_it: %s (%u)", set_it_name, set_it); offset += 4; switch (set_it) { case SET_TO_CLIENT_TIME: if (set_mtime_item) offset = dissect_nfstime3(tvb, offset, pinfo, set_mtime_tree, "atime"); break; default: /* void */ break; } /* now we know, that set_mtime is shorter */ if (set_mtime_item) { proto_item_set_len(set_mtime_item, offset - old_offset); } return offset; } /* RFC 1813, Page 25..27 */ int dissect_sattr3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* sattr3_item = NULL; proto_tree* sattr3_tree = NULL; int old_offset = offset; if (tree) { sattr3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); sattr3_tree = proto_item_add_subtree(sattr3_item, ett_nfs_sattr3); } offset = dissect_set_mode3(tvb, offset, pinfo, sattr3_tree, "mode"); offset = dissect_set_uid3 (tvb, offset, pinfo, sattr3_tree, "uid"); offset = dissect_set_gid3 (tvb, offset, pinfo, sattr3_tree, "gid"); offset = dissect_set_size3(tvb, offset, pinfo, sattr3_tree, "size"); offset = dissect_set_atime(tvb, offset, pinfo, sattr3_tree, "atime"); offset = dissect_set_mtime(tvb, offset, pinfo, sattr3_tree, "mtime"); /* now we know, that sattr3 is shorter */ if (sattr3_item) { proto_item_set_len(sattr3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 27 */ int dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { proto_item* diropargs3_item = NULL; proto_tree* diropargs3_tree = NULL; int old_offset = offset; if (tree) { diropargs3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s", name); diropargs3_tree = proto_item_add_subtree(diropargs3_item, ett_nfs_diropargs3); } offset = dissect_nfs_fh3(tvb, offset, pinfo, diropargs3_tree, "dir"); offset = dissect_filename3(tvb, offset, pinfo, diropargs3_tree, hf_nfs_name, NULL); /* now we know, that diropargs3 is shorter */ if (diropargs3_item) { proto_item_set_len(diropargs3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 27 */ int dissect_nfs3_diropargs3_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object"); return offset; } /* RFC 1813, Page 40 */ int dissect_access(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name) { guint32 access; proto_item* access_item = NULL; proto_tree* access_tree = NULL; access = tvb_get_ntohl(tvb, offset+0); if (tree) { access_item = proto_tree_add_text(tree, tvb, offset, 4, "%s: 0x%02x", name, access); if (access_item) access_tree = proto_item_add_subtree(access_item, ett_nfs_access); } if (access_tree) { proto_tree_add_text(access_tree, tvb, offset, 4, "%s READ", decode_boolean_bitfield(access, 0x001, 6, "allow", "not allow")); proto_tree_add_text(access_tree, tvb, offset, 4, "%s LOOKUP", decode_boolean_bitfield(access, 0x002, 6, "allow", "not allow")); proto_tree_add_text(access_tree, tvb, offset, 4, "%s MODIFY", decode_boolean_bitfield(access, 0x004, 6, "allow", "not allow")); proto_tree_add_text(access_tree, tvb, offset, 4, "%s EXTEND", decode_boolean_bitfield(access, 0x008, 6, "allow", "not allow")); proto_tree_add_text(access_tree, tvb, offset, 4, "%s DELETE", decode_boolean_bitfield(access, 0x010, 6, "allow", "not allow")); proto_tree_add_text(access_tree, tvb, offset, 4, "%s EXECUTE", decode_boolean_bitfield(access, 0x020, 6, "allow", "not allow")); } offset += 4; return offset; } /* NFS3 file handle dissector */ int dissect_nfs3_nfs_fh3_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object"); return offset; } /* generic NFS3 reply dissector */ int dissect_nfs3_any_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); return offset; } /* RFC 1813, Page 32,33 */ int dissect_nfs3_getattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object"); return offset; } /* RFC 1813, Page 32,33 */ int dissect_nfs3_getattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_fattr3(tvb, offset, pinfo, tree, "obj_attributes"); break; default: /* void */ break; } return offset; } /* RFC 1813, Page 33 */ int dissect_sattrguard3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree, char *name) { proto_item* sattrguard3_item = NULL; proto_tree* sattrguard3_tree = NULL; int old_offset = offset; guint32 check; char* check_name; check = tvb_get_ntohl(tvb, offset+0); check_name = val_to_str(check,value_follows,"Unknown"); if (tree) { sattrguard3_item = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "%s: %s", name, check_name); sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, ett_nfs_sattrguard3); } if (sattrguard3_tree) proto_tree_add_text(sattrguard3_tree, tvb, offset, 4, "check: %s (%u)", check_name, check); offset += 4; switch (check) { case TRUE: offset = dissect_nfstime3(tvb, offset, pinfo, sattrguard3_tree, "obj_ctime"); break; case FALSE: /* void */ break; } /* now we know, that sattrguard3 is shorter */ if (sattrguard3_item) { proto_item_set_len(sattrguard3_item, offset - old_offset); } return offset; } /* RFC 1813, Page 33..36 */ int dissect_nfs3_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3 (tvb, offset, pinfo, tree, "object"); offset = dissect_sattr3 (tvb, offset, pinfo, tree, "new_attributes"); offset = dissect_sattrguard3(tvb, offset, pinfo, tree, "guard"); return offset; } /* RFC 1813, Page 33..36 */ int dissect_nfs3_setattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc"); break; default: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc"); break; } return offset; } /* RFC 1813, Page 37..39 */ int dissect_nfs3_lookup_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "what"); return offset; } /* RFC 1813, Page 37..39 */ int dissect_nfs3_lookup_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object"); offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); break; } return offset; } /* RFC 1813, Page 40..43 */ int dissect_nfs3_access_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object"); offset = dissect_access (tvb, offset, pinfo, tree, "access"); return offset; } /* RFC 1813, Page 40..43 */ int dissect_nfs3_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); offset = dissect_access(tvb, offset, pinfo, tree, "access"); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); break; } return offset; } /* RFC 1813, Page 44,45 */ int dissect_nfs3_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "symlink_attributes"); offset = dissect_nfspath3(tvb, offset, pinfo, tree, hf_nfs_readlink_data); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "symlink_attributes"); break; } return offset; } /* RFC 1813, Page 46..48 */ int dissect_nfs3_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_offset3, offset); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); return offset; } /* RFC 1813, Page 46..48 */ int dissect_nfs3_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "file_attributes"); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); offset = dissect_rpc_bool(tvb, pinfo, tree, hf_nfs_read_eof, offset); offset = dissect_nfsdata(tvb, offset, pinfo, tree, hf_nfs_data); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "file_attributes"); break; } return offset; } /* RFC 1813, Page 49 */ static const value_string names_stable_how[] = { { UNSTABLE, "UNSTABLE" }, { DATA_SYNC, "DATA_SYNC" }, { FILE_SYNC, "FILE_SYNC" }, { 0, NULL } }; /* RFC 1813, Page 49 */ int dissect_stable_how(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree, int hfindex) { guint32 stable_how; stable_how = tvb_get_ntohl(tvb,offset+0); if (tree) { proto_tree_add_uint(tree, hfindex, tvb, offset, 4, stable_how); } offset += 4; return offset; } /* RFC 1813, Page 49..54 */ int dissect_nfs3_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3 (tvb, offset, pinfo, tree, "file"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_offset3, offset); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); offset = dissect_stable_how(tvb, offset, pinfo, tree, hf_nfs_write_stable); offset = dissect_nfsdata (tvb, offset, pinfo, tree, hf_nfs_data); return offset; } /* RFC 1813, Page 49..54 */ int dissect_nfs3_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_wcc_data (tvb, offset, pinfo, tree, "file_wcc"); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); offset = dissect_stable_how(tvb, offset, pinfo, tree, hf_nfs_write_committed); offset = dissect_writeverf3(tvb, offset, pinfo, tree); break; default: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc"); break; } return offset; } /* RFC 1813, Page 54 */ static const value_string names_createmode3[] = { { UNCHECKED, "UNCHECKED" }, { GUARDED, "GUARDED" }, { EXCLUSIVE, "EXCLUSIVE" }, { 0, NULL } }; /* RFC 1813, Page 54 */ int dissect_createmode3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree, guint32* mode) { guint32 mode_value; mode_value = tvb_get_ntohl(tvb, offset + 0); if (tree) { proto_tree_add_uint(tree, hf_nfs_createmode3, tvb, offset+0, 4, mode_value); } offset += 4; *mode = mode_value; return offset; } /* RFC 1813, Page 54..58 */ int dissect_nfs3_create_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 mode; offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "where"); offset = dissect_createmode3(tvb, offset, pinfo, tree, &mode); switch (mode) { case UNCHECKED: case GUARDED: offset = dissect_sattr3(tvb, offset, pinfo, tree, "obj_attributes"); break; case EXCLUSIVE: offset = dissect_createverf3(tvb, offset, pinfo, tree); break; } return offset; } /* RFC 1813, Page 54..58 */ int dissect_nfs3_create_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_fh3 (tvb, offset, pinfo, tree, "obj"); offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc"); break; default: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc"); break; } return offset; } /* RFC 1813, Page 58..60 */ int dissect_nfs3_mkdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where"); offset = dissect_sattr3 (tvb, offset, pinfo, tree, "attributes"); return offset; } /* RFC 1813, Page 61..63 */ int dissect_nfs3_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where"); offset = dissect_sattr3 (tvb, offset, pinfo, tree, "symlink_attributes"); offset = dissect_nfspath3 (tvb, offset, pinfo, tree, hf_nfs_symlink_to); return offset; } /* RFC 1813, Page 63..66 */ int dissect_nfs3_mknod_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 type; offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where"); offset = dissect_ftype3(tvb, offset, pinfo, tree, hf_nfs_ftype3, &type); switch (type) { case NF3CHR: case NF3BLK: offset = dissect_sattr3(tvb, offset, pinfo, tree, "dev_attributes"); offset = dissect_specdata3(tvb, offset, pinfo, tree, "spec"); break; case NF3SOCK: case NF3FIFO: offset = dissect_sattr3(tvb, offset, pinfo, tree, "pipe_attributes"); break; default: /* nothing to do */ break; } return offset; } /* RFC 1813, Page 67..69 */ int dissect_nfs3_remove_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_wcc_data (tvb, offset, pinfo, tree, "dir_wcc"); break; default: offset = dissect_wcc_data (tvb, offset, pinfo, tree, "dir_wcc"); break; } return offset; } /* RFC 1813, Page 71..74 */ int dissect_nfs3_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_diropargs3(tvb, offset, pinfo, tree, "from"); offset = dissect_diropargs3(tvb, offset, pinfo, tree, "to"); return offset; } /* RFC 1813, Page 71..74 */ int dissect_nfs3_rename_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc"); offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc"); break; default: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc"); offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc"); break; } return offset; } /* RFC 1813, Page 74..76 */ int dissect_nfs3_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3 (tvb, offset, pinfo, tree, "file"); offset = dissect_diropargs3(tvb, offset, pinfo, tree, "link"); return offset; } /* RFC 1813, Page 74..76 */ int dissect_nfs3_link_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "file_attributes"); offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc"); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "file_attributes"); offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc"); break; } return offset; } /* RFC 1813, Page 76..80 */ int dissect_nfs3_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3 (tvb, offset, pinfo, tree, "dir"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_cookie3, offset); offset = dissect_cookieverf3(tvb, offset, pinfo, tree); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); return offset; } /* RFC 1813, Page 76..80 */ int dissect_entry3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { proto_item* entry_item = NULL; proto_tree* entry_tree = NULL; int old_offset = offset; char *name; if (tree) { entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, tvb_length_remaining(tvb, offset), FALSE); entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry); } offset = dissect_rpc_uint64(tvb, pinfo, entry_tree, hf_nfs_readdir_entry3_fileid, offset); offset = dissect_filename3(tvb, offset, pinfo, entry_tree, hf_nfs_readdir_entry3_name, &name); if (entry_item) proto_item_set_text(entry_item, "Entry: name %s", name); g_free(name); offset = dissect_rpc_uint64(tvb, pinfo, entry_tree, hf_nfs_readdir_entry3_cookie, offset); /* now we know, that a readdir entry is shorter */ if (entry_item) { proto_item_set_len(entry_item, offset - old_offset); } return offset; } /* RFC 1813, Page 76..80 */ int dissect_nfs3_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 eof_value; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); offset = dissect_cookieverf3(tvb, offset, pinfo, tree); offset = dissect_rpc_list(tvb, pinfo, tree, offset, dissect_entry3); eof_value = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_readdir_eof, tvb, offset+ 0, 4, eof_value); offset += 4; break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); break; } return offset; } /* RFC 1813, Page 80..83 */ int dissect_nfs3_readdirplus_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3 (tvb, offset, pinfo, tree, "dir"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_cookie3, offset); offset = dissect_cookieverf3(tvb, offset, pinfo, tree); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3_dircount, offset); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3_maxcount, offset); return offset; } /* RFC 1813, Page 80..83 */ int dissect_entryplus3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { proto_item* entry_item = NULL; proto_tree* entry_tree = NULL; int old_offset = offset; char *name; if (tree) { entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, tvb_length_remaining(tvb, offset), FALSE); entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry); } offset = dissect_rpc_uint64(tvb, pinfo, entry_tree, hf_nfs_readdirplus_entry_fileid, offset); offset = dissect_filename3(tvb, offset, pinfo, entry_tree, hf_nfs_readdirplus_entry_name, &name); if (entry_item) proto_item_set_text(entry_item, "Entry: name %s", name); g_free(name); offset = dissect_rpc_uint64(tvb, pinfo, entry_tree, hf_nfs_readdirplus_entry_cookie, offset); offset = dissect_post_op_attr(tvb, offset, pinfo, entry_tree, "name_attributes"); offset = dissect_post_op_fh3(tvb, offset, pinfo, entry_tree, "name_handle"); /* now we know, that a readdirplus entry is shorter */ if (entry_item) { proto_item_set_len(entry_item, offset - old_offset); } return offset; } /* RFC 1813, Page 80..83 */ int dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 eof_value; offset = dissect_stat(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); offset = dissect_cookieverf3(tvb, offset, pinfo, tree); offset = dissect_rpc_list(tvb, pinfo, tree, offset, dissect_entryplus3); eof_value = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_readdir_eof, tvb, offset+ 0, 4, eof_value); offset += 4; break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "dir_attributes"); break; } return offset; } /* RFC 1813, Page 84..86 */ int dissect_nfs3_fsstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 invarsec; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_tbytes, offset); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_fbytes, offset); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_abytes, offset); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_tfiles, offset); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_ffiles, offset); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsstat3_resok_afiles, offset); invarsec = tvb_get_ntohl(tvb, offset + 0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsstat_invarsec, tvb, offset+0, 4, invarsec); offset += 4; break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); break; } return offset; } #define FSF3_LINK 0x0001 #define FSF3_SYMLINK 0x0002 #define FSF3_HOMOGENEOUS 0x0008 #define FSF3_CANSETTIME 0x0010 /* RFC 1813, Page 86..90 */ int dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 rtmax; guint32 rtpref; guint32 rtmult; guint32 wtmax; guint32 wtpref; guint32 wtmult; guint32 dtpref; guint32 properties; proto_item* properties_item = NULL; proto_tree* properties_tree = NULL; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); rtmax = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_rtmax, tvb, offset+0, 4, rtmax); offset += 4; rtpref = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_rtpref, tvb, offset+0, 4, rtpref); offset += 4; rtmult = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_rtmult, tvb, offset+0, 4, rtmult); offset += 4; wtmax = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_wtmax, tvb, offset+0, 4, wtmax); offset += 4; wtpref = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_wtpref, tvb, offset+0, 4, wtpref); offset += 4; wtmult = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_wtmult, tvb, offset+0, 4, wtmult); offset += 4; dtpref = tvb_get_ntohl(tvb, offset+0); if (tree) proto_tree_add_uint(tree, hf_nfs_fsinfo_dtpref, tvb, offset+0, 4, dtpref); offset += 4; offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_fsinfo_maxfilesize, offset); offset = dissect_nfstime3(tvb, offset, pinfo, tree, "time_delta"); properties = tvb_get_ntohl(tvb, offset+0); if (tree) { properties_item = proto_tree_add_uint(tree, hf_nfs_fsinfo_properties, tvb, offset+0, 4, properties); if (properties_item) properties_tree = proto_item_add_subtree(properties_item, ett_nfs_fsinfo_properties); if (properties_tree) { proto_tree_add_text(properties_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(properties, FSF3_CANSETTIME,5, "SETATTR can set time on server", "SETATTR can't set time on server")); proto_tree_add_text(properties_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(properties, FSF3_HOMOGENEOUS,5, "PATHCONF is valid for all files", "PATHCONF should be get for every single file")); proto_tree_add_text(properties_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(properties, FSF3_SYMLINK,5, "File System supports symbolic links", "File System does not symbolic hard links")); proto_tree_add_text(properties_tree, tvb, offset, 4, "%s", decode_boolean_bitfield(properties, FSF3_LINK,5, "File System supports hard links", "File System does not support hard links")); } } offset += 4; break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); break; } return offset; } /* RFC 1813, Page 90..92 */ int dissect_nfs3_pathconf_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; guint32 linkmax; guint32 name_max; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); linkmax = tvb_get_ntohl(tvb, offset + 0); if (tree) proto_tree_add_uint(tree, hf_nfs_pathconf_linkmax, tvb, offset+0, 4, linkmax); offset += 4; name_max = tvb_get_ntohl(tvb, offset + 0); if (tree) proto_tree_add_uint(tree, hf_nfs_pathconf_name_max, tvb, offset+0, 4, name_max); offset += 4; offset = dissect_rpc_bool(tvb, pinfo, tree, hf_nfs_pathconf_no_trunc, offset); offset = dissect_rpc_bool(tvb, pinfo, tree, hf_nfs_pathconf_chown_restricted, offset); offset = dissect_rpc_bool(tvb, pinfo, tree, hf_nfs_pathconf_case_insensitive, offset); offset = dissect_rpc_bool(tvb, pinfo, tree, hf_nfs_pathconf_case_preserving, offset); break; default: offset = dissect_post_op_attr(tvb, offset, pinfo, tree, "obj_attributes"); break; } return offset; } /* RFC 1813, Page 92..95 */ int dissect_nfs3_commit_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file"); offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_offset3, offset); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_count3, offset); return offset; } /* RFC 1813, Page 92..95 */ int dissect_nfs3_commit_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfsstat3(tvb, offset, pinfo, tree, &status); switch (status) { case 0: offset = dissect_wcc_data (tvb, offset, pinfo, tree, "file_wcc"); offset = dissect_writeverf3(tvb, offset, pinfo, tree); break; default: offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc"); break; } return offset; } /* 1 missing functions */ /* NFS Version 4 Protocol Draft Specification 07 */ int dissect_nfs_utf8string(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf, char **string_ret) { /* TODO: this needs to be fixed */ return dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret); } int dissect_nfs_seqid4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint seqid; seqid = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(tree, hf_nfs_seqid4, tvb, offset, 4, seqid); offset += 4; return offset; } int dissect_nfs_linktext4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { return dissect_nfs_utf8string(tvb, offset, pinfo, tree, hf_nfs_linktext4, NULL); } int dissect_nfs_specdata4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_specdata1, offset); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_specdata2, offset); return offset; } int dissect_nfs_client_id4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_clientid4_verifier, offset); offset = dissect_nfsdata(tvb, offset, pinfo, tree, hf_nfs_data); return offset; } static const value_string names_ftype4[] = { { NF4REG, "NF4REG" }, { NF4DIR, "NF4DIR" }, { NF4BLK, "NF4BLK" }, { NF4CHR, "NF4CHR" }, { NF4LNK, "NF4LNK" }, { NF4SOCK, "NF4SOCK" }, { NF4FIFO, "NF4FIFO" }, { NF4ATTRDIR, "NF4ATTRDIR" }, { NF4NAMEDATTR, "NF4NAMEDATTR" }, { 0, NULL } }; int dissect_nfs_ftype4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { guint ftype4; ftype4 = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(tree, hf_nfs_ftype4, tvb, offset, 4, ftype4); offset += 4; return offset; } int dissect_nfs_component4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { return dissect_nfs_utf8string(tvb, offset, pinfo, tree, hf_nfs_component4, NULL); } int dissect_nfs_reclaim4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_reclaim4, offset); return offset; } int dissect_nfs_length4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_nfs_length4, offset); return offset; } int dissect_nfs_opaque4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name); int dissect_nfs_lockowner4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { proto_tree *newftree = NULL; proto_item *fitem = NULL; fitem = proto_tree_add_text(tree, tvb, offset, 4, "Owner"); if (fitem) { newftree = proto_item_add_subtree(fitem, ett_nfs_lockowner4); if (newftree) { offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_clientid4, offset); offset = dissect_nfs_opaque4(tvb, offset, pinfo, newftree, "Owner"); } } return offset; } int dissect_nfs_pathname4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { guint comp_count, i; proto_item *fitem = NULL; proto_tree *newftree = NULL; comp_count=tvb_get_ntohl(tvb, offset); fitem = proto_tree_add_text(tree, tvb, offset, 4, "pathname components (%d)", comp_count); offset += 4; if (fitem) { newftree = proto_item_add_subtree(fitem, ett_nfs_pathname4); if (newftree) { for (i=0; iNFS4_OP_WRITE) break; if (fitem == NULL) break; newftree = proto_item_add_subtree(fitem, *nfsv4_operation_ett[opcode-3]); if (newftree == NULL) break; switch(opcode) { case NFS4_OP_ACCESS: offset = dissect_access(tvb, offset, pinfo, newftree, "access"); break; case NFS4_OP_CLOSE: offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_COMMIT: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_count4, offset); break; case NFS4_OP_CREATE: { guint create_type; offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "objname"); create_type = tvb_get_ntohl(tvb, offset); offset = dissect_nfs_ftype4(tvb, offset, pinfo, newftree, "type"); switch(create_type) { case NF4LNK: offset = dissect_nfs_linktext4(tvb, offset, pinfo, newftree, "linkdata"); break; case NF4BLK: case NF4CHR: offset = dissect_nfs_specdata4(tvb, offset, pinfo, newftree, "devdata"); break; case NF4SOCK: case NF4FIFO: case NF4DIR: break; default: break; } } break; case NFS4_OP_DELEGPURGE: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_clientid4, offset); break; case NFS4_OP_DELEGRETURN: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_GETATTR: offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, "attr_request", 0); break; case NFS4_OP_GETFH: break; case NFS4_OP_LINK: offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "newname"); break; case NFS4_OP_LOCK: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_locktype4, offset); offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_nfs_reclaim4(tvb, offset, pinfo, newftree, "reclaim"); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_nfs_length4(tvb, offset, pinfo, newftree, "length"); break; case NFS4_OP_LOCKT: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_locktype4, offset); offset = dissect_nfs_lockowner4(tvb, offset, pinfo, newftree, "owner"); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_nfs_length4(tvb, offset, pinfo, newftree, "length"); break; case NFS4_OP_LOCKU: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_locktype4, offset); offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_nfs_length4(tvb, offset, pinfo, newftree, "length"); break; case NFS4_OP_LOOKUP: offset = dissect_nfs_pathname4(tvb, offset, pinfo, newftree, "path"); break; case NFS4_OP_LOOKUPP: break; case NFS4_OP_NVERIFY: offset = dissect_nfs_fattr4(tvb, offset, pinfo, newftree, "obj_attributes"); break; case NFS4_OP_OPEN: offset = dissect_nfs_open_claim4(tvb, offset, pinfo, newftree, "claim"); offset = dissect_nfs_openflag4(tvb, offset, pinfo, newftree); offset = dissect_nfs_lockowner4(tvb, offset, pinfo, newftree, "Owner"); offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_nfs_open4_share_access(tvb, offset, pinfo, newftree); offset = dissect_nfs_open4_share_deny(tvb, offset, pinfo, newftree); break; case NFS4_OP_OPENATTR: break; case NFS4_OP_OPEN_CONFIRM: offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "verifier"); break; case NFS4_OP_OPEN_DOWNGRADE: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_nfs_seqid4(tvb, offset, pinfo, newftree); offset = dissect_nfs_open4_share_access(tvb, offset, pinfo, newftree); offset = dissect_nfs_open4_share_deny(tvb, offset, pinfo, newftree); break; case NFS4_OP_PUTFH: offset = dissect_nfs_fh4(tvb, offset, pinfo, newftree, "filehandle"); break; case NFS4_OP_PUTPUBFH: case NFS4_OP_PUTROOTFH: break; case NFS4_OP_READ: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_count4, offset); break; case NFS4_OP_READDIR: offset = dissect_nfs_cookie4(tvb, offset, pinfo, newftree, "cookie"); offset = dissect_nfs_cookieverf4(tvb, offset, pinfo, newftree, "cookieverf"); offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_count4_dircount, offset); offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_count4_maxcount, offset); offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, "attr", 0); break; case NFS4_OP_READLINK: break; case NFS4_OP_REMOVE: offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "target"); break; case NFS4_OP_RENAME: offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "oldname"); offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "newname"); break; case NFS4_OP_RENEW: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_RESTOREFH: case NFS4_OP_SAVEFH: break; case NFS4_OP_SECINFO: offset = dissect_nfs_component4(tvb, offset, pinfo, newftree, "name"); break; case NFS4_OP_SETATTR: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_nfs_fattr4(tvb, offset, pinfo, newftree, "obj_attributes"); break; case NFS4_OP_SETCLIENTID: { proto_tree *client_tree = NULL; fitem = proto_tree_add_text(newftree, tvb, offset, 0, "Client"); if (fitem) { client_tree = proto_item_add_subtree(fitem, ett_nfs_client_id4); if (newftree) offset = dissect_nfs_client_id4(tvb, offset, pinfo, client_tree, "client"); } fitem = proto_tree_add_text(newftree, tvb, offset, 0, "Callback"); if (fitem) { newftree = proto_item_add_subtree(fitem, ett_nfs_cb_client4); if (newftree) offset = dissect_nfs_cb_client4(tvb, offset, pinfo, newftree, "callback"); } } break; case NFS4_OP_SETCLIENTID_CONFIRM: offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "setclientid_confirm"); break; case NFS4_OP_VERIFY: offset = dissect_nfs_fattr4(tvb, offset, pinfo, newftree, "obj_attributes"); break; case NFS4_OP_WRITE: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_offset4, offset); offset = dissect_nfs_stable_how4(tvb, offset, pinfo, newftree, "stable"); offset = dissect_nfs_opaque4(tvb, offset, pinfo, newftree, "data"); break; default: break; } } return offset; } int dissect_nfs4_compound_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { offset = dissect_nfs_utf8string(tvb, offset, pinfo, tree, hf_nfs_tag4, NULL); offset = dissect_rpc_uint32(tvb, pinfo, tree, hf_nfs_minorversion, offset); offset = dissect_nfs_argop4(tvb, offset, pinfo, tree); return offset; } int dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *name) { guint ops, ops_counter; guint opcode; proto_item *fitem; proto_tree *ftree = NULL; proto_tree *newftree = NULL; guint32 status; ops = tvb_get_ntohl(tvb, offset+0); fitem = proto_tree_add_text(tree, tvb, offset, 4, "Operations (count: %d)", ops); offset += 4; if (fitem == NULL) return offset; ftree = proto_item_add_subtree(fitem, ett_nfs_resop4); if (ftree == NULL) return offset; /* error adding new subtree */ for (ops_counter = 0; ops_counter < ops; ops_counter++) { opcode = tvb_get_ntohl(tvb, offset); /* sanity check for bogus packets */ if (opcode < NFS4_OP_ACCESS || opcode > NFS4_OP_WRITE) break; fitem = proto_tree_add_uint(ftree, hf_nfs_resop4, tvb, offset, 4, opcode); offset += 4; if (fitem == NULL) break; /* error adding new item to tree */ newftree = proto_item_add_subtree(fitem, *nfsv4_operation_ett[opcode-3]); if (newftree == NULL) break; /* error adding new subtree to operation item */ offset = dissect_nfs_nfsstat4(tvb, offset, pinfo, newftree, &status); /* * With the exception of NFS4_OP_LOCK, NFS4_OP_LOCKT, and * NFS4_OP_SETATTR, all other ops do *not* return data with the * failed status code. */ if ((status != NFS4_OK) && ((opcode != NFS4_OP_LOCK) && (opcode != NFS4_OP_LOCKT) && (opcode != NFS4_OP_SETATTR))) continue; /* These parsing routines are only executed if the status is NFS4_OK */ switch(opcode) { case NFS4_OP_ACCESS: offset = dissect_access(tvb, offset, pinfo, newftree, "Supported"); offset = dissect_access(tvb, offset, pinfo, newftree, "Access"); break; case NFS4_OP_CLOSE: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_COMMIT: offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "writeverf"); break; case NFS4_OP_CREATE: offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "change_info"); break; case NFS4_OP_DELEGPURGE: /* void */ break; case NFS4_OP_DELEGRETURN: /* void */ break; case NFS4_OP_GETATTR: offset = dissect_nfs_fattr4(tvb, offset, pinfo, newftree, "obj_attributes"); break; case NFS4_OP_GETFH: offset = dissect_nfs_fh4(tvb, offset, pinfo, newftree, "Filehandle"); break; case NFS4_OP_LINK: offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "change_info"); break; case NFS4_OP_LOCK: case NFS4_OP_LOCKT: if (status == NFS4_OK) offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); else if (status == NFS4ERR_DENIED) offset = dissect_nfs_lock4denied(tvb, offset, pinfo, newftree, "denied"); break; case NFS4_OP_LOCKU: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_LOOKUP: /* void */ break; case NFS4_OP_LOOKUPP: /* void */ break; case NFS4_OP_NVERIFY: /* void */ break; case NFS4_OP_OPEN: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "change_info"); offset = dissect_nfs_open4_rflags(tvb, offset, pinfo, newftree, "result_flags"); offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "verifier"); offset = dissect_nfs_open_delegation4(tvb, offset, pinfo, newftree, "delegation"); break; case NFS4_OP_OPENATTR: /* void */ break; case NFS4_OP_OPEN_CONFIRM: case NFS4_OP_OPEN_DOWNGRADE: offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_stateid4, offset); break; case NFS4_OP_PUTFH: /* void */ break; case NFS4_OP_PUTPUBFH: /* void */ break; case NFS4_OP_PUTROOTFH: /* void */ break; case NFS4_OP_READ: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_eof, offset); offset = dissect_nfs_opaque4(tvb, offset, pinfo, newftree, "data"); break; case NFS4_OP_READDIR: offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "cookieverf"); offset = dissect_nfs_dirlist4(tvb, offset, pinfo, newftree, "reply"); break; case NFS4_OP_READLINK: offset = dissect_nfs_linktext4(tvb, offset, pinfo, newftree, "link"); break; case NFS4_OP_REMOVE: offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "change_info"); break; case NFS4_OP_RENAME: offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "source_cinfo"); offset = dissect_nfs_change_info4(tvb, offset, pinfo, newftree, "target_cinfo"); break; case NFS4_OP_RENEW: /* void */ break; case NFS4_OP_RESTOREFH: /* void */ break; case NFS4_OP_SAVEFH: /* void */ break; case NFS4_OP_SECINFO: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_secinfo_flavor, offset); offset = dissect_nfs_opaque4(tvb, offset, pinfo, newftree, "flavor_info"); break; case NFS4_OP_SETATTR: offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, "attrsset", 0); break; case NFS4_OP_SETCLIENTID: if (status == NFS4_OK) { offset = dissect_rpc_uint64(tvb, pinfo, newftree, hf_nfs_clientid4, offset); offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "setclientid_confirm"); } else if (status == NFS4ERR_CLID_INUSE) { offset = dissect_nfs_clientaddr4(tvb, offset, pinfo, newftree, "client_using"); } break; case NFS4_OP_SETCLIENTID_CONFIRM: /* void */ break; case NFS4_OP_VERIFY: /* void */ break; case NFS4_OP_WRITE: offset = dissect_rpc_uint32(tvb, pinfo, newftree, hf_nfs_count4, offset); offset = dissect_nfs_stable_how4(tvb, offset, pinfo, newftree, "committed"); offset = dissect_nfs_verifier4(tvb, offset, pinfo, newftree, "writeverf"); break; default: break; } } return offset; } int dissect_nfs4_compound_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree* tree) { guint32 status; offset = dissect_nfs_nfsstat4(tvb, offset, pinfo, tree, &status); offset = dissect_nfs_utf8string(tvb, offset, pinfo, tree, hf_nfs_tag4, NULL); offset = dissect_nfs_resop4(tvb, offset, pinfo, tree, "arguments"); return offset; } /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: type of arguments is "void". */ static const vsff nfs3_proc[] = { { 0, "NULL", /* OK */ NULL, NULL }, { 1, "GETATTR", /* OK */ dissect_nfs3_getattr_call, dissect_nfs3_getattr_reply }, { 2, "SETATTR", /* OK */ dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply }, { 3, "LOOKUP", /* OK */ dissect_nfs3_lookup_call, dissect_nfs3_lookup_reply }, { 4, "ACCESS", /* OK */ dissect_nfs3_access_call, dissect_nfs3_access_reply }, { 5, "READLINK", /* OK */ dissect_nfs3_nfs_fh3_call, dissect_nfs3_readlink_reply }, { 6, "READ", /* OK */ dissect_nfs3_read_call, dissect_nfs3_read_reply }, { 7, "WRITE", /* OK */ dissect_nfs3_write_call, dissect_nfs3_write_reply }, { 8, "CREATE", /* OK */ dissect_nfs3_create_call, dissect_nfs3_create_reply }, { 9, "MKDIR", /* OK */ dissect_nfs3_mkdir_call, dissect_nfs3_create_reply }, { 10, "SYMLINK", /* OK */ dissect_nfs3_symlink_call, dissect_nfs3_create_reply }, { 11, "MKNOD", /* OK */ dissect_nfs3_mknod_call, dissect_nfs3_create_reply }, { 12, "REMOVE", /* OK */ dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply }, { 13, "RMDIR", /* OK */ dissect_nfs3_diropargs3_call, dissect_nfs3_remove_reply }, { 14, "RENAME", /* OK */ dissect_nfs3_rename_call, dissect_nfs3_rename_reply }, { 15, "LINK", /* OK */ dissect_nfs3_link_call, dissect_nfs3_link_reply }, { 16, "READDIR", /* OK */ dissect_nfs3_readdir_call, dissect_nfs3_readdir_reply }, { 17, "READDIRPLUS", /* OK */ dissect_nfs3_readdirplus_call, dissect_nfs3_readdirplus_reply }, { 18, "FSSTAT", /* OK */ dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsstat_reply }, { 19, "FSINFO", /* OK */ dissect_nfs3_nfs_fh3_call, dissect_nfs3_fsinfo_reply }, { 20, "PATHCONF", /* OK */ dissect_nfs3_nfs_fh3_call, dissect_nfs3_pathconf_reply }, { 21, "COMMIT", /* OK */ dissect_nfs3_commit_call, dissect_nfs3_commit_reply }, { 0,NULL,NULL,NULL } }; /* end of NFS Version 3 */ static const vsff nfs4_proc[] = { { 0, "NULL", NULL, NULL }, { 1, "COMPOUND", dissect_nfs4_compound_call, dissect_nfs4_compound_reply }, { 0, NULL, NULL, NULL } }; static struct true_false_string yesno = { "Yes", "No" }; void proto_register_nfs(void) { static hf_register_info hf[] = { { &hf_nfs_fh_length, { "length", "nfs.fh.length", FT_UINT32, BASE_DEC, NULL, 0, "file handle length", HFILL }}, { &hf_nfs_fh_fsid_major, { "major", "nfs.fh.fsid.major", FT_UINT32, BASE_DEC, NULL, 0, "major file system ID", HFILL }}, { &hf_nfs_fh_fsid_minor, { "minor", "nfs.fh.fsid.minor", FT_UINT32, BASE_DEC, NULL, 0, "minor file system ID", HFILL }}, { &hf_nfs_fh_fsid_inode, { "inode", "nfs.fh.fsid.inode", FT_UINT32, BASE_DEC, NULL, 0, "file system inode", HFILL }}, { &hf_nfs_fh_xfsid_major, { "exported major", "nfs.fh.xfsid.major", FT_UINT32, BASE_DEC, NULL, 0, "exported major file system ID", HFILL }}, { &hf_nfs_fh_xfsid_minor, { "exported minor", "nfs.fh.xfsid.minor", FT_UINT32, BASE_DEC, NULL, 0, "exported minor file system ID", HFILL }}, { &hf_nfs_fh_fstype, { "file system type", "nfs.fh.fstype", FT_UINT32, BASE_DEC, NULL, 0, "file system type", HFILL }}, { &hf_nfs_fh_fn, { "file number", "nfs.fh.fn", FT_UINT32, BASE_DEC, NULL, 0, "file number", HFILL }}, { &hf_nfs_fh_fn_len, { "length", "nfs.fh.fn.len", FT_UINT32, BASE_DEC, NULL, 0, "file number length", HFILL }}, { &hf_nfs_fh_fn_inode, { "inode", "nfs.fh.fn.inode", FT_UINT32, BASE_DEC, NULL, 0, "file number inode", HFILL }}, { &hf_nfs_fh_fn_generation, { "generation", "nfs.fh.fn.generation", FT_UINT32, BASE_DEC, NULL, 0, "file number generation", HFILL }}, { &hf_nfs_fh_xfn, { "exported file number", "nfs.fh.xfn", FT_UINT32, BASE_DEC, NULL, 0, "exported file number", HFILL }}, { &hf_nfs_fh_xfn_len, { "length", "nfs.fh.xfn.len", FT_UINT32, BASE_DEC, NULL, 0, "exported file number length", HFILL }}, { &hf_nfs_fh_xfn_inode, { "exported inode", "nfs.fh.xfn.inode", FT_UINT32, BASE_DEC, NULL, 0, "exported file number inode", HFILL }}, { &hf_nfs_fh_xfn_generation, { "generation", "nfs.fh.xfn.generation", FT_UINT32, BASE_DEC, NULL, 0, "exported file number generation", HFILL }}, { &hf_nfs_fh_dentry, { "dentry", "nfs.fh.dentry", FT_UINT32, BASE_HEX, NULL, 0, "dentry (cookie)", HFILL }}, { &hf_nfs_fh_dev, { "device", "nfs.fh.dev", FT_UINT32, BASE_DEC, NULL, 0, "device", HFILL }}, { &hf_nfs_fh_xdev, { "exported device", "nfs.fh.xdev", FT_UINT32, BASE_DEC, NULL, 0, "exported device", HFILL }}, { &hf_nfs_fh_dirinode, { "directory inode", "nfs.fh.dirinode", FT_UINT32, BASE_DEC, NULL, 0, "directory inode", HFILL }}, { &hf_nfs_fh_pinode, { "pseudo inode", "nfs.fh.pinode", FT_UINT32, BASE_HEX, NULL, 0, "pseudo inode", HFILL }}, { &hf_nfs_fh_hp_len, { "length", "nfs.fh.hp.len", FT_UINT32, BASE_DEC, NULL, 0, "hash path length", HFILL }}, { &hf_nfs_fh_version, { "version", "nfs.fh.version", FT_UINT8, BASE_DEC, NULL, 0, "file handle layout version", HFILL }}, { &hf_nfs_fh_auth_type, { "auth_type", "nfs.fh.auth_type", FT_UINT8, BASE_DEC, VALS(auth_type_names), 0, "authentication type", HFILL }}, { &hf_nfs_fh_fsid_type, { "fsid_type", "nfs.fh.fsid_type", FT_UINT8, BASE_DEC, VALS(fsid_type_names), 0, "file system ID type", HFILL }}, { &hf_nfs_fh_fileid_type, { "fileid_type", "nfs.fh.fileid_type", FT_UINT8, BASE_DEC, VALS(fileid_type_names), 0, "file ID type", HFILL }}, { &hf_nfs_stat, { "Status", "nfs.status2", FT_UINT32, BASE_DEC, VALS(names_nfs_stat), 0, "Reply status", HFILL }}, { &hf_nfs_name, { "Name", "nfs.name", FT_STRING, BASE_DEC, NULL, 0, "Name", HFILL }}, { &hf_nfs_readlink_data, { "Data", "nfs.readlink.data", FT_STRING, BASE_DEC, NULL, 0, "Symbolic Link Data", HFILL }}, { &hf_nfs_read_offset, { "Offset", "nfs.read.offset", FT_UINT32, BASE_DEC, NULL, 0, "Read Offset", HFILL }}, { &hf_nfs_read_count, { "Count", "nfs.read.count", FT_UINT32, BASE_DEC, NULL, 0, "Read Count", HFILL }}, { &hf_nfs_read_totalcount, { "Total Count", "nfs.read.totalcount", FT_UINT32, BASE_DEC, NULL, 0, "Total Count (obsolete)", HFILL }}, { &hf_nfs_data, { "Data", "nfs.data", FT_BYTES, BASE_DEC, NULL, 0, "Data", HFILL }}, { &hf_nfs_write_beginoffset, { "Begin Offset", "nfs.write.beginoffset", FT_UINT32, BASE_DEC, NULL, 0, "Begin offset (obsolete)", HFILL }}, { &hf_nfs_write_offset, { "Offset", "nfs.write.offset", FT_UINT32, BASE_DEC, NULL, 0, "Offset", HFILL }}, { &hf_nfs_write_totalcount, { "Total Count", "nfs.write.totalcount", FT_UINT32, BASE_DEC, NULL, 0, "Total Count (obsolete)", HFILL }}, { &hf_nfs_symlink_to, { "To", "nfs.symlink.to", FT_STRING, BASE_DEC, NULL, 0, "Symbolic link destination name", HFILL }}, { &hf_nfs_readdir_cookie, { "Cookie", "nfs.readdir.cookie", FT_UINT32, BASE_DEC, NULL, 0, "Directory Cookie", HFILL }}, { &hf_nfs_readdir_count, { "Count", "nfs.readdir.count", FT_UINT32, BASE_DEC, NULL, 0, "Directory Count", HFILL }}, { &hf_nfs_readdir_entry, { "Entry", "nfs.readdir.entry", FT_NONE, 0, NULL, 0, "Directory Entry", HFILL }}, { &hf_nfs_readdir_entry_fileid, { "File ID", "nfs.readdir.entry.fileid", FT_UINT32, BASE_DEC, NULL, 0, "File ID", HFILL }}, { &hf_nfs_readdir_entry_name, { "Name", "nfs.readdir.entry.name", FT_STRING, BASE_DEC, NULL, 0, "Name", HFILL }}, { &hf_nfs_readdir_entry_cookie, { "Cookie", "nfs.readdir.entry.cookie", FT_UINT32, BASE_DEC, NULL, 0, "Directory Cookie", HFILL }}, { &hf_nfs_readdir_entry3_fileid, { "File ID", "nfs.readdir.entry3.fileid", FT_UINT32, BASE_DEC, NULL, 0, "File ID", HFILL }}, { &hf_nfs_readdir_entry3_name, { "Name", "nfs.readdir.entry3.name", FT_STRING, BASE_DEC, NULL, 0, "Name", HFILL }}, { &hf_nfs_readdir_entry3_cookie, { "Cookie", "nfs.readdir.entry3.cookie", FT_UINT32, BASE_DEC, NULL, 0, "Directory Cookie", HFILL }}, { &hf_nfs_readdirplus_entry_fileid, { "File ID", "nfs.readdirplus.entry.fileid", FT_UINT32, BASE_DEC, NULL, 0, "Name", HFILL }}, { &hf_nfs_readdirplus_entry_name, { "Name", "nfs.readdirplus.entry.name", FT_STRING, BASE_DEC, NULL, 0, "Name", HFILL }}, { &hf_nfs_readdirplus_entry_cookie, { "Cookie", "nfs.readdirplus.entry.cookie", FT_UINT32, BASE_DEC, NULL, 0, "Directory Cookie", HFILL }}, { &hf_nfs_readdir_eof, { "EOF", "nfs.readdir.eof", FT_UINT32, BASE_DEC, NULL, 0, "EOF", HFILL }}, { &hf_nfs_statfs_tsize, { "Transfer Size", "nfs.statfs.tsize", FT_UINT32, BASE_DEC, NULL, 0, "Transfer Size", HFILL }}, { &hf_nfs_statfs_bsize, { "Block Size", "nfs.statfs.bsize", FT_UINT32, BASE_DEC, NULL, 0, "Block Size", HFILL }}, { &hf_nfs_statfs_blocks, { "Total Blocks", "nfs.statfs.blocks", FT_UINT32, BASE_DEC, NULL, 0, "Total Blocks", HFILL }}, { &hf_nfs_statfs_bfree, { "Free Blocks", "nfs.statfs.bfree", FT_UINT32, BASE_DEC, NULL, 0, "Free Blocks", HFILL }}, { &hf_nfs_statfs_bavail, { "Available Blocks", "nfs.statfs.bavail", FT_UINT32, BASE_DEC, NULL, 0, "Available Blocks", HFILL }}, { &hf_nfs_ftype3, { "Type", "nfs.type", FT_UINT32, BASE_DEC, VALS(names_nfs_ftype3), 0, "File Type", HFILL }}, { &hf_nfs_nfsstat3, { "Status", "nfs.status", FT_UINT32, BASE_DEC, VALS(names_nfs_nfsstat3), 0, "Reply status", HFILL }}, { &hf_nfs_read_eof, { "EOF", "nfs.read.eof", FT_BOOLEAN, BASE_NONE, &yesno, 0, "EOF", HFILL }}, { &hf_nfs_write_stable, { "Stable", "nfs.write.stable", FT_UINT32, BASE_DEC, VALS(names_stable_how), 0, "Stable", HFILL }}, { &hf_nfs_write_committed, { "Committed", "nfs.write.committed", FT_UINT32, BASE_DEC, VALS(names_stable_how), 0, "Committed", HFILL }}, { &hf_nfs_createmode3, { "Create Mode", "nfs.createmode", FT_UINT32, BASE_DEC, VALS(names_createmode3), 0, "Create Mode", HFILL }}, { &hf_nfs_fsstat_invarsec, { "invarsec", "nfs.fsstat.invarsec", FT_UINT32, BASE_DEC, NULL, 0, "probable number of seconds of file system invariance", HFILL }}, { &hf_nfs_fsinfo_rtmax, { "rtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC, NULL, 0, "maximum READ request", HFILL }}, { &hf_nfs_fsinfo_rtpref, { "rtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC, NULL, 0, "Preferred READ request size", HFILL }}, { &hf_nfs_fsinfo_rtmult, { "rtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC, NULL, 0, "Suggested READ multiple", HFILL }}, { &hf_nfs_fsinfo_wtmax, { "wtmax", "nfs.fsinfo.wtmax", FT_UINT32, BASE_DEC, NULL, 0, "Maximum WRITE request size", HFILL }}, { &hf_nfs_fsinfo_wtpref, { "wtpref", "nfs.fsinfo.wtpref", FT_UINT32, BASE_DEC, NULL, 0, "Preferred WRITE request size", HFILL }}, { &hf_nfs_fsinfo_wtmult, { "wtmult", "nfs.fsinfo.wtmult", FT_UINT32, BASE_DEC, NULL, 0, "Suggested WRITE multiple", HFILL }}, { &hf_nfs_fsinfo_dtpref, { "dtpref", "nfs.fsinfo.dtpref", FT_UINT32, BASE_DEC, NULL, 0, "Preferred READDIR request", HFILL }}, { &hf_nfs_fsinfo_maxfilesize, { "maxfilesize", "nfs.fsinfo.maxfilesize", FT_UINT32, BASE_DEC, NULL, 0, "Maximum file size", HFILL }}, { &hf_nfs_fsinfo_properties, { "Properties", "nfs.fsinfo.propeties", FT_UINT32, BASE_HEX, NULL, 0, "File System Properties", HFILL }}, { &hf_nfs_pathconf_linkmax, { "linkmax", "nfs.pathconf.linkmax", FT_UINT32, BASE_DEC, NULL, 0, "Maximum number of hard links", HFILL }}, { &hf_nfs_pathconf_name_max, { "name_max", "nfs.pathconf.name_max", FT_UINT32, BASE_DEC, NULL, 0, "Maximum file name length", HFILL }}, { &hf_nfs_pathconf_no_trunc, { "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE, &yesno, 0, "No long file name truncation", HFILL }}, { &hf_nfs_pathconf_chown_restricted, { "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, BASE_NONE, &yesno, 0, "chown is restricted to root", HFILL }}, { &hf_nfs_pathconf_case_insensitive, { "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, BASE_NONE, &yesno, 0, "file names are treated case insensitive", HFILL }}, { &hf_nfs_pathconf_case_preserving, { "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, BASE_NONE, &yesno, 0, "file name cases are preserved", HFILL }}, { &hf_nfs_fattr_type, { "type", "nfs.fattr.type", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.type", HFILL }}, { &hf_nfs_fattr_nlink, { "nlink", "nfs.fattr.nlink", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.nlink", HFILL }}, { &hf_nfs_fattr_uid, { "uid", "nfs.fattr.uid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.uid", HFILL }}, { &hf_nfs_fattr_gid, { "gid", "nfs.fattr.gid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.gid", HFILL }}, { &hf_nfs_fattr_size, { "size", "nfs.fattr.size", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.size", HFILL }}, { &hf_nfs_fattr_blocksize, { "blocksize", "nfs.fattr.blocksize", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.blocksize", HFILL }}, { &hf_nfs_fattr_rdev, { "rdev", "nfs.fattr.rdev", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.rdev", HFILL }}, { &hf_nfs_fattr_blocks, { "blocks", "nfs.fattr.blocks", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.blocks", HFILL }}, { &hf_nfs_fattr_fsid, { "fsid", "nfs.fattr.fsid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.fsid", HFILL }}, { &hf_nfs_fattr_fileid, { "fileid", "nfs.fattr.fileid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr.fileid", HFILL }}, { &hf_nfs_fattr3_type, { "Type", "nfs.fattr3.type", FT_UINT32, BASE_DEC, VALS(names_nfs_ftype3), 0, "nfs.fattr3.type", HFILL }}, { &hf_nfs_fattr3_nlink, { "nlink", "nfs.fattr3.nlink", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.nlink", HFILL }}, { &hf_nfs_fattr3_uid, { "uid", "nfs.fattr3.uid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.uid", HFILL }}, { &hf_nfs_fattr3_gid, { "gid", "nfs.fattr3.gid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.gid", HFILL }}, { &hf_nfs_fattr3_size, { "size", "nfs.fattr3.size", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.size", HFILL }}, { &hf_nfs_fattr3_used, { "used", "nfs.fattr3.used", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.used", HFILL }}, { &hf_nfs_fattr3_rdev, { "rdev", "nfs.fattr3.rdev", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.rdev", HFILL }}, { &hf_nfs_fattr3_fsid, { "fsid", "nfs.fattr3.fsid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.fsid", HFILL }}, { &hf_nfs_fattr3_fileid, { "fileid", "nfs.fattr3.fileid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr3.fileid", HFILL }}, { &hf_nfs_wcc_attr_size, { "size", "nfs.wcc_attr.size", FT_UINT32, BASE_DEC, NULL, 0, "nfs.wcc_attr.size", HFILL }}, { &hf_nfs_set_size3_size, { "size", "nfs.set_size3.size", FT_UINT32, BASE_DEC, NULL, 0, "nfs.set_size3.size", HFILL }}, { &hf_nfs_uid3, { "uid", "nfs.uid3", FT_UINT32, BASE_DEC, NULL, 0, "nfs.uid3", HFILL }}, { &hf_nfs_gid3, { "gid", "nfs.gid3", FT_UINT32, BASE_DEC, NULL, 0, "nfs.gid3", HFILL }}, { &hf_nfs_cookie3, { "cookie", "nfs.cookie3", FT_UINT32, BASE_DEC, NULL, 0, "nfs.cookie3", HFILL }}, { &hf_nfs_offset3, { "offset", "nfs.offset3", FT_UINT32, BASE_DEC, NULL, 0, "nfs.offset3", HFILL }}, { &hf_nfs_count3, { "count", "nfs.count3", FT_UINT32, BASE_DEC, NULL, 0, "nfs.count3", HFILL }}, { &hf_nfs_count3_maxcount, { "maxcount", "nfs.count3_maxcount", FT_UINT32, BASE_DEC, NULL, 0, "nfs.count3_maxcount", HFILL }}, { &hf_nfs_count3_dircount, { "dircount", "nfs.count3_dircount", FT_UINT32, BASE_DEC, NULL, 0, "nfs.count3_dircount", HFILL }}, { &hf_nfs_fsstat3_resok_tbytes, { "tbytes", "nfs.fsstat3_resok.tbytes", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.tbytes", HFILL }}, { &hf_nfs_fsstat3_resok_fbytes, { "fbytes", "nfs.fsstat3_resok.fbytes", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.fbytes", HFILL }}, { &hf_nfs_fsstat3_resok_abytes, { "abytes", "nfs.fsstat3_resok.abytes", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.abytes", HFILL }}, { &hf_nfs_fsstat3_resok_tfiles, { "tfiles", "nfs.fsstat3_resok.tfiles", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.tfiles", HFILL }}, { &hf_nfs_fsstat3_resok_ffiles, { "ffiles", "nfs.fsstat3_resok.ffiles", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.ffiles", HFILL }}, { &hf_nfs_fsstat3_resok_afiles, { "afiles", "nfs.fsstat3_resok.afiles", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsstat3_resok.afiles", HFILL }}, /* NFSv4 */ { &hf_nfs_argop4, { "Opcode", "nfs.call.operation", FT_UINT32, BASE_DEC, VALS(names_nfsv4_operation), 0, "Opcode", HFILL }}, { &hf_nfs_resop4, { "Opcode", "nfs.reply.operation", FT_UINT32, BASE_DEC, VALS(names_nfsv4_operation), 0, "Opcode", HFILL }}, { &hf_nfs_linktext4, { "Name", "nfs.symlink.linktext", FT_STRING, BASE_DEC, NULL, 0, "Symbolic link contents", HFILL }}, { &hf_nfs_component4, { "Filename", "nfs.pathname.component", FT_STRING, BASE_DEC, NULL, 0, "Pathname component", HFILL }}, { &hf_nfs_tag4, { "Tag", "nfs.tag", FT_STRING, BASE_DEC, NULL, 0, "Tag", HFILL }}, { &hf_nfs_clientid4, { "clientid", "nfs.clientid", FT_UINT32, BASE_DEC, NULL, 0, "Client ID", HFILL }}, { &hf_nfs_clientid4_verifier, { "verifier", "nfs.clientid.verifier", FT_UINT32, BASE_DEC, NULL, 0, "Verifier Client ID", HFILL }}, { &hf_nfs_ace4, { "ace", "nfs.ace", FT_STRING, BASE_DEC, NULL, 0, "Access Control Entry", HFILL }}, { &hf_nfs_recall, { "EOF", "nfs.recall", FT_BOOLEAN, BASE_NONE, &yesno, 0, "Recall", HFILL }}, { &hf_nfs_open_claim_type4, { "Claim Type", "nfs.open.claim_type", FT_UINT32, BASE_DEC, VALS(names_claim_type4), 0, "Claim Type", HFILL }}, { &hf_nfs_opentype4, { "Open Type", "nfs.open.opentype", FT_UINT32, BASE_DEC, VALS(names_opentype4), 0, "Open Type", HFILL }}, { &hf_nfs_limit_by4, { "Space Limit", "nfs.open.limit_by", FT_UINT32, BASE_DEC, VALS(names_limit_by4), 0, "Limit By", HFILL }}, { &hf_nfs_open_delegation_type4, { "Delegation Type", "nfs.open.delegation_type", FT_UINT32, BASE_DEC, VALS(names_open_delegation_type4), 0, "Delegation Type", HFILL }}, { &hf_nfs_ftype4, { "nfs_ftype4", "nfs.nfs_ftype4", FT_UINT32, BASE_DEC, VALS(names_ftype4), 0, "nfs.nfs_ftype4", HFILL }}, { &hf_nfs_change_info4_atomic, { "Atomic", "nfs.change_info.atomic", FT_BOOLEAN, BASE_NONE, &yesno, 0, "Atomic", HFILL }}, { &hf_nfs_open4_share_access, { "share_access", "nfs.open4.share_access", FT_UINT32, BASE_DEC, VALS(names_open4_share_access), 0, "Share Access", HFILL }}, { &hf_nfs_open4_share_deny, { "share_deny", "nfs.open4.share_deny", FT_UINT32, BASE_DEC, VALS(names_open4_share_deny), 0, "Share Deny", HFILL }}, { &hf_nfs_seqid4, { "seqid", "nfs.seqid", FT_UINT32, BASE_HEX, NULL, 0, "Sequence ID", HFILL }}, { &hf_nfs_mand_attr, { "mand_attr", "nfs.attr", FT_UINT32, BASE_DEC, VALS(names_fattr4), 0, "Mandatory Attribute", HFILL }}, { &hf_nfs_recc_attr, { "recc_attr", "nfs.attr", FT_UINT32, BASE_DEC, VALS(names_fattr4), 0, "Recommended Attribute", HFILL }}, { &hf_nfs_time_how4, { "set_it", "nfs.set_it", FT_UINT32, BASE_DEC, VALS(names_time_how4), 0, "How To Set Time", HFILL }}, { &hf_nfs_attrlist4, { "attr_vals", "nfs.fattr4.attr_vals", FT_BYTES, BASE_DEC, NULL, 0, "attr_vals", HFILL }}, { &hf_nfs_fattr4_expire_type, { "fattr4_expire_type", "nfs.fattr4_expire_type", FT_UINT32, BASE_DEC, VALS(names_fattr4_expire_type), 0, "fattr4_expire_type", HFILL }}, { &hf_nfs_fattr4_link_support, { "fattr4_link_support", "nfs.fattr4_link_support", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_link_support", HFILL }}, { &hf_nfs_fattr4_symlink_support, { "fattr4_symlink_support", "nfs.fattr4_symlink_support", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_symlink_support", HFILL }}, { &hf_nfs_fattr4_named_attr, { "fattr4_named_attr", "nfs.fattr4_named_attr", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_named_attr", HFILL }}, { &hf_nfs_fattr4_unique_handles, { "fattr4_unique_handles", "nfs.fattr4_unique_handles", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_unique_handles", HFILL }}, { &hf_nfs_fattr4_archive, { "fattr4_archive", "nfs.fattr4_archive", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_archive", HFILL }}, { &hf_nfs_fattr4_cansettime, { "fattr4_cansettime", "nfs.fattr4_cansettime", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_cansettime", HFILL }}, { &hf_nfs_fattr4_case_insensitive, { "fattr4_case_insensitive", "nfs.fattr4_case_insensitive", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_case_insensitive", HFILL }}, { &hf_nfs_fattr4_case_preserving, { "fattr4_case_preserving", "nfs.fattr4_case_preserving", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_case_preserving", HFILL }}, { &hf_nfs_fattr4_chown_restricted, { "fattr4_chown_restricted", "nfs.fattr4_chown_restricted", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_chown_restricted", HFILL }}, { &hf_nfs_fattr4_hidden, { "fattr4_hidden", "nfs.fattr4_hidden", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_hidden", HFILL }}, { &hf_nfs_fattr4_homogeneous, { "fattr4_homogeneous", "nfs.fattr4_homogeneous", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_homogeneous", HFILL }}, { &hf_nfs_fattr4_mimetype, { "fattr4_mimetype", "nfs.fattr4_mimetype", FT_STRING, BASE_DEC, NULL, 0, "nfs.fattr4_mimetype", HFILL }}, { &hf_nfs_fattr4_no_trunc, { "fattr4_no_trunc", "nfs.fattr4_no_trunc", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_no_trunc", HFILL }}, { &hf_nfs_fattr4_system, { "fattr4_system", "nfs.fattr4_system", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.fattr4_system", HFILL }}, { &hf_nfs_who, { "who", "nfs.who", FT_STRING, BASE_DEC, NULL, 0, "nfs.who", HFILL }}, { &hf_nfs_server, { "server", "nfs.server", FT_STRING, BASE_DEC, NULL, 0, "nfs.server", HFILL }}, { &hf_nfs_fattr4_owner, { "fattr4_owner", "nfs.fattr4_owner", FT_STRING, BASE_DEC, NULL, 0, "nfs.fattr4_owner", HFILL }}, { &hf_nfs_fattr4_owner_group, { "fattr4_owner_group", "nfs.fattr4_owner_group", FT_STRING, BASE_DEC, NULL, 0, "nfs.fattr4_owner_group", HFILL }}, { &hf_nfs_stable_how4, { "stable_how4", "nfs.stable_how4", FT_UINT32, BASE_DEC, VALS(names_stable_how4), 0, "nfs.stable_how4", HFILL }}, { &hf_nfs_dirlist4_eof, { "eof", "nfs.dirlist4.eof", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.dirlist4.eof", HFILL }}, { &hf_nfs_data_follows, { "data_follows", "nfs.data_follows", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.data_follows", HFILL }}, { &hf_nfs_stateid4, { "stateid", "nfs.stateid4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.stateid4", HFILL }}, { &hf_nfs_offset4, { "offset", "nfs.offset4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.offset4", HFILL }}, { &hf_nfs_specdata1, { "specdata1", "nfs.specdata1", FT_UINT32, BASE_DEC, NULL, 0, "nfs.specdata1", HFILL }}, { &hf_nfs_specdata2, { "specdata2", "nfs.specdata2", FT_UINT32, BASE_DEC, NULL, 0, "nfs.specdata2", HFILL }}, { &hf_nfs_locktype4, { "locktype", "nfs.locktype4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.locktype4", HFILL }}, { &hf_nfs_reclaim4, { "reclaim", "nfs.reclaim4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.reclaim4", HFILL }}, { &hf_nfs_length4, { "length", "nfs.length4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.length4", HFILL }}, { &hf_nfs_changeid4, { "changeid", "nfs.changeid4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.changeid4", HFILL }}, { &hf_nfs_nfstime4_seconds, { "seconds", "nfs.nfstime4.seconds", FT_UINT32, BASE_DEC, NULL, 0, "nfs.nfstime4.seconds", HFILL }}, { &hf_nfs_nfstime4_nseconds, { "nseconds", "nfs.nfstime4.nseconds", FT_UINT32, BASE_DEC, NULL, 0, "nfs.nfstime4.nseconds", HFILL }}, { &hf_nfs_fsid4_major, { "fsid4.major", "nfs.fsid4.major", FT_UINT32, BASE_DEC, NULL, 0, "nfs.nfstime4.fsid4.major", HFILL }}, { &hf_nfs_fsid4_minor, { "fsid4.minor", "nfs.fsid4.minor", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fsid4.minor", HFILL }}, { &hf_nfs_acetype4, { "acetype", "nfs.acetype4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.acetype4", HFILL }}, { &hf_nfs_aceflag4, { "aceflag", "nfs.aceflag4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.aceflag4", HFILL }}, { &hf_nfs_acemask4, { "acemask", "nfs.acemask4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.acemask4", HFILL }}, { &hf_nfs_fattr4_size, { "size", "nfs.fattr4.size", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.size", HFILL }}, { &hf_nfs_fattr4_lease_time, { "lease_time", "nfs.fattr4.lease_time", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.lease_time", HFILL }}, { &hf_nfs_fattr4_aclsupport, { "aclsupport", "nfs.fattr4.aclsupport", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.aclsupport", HFILL }}, { &hf_nfs_fattr4_fileid, { "fileid", "nfs.fattr4.fileid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.fileid", HFILL }}, { &hf_nfs_fattr4_files_avail, { "files_avail", "nfs.fattr4.files_avail", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.files_avail", HFILL }}, { &hf_nfs_fattr4_files_free, { "files_free", "nfs.fattr4.files_free", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.files_free", HFILL }}, { &hf_nfs_fattr4_files_total, { "files_total", "nfs.fattr4.files_total", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.files_total", HFILL }}, { &hf_nfs_fattr4_maxfilesize, { "maxfilesize", "nfs.fattr4.maxfilesize", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.maxfilesize", HFILL }}, { &hf_nfs_fattr4_maxlink, { "maxlink", "nfs.fattr4.maxlink", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.maxlink", HFILL }}, { &hf_nfs_fattr4_maxname, { "maxname", "nfs.fattr4.maxname", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.maxname", HFILL }}, { &hf_nfs_fattr4_numlinks, { "numlinks", "nfs.fattr4.numlinks", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.numlinks", HFILL }}, { &hf_nfs_delegate_type, { "delegate_type", "nfs.delegate_type", FT_UINT32, BASE_DEC, NULL, 0, "nfs.delegate_type", HFILL }}, { &hf_nfs_secinfo_flavor, { "secinfo_flavor", "nfs.secinfo_flavor", FT_UINT32, BASE_DEC, NULL, 0, "nfs.secinfo_flavor", HFILL }}, { &hf_nfs_num_blocks, { "num_blocks", "nfs.num_blocks", FT_UINT32, BASE_DEC, NULL, 0, "nfs.num_blocks", HFILL }}, { &hf_nfs_bytes_per_block, { "bytes_per_block", "nfs.bytes_per_block", FT_UINT32, BASE_DEC, NULL, 0, "nfs.bytes_per_block", HFILL }}, { &hf_nfs_eof, { "eof", "nfs.eof", FT_UINT32, BASE_DEC, NULL, 0, "nfs.eof", HFILL }}, { &hf_nfs_fattr4_maxread, { "maxread", "nfs.fattr4.maxread", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.maxread", HFILL }}, { &hf_nfs_fattr4_maxwrite, { "maxwrite", "nfs.fattr4.maxwrite", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.maxwrite", HFILL }}, { &hf_nfs_fattr4_quota_hard, { "quota_hard", "nfs.fattr4.quota_hard", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.quota_hard", HFILL }}, { &hf_nfs_fattr4_quota_soft, { "quota_soft", "nfs.fattr4.quota_soft", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.quota_soft", HFILL }}, { &hf_nfs_fattr4_quota_used, { "quota_used", "nfs.fattr4.quota_used", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.quota_used", HFILL }}, { &hf_nfs_fattr4_space_avail, { "space_avail", "nfs.fattr4.space_avail", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.space_avail", HFILL }}, { &hf_nfs_fattr4_space_free, { "space_free", "nfs.fattr4.space_free", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.space_free", HFILL }}, { &hf_nfs_fattr4_space_total, { "space_total", "nfs.fattr4.space_total", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.space_total", HFILL }}, { &hf_nfs_fattr4_space_used, { "space_used", "nfs.fattr4.space_used", FT_UINT32, BASE_DEC, NULL, 0, "nfs.fattr4.space_used", HFILL }}, { &hf_nfs_stateid4_delegate_stateid, { "delegate_stateid", "nfs.delegate_stateid", FT_UINT32, BASE_DEC, NULL, 0, "nfs.delegate_stateid", HFILL }}, { &hf_nfs_verifier4, { "verifier", "nfs.verifier4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.verifier4", HFILL }}, { &hf_nfs_cookie4, { "cookie", "nfs.cookie4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.cookie4", HFILL }}, { &hf_nfs_cookieverf4, { "cookieverf", "nfs.cookieverf4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.cookieverf4", HFILL }}, { &hf_nfs_cb_location, { "cb_location", "nfs.cb_location", FT_UINT32, BASE_DEC, NULL, 0, "nfs.cb_location", HFILL }}, { &hf_nfs_cb_program, { "cb_program", "nfs.cb_program", FT_UINT32, BASE_DEC, NULL, 0, "nfs.cb_program", HFILL }}, { &hf_nfs_recall4, { "recall", "nfs.recall4", FT_BOOLEAN, BASE_NONE, &yesno, 0, "nfs.recall4", HFILL }}, { &hf_nfs_filesize, { "filesize", "nfs.filesize", FT_UINT32, BASE_DEC, NULL, 0, "nfs.filesize", HFILL }}, { &hf_nfs_count4, { "count", "nfs.count4", FT_UINT32, BASE_DEC, NULL, 0, "nfs.count4", HFILL }}, { &hf_nfs_count4_dircount, { "dircount", "nfs.dircount", FT_UINT32, BASE_DEC, NULL, 0, "nfs.dircount", HFILL }}, { &hf_nfs_count4_maxcount, { "maxcount", "nfs.maxcount", FT_UINT32, BASE_DEC, NULL, 0, "nfs.maxcount", HFILL }}, { &hf_nfs_minorversion, { "minorversion", "nfs.minorversion", FT_UINT32, BASE_DEC, NULL, 0, "nfs.minorversion", HFILL }}, }; static gint *ett[] = { &ett_nfs, &ett_nfs_fh_encoding, &ett_nfs_fh_fsid, &ett_nfs_fh_xfsid, &ett_nfs_fh_fn, &ett_nfs_fh_xfn, &ett_nfs_fh_hp, &ett_nfs_fh_auth, &ett_nfs_fhandle, &ett_nfs_timeval, &ett_nfs_mode, &ett_nfs_fattr, &ett_nfs_sattr, &ett_nfs_diropargs, &ett_nfs_readdir_entry, &ett_nfs_mode3, &ett_nfs_specdata3, &ett_nfs_fh3, &ett_nfs_nfstime3, &ett_nfs_fattr3, &ett_nfs_post_op_fh3, &ett_nfs_sattr3, &ett_nfs_diropargs3, &ett_nfs_sattrguard3, &ett_nfs_set_mode3, &ett_nfs_set_uid3, &ett_nfs_set_gid3, &ett_nfs_set_size3, &ett_nfs_set_atime, &ett_nfs_set_mtime, &ett_nfs_pre_op_attr, &ett_nfs_post_op_attr, &ett_nfs_wcc_attr, &ett_nfs_wcc_data, &ett_nfs_access, &ett_nfs_fsinfo_properties, &ett_nfs_compound_call4, &ett_nfs_utf8string, &ett_nfs_argop4, &ett_nfs_resop4, &ett_nfs_access4, &ett_nfs_close4, &ett_nfs_commit4, &ett_nfs_create4, &ett_nfs_delegpurge4, &ett_nfs_delegreturn4, &ett_nfs_getattr4, &ett_nfs_getfh4, &ett_nfs_link4, &ett_nfs_lock4, &ett_nfs_lockt4, &ett_nfs_locku4, &ett_nfs_lookup4, &ett_nfs_lookupp4, &ett_nfs_nverify4, &ett_nfs_open4, &ett_nfs_openattr4, &ett_nfs_open_confirm4, &ett_nfs_open_downgrade4, &ett_nfs_putfh4, &ett_nfs_putpubfh4, &ett_nfs_putrootfh4, &ett_nfs_read4, &ett_nfs_readdir4, &ett_nfs_readlink4, &ett_nfs_remove4, &ett_nfs_rename4, &ett_nfs_renew4, &ett_nfs_restorefh4, &ett_nfs_savefh4, &ett_nfs_secinfo4, &ett_nfs_setattr4, &ett_nfs_setclientid4, &ett_nfs_setclientid_confirm4, &ett_nfs_verify4, &ett_nfs_write4, &ett_nfs_verifier4, &ett_nfs_opaque, &ett_nfs_dirlist4, &ett_nfs_pathname4, &ett_nfs_change_info4, &ett_nfs_open_delegation4, &ett_nfs_open_claim4, &ett_nfs_opentype4, &ett_nfs_lockowner4, &ett_nfs_cb_client4, &ett_nfs_client_id4, &ett_nfs_bitmap4, &ett_nfs_fattr4, &ett_nfs_fsid4, &ett_nfs_fs_locations4, &ett_nfs_fs_location4, &ett_nfs_open4_result_flags }; proto_nfs = proto_register_protocol("Network File System", "NFS", "nfs"); proto_register_field_array(proto_nfs, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_nfs(void) { /* Register the protocol as RPC */ rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs); /* Register the procedure tables */ rpc_init_proc_table(NFS_PROGRAM, 2, nfs2_proc); rpc_init_proc_table(NFS_PROGRAM, 3, nfs3_proc); rpc_init_proc_table(NFS_PROGRAM, 4, nfs4_proc); }