[pnfs] OP_SEQUENCE for ethereal

Benny Halevy bhalevy at panasas.com
Mon Feb 26 03:59:36 EST 2007


Can we maintain an up-to-date git tree of the wireshark sources
until the nfsv4 rfc is submitted (and then submit what we have
to wireshark-dev)?

Benny

Garth Goodson wrote:
> Here are the packet-nfs.c and packet-nfs.h files (sorry didn't have time 
> to make a patch).  But just replace the existing ones from 
> epan/dissectors/packet-nfs.[ch].  They come from wireshark version 
> 0.99.6-SVN-20556, but should work with most versions of wireshark and 
> ethereal.  I've also fixed some other bugs that were present within 
> those files (regarding parsing of stateids).
> 
> -Garth
> 
> William A. (Andy) Adamson wrote:
>> has anyone added code to ethereal for OP_SEQUENCE?
>>
>> -->Andy
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> pNFS mailing list
>> pNFS at linux-nfs.org
>> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs
>>
>> ------------------------------------------------------------------------
>>
>> /* packet-nfs.c
>>  * Routines for nfs dissection
>>  * Copyright 1999, Uwe Girlich <Uwe.Girlich at philosys.de>
>>  * Copyright 2000-2004, Mike Frisch <frisch at hummingbird.com> (NFSv4 decoding)
>>  *
>>  * $Id: packet-nfs.c 19875 2006-11-10 23:36:57Z sahlberg $
>>  *
>>  * Wireshark - Network traffic analyzer
>>  * By Gerald Combs <gerald at wireshark.org>
>>  * 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
>>
>>
>> #include <string.h>
>>
>>
>> #include "packet-rpc.h"
>> #include "packet-nfs.h"
>> #include <epan/prefs.h>
>> #include <epan/packet.h>
>> #include <epan/emem.h>
>>
>> static int proto_nfs = -1;
>>
>> static int hf_nfs_procedure_v2 = -1;
>> static int hf_nfs_procedure_v3 = -1;
>> static int hf_nfs_procedure_v4 = -1;
>> static int hf_nfs_fh_length = -1;
>> static int hf_nfs_fh_hash = -1;
>> static int hf_nfs_fh_fhandle_data = -1;
>> static int hf_nfs_fh_mount_fileid = -1;
>> static int hf_nfs_fh_mount_generation = -1;
>> static int hf_nfs_fh_snapid = -1;
>> static int hf_nfs_fh_unused = -1;
>> static int hf_nfs_fh_flags = -1;
>> static int hf_nfs_fh_fileid = -1;
>> static int hf_nfs_fh_generation = -1;
>> static int hf_nfs_fh_fsid = -1;
>> static int hf_nfs_fh_export_fileid = -1;
>> static int hf_nfs_fh_export_generation = -1;
>> static int hf_nfs_fh_export_snapid = -1;
>> static int hf_nfs_fh_file_flag_mntpoint = -1;
>> static int hf_nfs_fh_file_flag_snapdir = -1;
>> static int hf_nfs_fh_file_flag_snapdir_ent = -1;
>> static int hf_nfs_fh_file_flag_empty = -1;
>> static int hf_nfs_fh_file_flag_vbn_access = -1;
>> static int hf_nfs_fh_file_flag_multivolume = -1;
>> static int hf_nfs_fh_file_flag_metadata = -1;
>> static int hf_nfs_fh_file_flag_orphan = -1;
>> static int hf_nfs_fh_file_flag_foster = -1;
>> static int hf_nfs_fh_file_flag_named_attr = -1;
>> static int hf_nfs_fh_file_flag_exp_snapdir = -1;
>> static int hf_nfs_fh_file_flag_vfiler = -1;
>> static int hf_nfs_fh_file_flag_aggr = -1;
>> static int hf_nfs_fh_file_flag_striped = -1;
>> static int hf_nfs_fh_file_flag_private = -1;
>> static int hf_nfs_fh_file_flag_next_gen = -1;
>> static int hf_nfs_fh_handle_type = -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_gxfh3_utlfield = -1;
>> static int hf_gxfh3_utlfield_tree_r = -1;
>> static int hf_gxfh3_utlfield_tree_w = -1;
>> static int hf_gxfh3_utlfield_jun = -1;
>> static int hf_gxfh3_utlfield_jun_not = -1;
>> static int hf_gxfh3_utlfield_ver = -1;
>> static int hf_gxfh3_volcnt = -1; 
>> static int hf_gxfh3_epoch = -1; 
>> static int hf_gxfh3_ldsid = -1; 
>> static int hf_gxfh3_cid = -1; 
>> static int hf_gxfh3_resv = -1; 			
>> static int hf_gxfh3_sfhflags = -1; 			
>> static int hf_gxfh3_sfhflags_resv1 = -1; 			
>> static int hf_gxfh3_sfhflags_resv2 = -1; 			
>> static int hf_gxfh3_sfhflags_ontap7G = -1; 			
>> static int hf_gxfh3_sfhflags_ontapGX = -1; 			
>> static int hf_gxfh3_sfhflags_striped = -1; 			
>> static int hf_gxfh3_sfhflags_empty = -1; 			
>> static int hf_gxfh3_sfhflags_snapdirent = -1; 			
>> static int hf_gxfh3_sfhflags_snapdir = -1; 
>> static int hf_gxfh3_sfhflags_streamdir = -1;  
>> static int hf_gxfh3_spinfid = -1; 
>> static int hf_gxfh3_spinfuid = -1; 
>> static int hf_gxfh3_exportptid = -1; 
>> static int hf_gxfh3_exportptuid = -1; 
>>
>> static int hf_nfs_stat = -1;
>> static int hf_nfs_full_name = -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_atime = -1;
>> static int hf_nfs_atime_sec = -1;
>> static int hf_nfs_atime_nsec = -1;
>> static int hf_nfs_atime_usec = -1;
>> static int hf_nfs_mtime = -1;
>> static int hf_nfs_mtime_sec = -1;
>> static int hf_nfs_mtime_nsec = -1;
>> static int hf_nfs_mtime_usec = -1;
>> static int hf_nfs_ctime = -1;
>> static int hf_nfs_ctime_sec = -1;
>> static int hf_nfs_ctime_nsec = -1;
>> static int hf_nfs_ctime_usec = -1;
>> static int hf_nfs_dtime = -1;
>> static int hf_nfs_dtime_sec = -1;
>> static int hf_nfs_dtime_nsec = -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_nfsstat4 = -1;
>> 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_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_lock_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_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_lock_type4 = -1;
>> static int hf_nfs_reclaim4 = -1;
>> static int hf_nfs_length4 = -1;
>> static int hf_nfs_changeid4 = -1;
>> static int hf_nfs_changeid4_before = -1;
>> static int hf_nfs_changeid4_after = -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_secinfo_arr4 = -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 int hf_nfs_open_owner4 = -1;
>> static int hf_nfs_lock_owner4 = -1;
>> static int hf_nfs_new_lock_owner = -1;
>> static int hf_nfs_sec_oid4 = -1;
>> static int hf_nfs_qop4 = -1;
>> static int hf_nfs_secinfo_rpcsec_gss_info_service = -1;
>> static int hf_nfs_attrdircreate = -1;
>> static int hf_nfs_client_id4_id = -1;
>> static int hf_nfs_stateid4_other = -1;
>> static int hf_nfs_lock4_reclaim = -1;
>> static int hf_nfs_acl4 = -1;
>> static int hf_nfs_callback_ident = -1;
>> static int hf_nfs_r_netid = -1;
>> static int hf_nfs_r_addr = -1;
>>
>> /* NFSv4.1 */
>> static int hf_nfs_length4_minlength = -1;
>> static int hf_nfs_layouttype4 = -1;
>> static int hf_nfs_layoutreturn_type4 = -1;
>> static int hf_nfs_iomode4 = -1;
>> static int hf_nfs_fldtype4 = -1;
>> static int hf_nfs_stripetype4 = -1;
>> static int hf_nfs_mdscommit4 = -1;
>> static int hf_nfs_stripeunit4 = -1;
>> static int hf_nfs_newtime4 = -1;
>> static int hf_nfs_newoffset4 = -1;
>> static int hf_nfs_layout_avail4 = -1;
>> static int hf_nfs_newsize4 = -1;
>> static int hf_nfs_layoutupdate4 = -1;
>> static int hf_nfs_deviceid4 = -1;
>> static int hf_nfs_devicenum4 = -1;
>> static int hf_nfs_deviceidx4 = -1;
>> static int hf_nfs_layout4 = -1;
>> static int hf_nfs_stripedevs4 = -1;
>> static int hf_nfs_devaddr4 = -1;
>> static int hf_nfs_notifydsop4 = -1;
>> static int hf_nfs_return_on_close4 = -1;
>> static int hf_nfs_slotid4 = -1;
>> static int hf_nfs_sr_status4 = -1;
>> static int hf_nfs_serverscope4 = -1;
>> static int hf_nfs_minorid4 = -1;
>> static int hf_nfs_majorid4 = -1;
>> static int hf_nfs_persist4 = -1;
>> static int hf_nfs_backchan4 = -1;
>> static int hf_nfs_rdmamode4 = -1;
>> static int hf_nfs_padsize4 = -1;
>> static int hf_nfs_cbrenforce4 = -1;
>> static int hf_nfs_hashalg4 = -1;
>> static int hf_nfs_ssvlen4 = -1;
>> static int hf_nfs_maxreqsize4 = -1;
>> static int hf_nfs_maxrespsize4 = -1;
>> static int hf_nfs_maxrespsizecached4 = -1;
>> static int hf_nfs_maxops4 = -1;
>> static int hf_nfs_maxreqs4 = -1;
>> static int hf_nfs_streamchanattrs4 = -1;
>> static int hf_nfs_rdmachanattrs4 = -1;
>> static int hf_nfs_machinename4 = -1;
>> static int hf_nfs_flavor4 = -1;
>> static int hf_nfs_stamp4 = -1;
>> static int hf_nfs_uid4 = -1;
>> static int hf_nfs_gid4 = -1;
>> static int hf_nfs_service4 = -1;
>> static int hf_nfs_sessionid4 = -1;
>>
>> /* Hidden field for v2, v3, and v4 status */
>> static int hf_nfs_nfsstat = -1;
>>
>> static gint ett_nfs = -1;
>> static gint ett_nfs_fh_encoding = -1;
>> static gint ett_nfs_fh_mount = -1;
>> static gint ett_nfs_fh_file = -1;
>> static gint ett_nfs_fh_export = -1;
>> static gint ett_nfsv4_fh_export = -1;
>> static gint ett_nfsv4_fh_file   = -1;
>> static gint ett_nfsv4_fh_handle_type = -1;
>> static gint ett_nfsv4_fh_export_snapgen = -1;
>> static gint ett_nfsv4_fh_file_flags = -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;
>> static gint ett_nfs_gxfh3_utlfield = -1;
>> static gint ett_nfs_gxfh3_sfhfield = -1;
>> static gint ett_nfs_gxfh3_sfhflags = -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_release_lockowner4 = -1;
>> static gint ett_nfs_illegal4 = -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_lock_owner4 = -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;
>> static gint ett_nfs_secinfo4_flavor_info = -1;
>> static gint ett_nfs_stateid4 = -1;
>> static gint ett_nfs_fattr4_fh_expire_type = -1;
>> static gint ett_nfs_ace4 = -1;
>> static gint ett_nfs_clientaddr4 = -1;
>> static gint ett_nfs_aceflag4 = -1;
>> static gint ett_nfs_acemask4 = -1;
>>
>> static gint ett_nfs_layoutget4 = -1;
>> static gint ett_nfs_layoutcommit4 = -1;
>> static gint ett_nfs_layoutreturn4 = -1;
>> static gint ett_nfs_getdevinfo4 = -1;
>> static gint ett_nfs_getdevlist4 = -1;
>> static gint ett_nfs_notifyds4 = -1;
>> static gint ett_nfs_exchange_id4 = -1;
>> static gint ett_nfs_create_session4 = -1;
>> static gint ett_nfs_destroy_session4 = -1;
>> static gint ett_nfs_sequence4 = -1;
>> static gint ett_nfs_pnfs_create4 = -1;
>> static gint ett_nfs_slotid4 = -1;
>> static gint ett_nfs_sr_status4 = -1;
>> static gint ett_nfs_serverscope4 = -1;
>> static gint ett_nfs_minorid4 = -1;
>> static gint ett_nfs_majorid4 = -1;
>> static gint ett_nfs_persist4 = -1;
>> static gint ett_nfs_backchan4 = -1;
>> static gint ett_nfs_rdmamode4 = -1;
>> static gint ett_nfs_padsize4 = -1;
>> static gint ett_nfs_cbrenforce4 = -1;
>> static gint ett_nfs_hashalg4 = -1;
>> static gint ett_nfs_ssvlen4 = -1;
>> static gint ett_nfs_maxreqsize4 = -1;
>> static gint ett_nfs_maxrespsize4 = -1;
>> static gint ett_nfs_maxrespsizecached4 = -1;
>> static gint ett_nfs_maxops4 = -1;
>> static gint ett_nfs_maxreqs4 = -1;
>> static gint ett_nfs_streamchanattrs4 = -1;
>> static gint ett_nfs_rdmachanattrs4 = -1;
>> static gint ett_nfs_machinename4 = -1;
>> static gint ett_nfs_flavor4 = -1;
>> static gint ett_nfs_stamp4 = -1;
>> static gint ett_nfs_uid4 = -1;
>> static gint ett_nfs_gid4 = -1;
>> static gint ett_nfs_service4 = -1;
>> static gint ett_nfs_sessionid4 = -1;
>>
>> /* what type of fhandles shoudl we dissect as */
>> static dissector_table_t nfs_fhandle_table;
>>
>>
>> #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
>> #define FHT_NETAPP		5
>> #define FHT_NETAPP_V4		6
>> #define FHT_NETAPP_GX_V3	7
>>
>>
>> static enum_val_t nfs_fhandle_types[] = {
>> 	{ "unknown",	"Unknown",	FHT_UNKNOWN },
>> 	{ "svr4",	"SVR4",		FHT_SVR4 },
>> 	{ "knfsd_le",	"KNFSD_LE",	FHT_LINUX_KNFSD_LE },
>> 	{ "nfsd_le",	"NFSD_LE",	FHT_LINUX_NFSD_LE },
>> 	{ "knfsd_new",	"KNFSD_NEW",	FHT_LINUX_KNFSD_NEW },
>> 	{ "ontap_v3",	"ONTAP_V3",	FHT_NETAPP },
>> 	{ "ontap_v4",	"ONTAP_V4",	FHT_NETAPP_V4},
>> 	{ "ontap_gx_v3","ONTAP_GX_V3",	FHT_NETAPP_GX_V3},	
>> 	{ NULL, NULL, 0 }
>> };
>> /* decode all nfs filehandles as this type */
>> gint default_nfs_fhandle_type=FHT_UNKNOWN;
>>
>> /* For dissector helpers which take a "levels" argument to indicate how
>>  * many expansions up they should populate the expansion items with
>>  * text to enhance useability, this flag to "levels" specify that the
>>  * text should also be appended to COL_INFO
>>  */
>> #define COL_INFO_LEVEL 0x80000000
>>
>>
>> /* fhandle displayfilters to match also corresponding request/response
>>    packet in addition to the one containing the actual filehandle */
>> gboolean nfs_fhandle_reqrep_matching = FALSE;
>> static emem_tree_t *nfs_fhandle_frame_table = NULL;
>>
>>
>> /* file name snooping */
>> gboolean nfs_file_name_snooping = FALSE;
>> gboolean nfs_file_name_full_snooping = FALSE;
>> typedef struct nfs_name_snoop {
>> 	int fh_length;
>> 	unsigned char *fh;
>> 	int name_len;
>> 	unsigned char *name;
>> 	int parent_len;
>> 	unsigned char *parent;
>> 	int full_name_len;
>> 	unsigned char *full_name;
>> } nfs_name_snoop_t;
>>
>> typedef struct nfs_name_snoop_key {
>> 	int key;
>> 	int fh_length;
>> 	const unsigned char *fh;
>> } nfs_name_snoop_key_t;
>>
>> static GHashTable *nfs_name_snoop_unmatched = NULL;
>>
>> static GHashTable *nfs_name_snoop_matched = NULL;
>>
>> static emem_tree_t *nfs_name_snoop_known = NULL;
>> static emem_tree_t *nfs_file_handles = NULL;
>>
>> /* This function will store one nfs filehandle in our global tree of
>>  * filehandles.
>>  * We store all filehandles we see in this tree so that every unique
>>  * filehandle is only stored once with a unique pointer.
>>  * We need to store pointers to filehandles in several of our other
>>  * structures and this is a way to make sure we dont keep any redundant
>>  * copiesd around for a specific filehandle.
>>  *
>>  * If this is the first time this filehandle has been seen an se block
>>  * is allocated to store the filehandle in.
>>  * If this filehandle has already been stored in the tree this function returns
>>  * a pointer to the original copy.
>>  */
>> static nfs_fhandle_data_t *
>> store_nfs_file_handle(nfs_fhandle_data_t *nfs_fh)
>> {
>> 	guint32 fhlen;
>> 	emem_tree_key_t fhkey[3];
>> 	nfs_fhandle_data_t *new_nfs_fh;
>>
>> 	fhlen=nfs_fh->len/4;
>> 	fhkey[0].length=1;
>> 	fhkey[0].key=&fhlen;
>> 	fhkey[1].length=fhlen;
>> 	fhkey[1].key=(guint32 *)nfs_fh->fh;
>> 	fhkey[2].length=0;
>>
>> 	new_nfs_fh=se_tree_lookup32_array(nfs_file_handles, &fhkey[0]);
>> 	if(new_nfs_fh){
>> 		return new_nfs_fh;
>> 	}
>>
>> 	new_nfs_fh=se_alloc(sizeof(nfs_fhandle_data_t));
>> 	new_nfs_fh->len=nfs_fh->len;
>> 	new_nfs_fh->fh=se_alloc(sizeof(guint32)*(nfs_fh->len/4));
>> 	memcpy(new_nfs_fh->fh, nfs_fh->fh, nfs_fh->len);
>> 	new_nfs_fh->tvb=tvb_new_real_data(new_nfs_fh->fh, new_nfs_fh->len, new_nfs_fh->len);
>> 	fhlen=nfs_fh->len/4;
>> 	fhkey[0].length=1;
>> 	fhkey[0].key=&fhlen;
>> 	fhkey[1].length=fhlen;
>> 	fhkey[1].key=(guint32 *)nfs_fh->fh;
>> 	fhkey[2].length=0;
>> 	se_tree_insert32_array(nfs_file_handles, &fhkey[0], new_nfs_fh);
>>
>> 	return new_nfs_fh;
>> }
>>
>> static gint
>> nfs_name_snoop_matched_equal(gconstpointer k1, gconstpointer k2)
>> {
>> 	const nfs_name_snoop_key_t *key1 = (const nfs_name_snoop_key_t *)k1;
>> 	const nfs_name_snoop_key_t *key2 = (const nfs_name_snoop_key_t *)k2;
>>
>> 	return (key1->key==key2->key)
>> 	     &&(key1->fh_length==key2->fh_length)
>> 	     &&(!memcmp(key1->fh, key2->fh, key1->fh_length));
>> }
>> static guint
>> nfs_name_snoop_matched_hash(gconstpointer k)
>> {
>> 	const nfs_name_snoop_key_t *key = (const nfs_name_snoop_key_t *)k;
>> 	int i;
>> 	guint hash;
>>
>> 	hash=key->key;
>> 	for(i=0;i<key->fh_length;i++)
>> 		hash ^= key->fh[i];
>>
>> 	return hash;
>> }
>> static gint
>> nfs_name_snoop_unmatched_equal(gconstpointer k1, gconstpointer k2)
>> {
>> 	guint32 key1 = GPOINTER_TO_UINT(k1);
>> 	guint32 key2 = GPOINTER_TO_UINT(k2);
>>
>> 	return key1==key2;
>> }
>> static guint
>> nfs_name_snoop_unmatched_hash(gconstpointer k)
>> {
>> 	guint32 key = GPOINTER_TO_UINT(k);
>>
>> 	return key;
>> }
>> static gboolean
>> nfs_name_snoop_unmatched_free_all(gpointer key_arg _U_, gpointer value, gpointer user_data _U_)
>> {
>> 	nfs_name_snoop_t *nns = (nfs_name_snoop_t *)value;
>>
>> 	if(nns->name){
>> 		g_free((gpointer)nns->name);
>> 		nns->name=NULL;
>> 		nns->name_len=0;
>> 	}
>> 	if(nns->full_name){
>> 		g_free((gpointer)nns->full_name);
>> 		nns->full_name=NULL;
>> 		nns->full_name_len=0;
>> 	}
>> 	if(nns->parent){
>> 		g_free((gpointer)nns->parent);
>> 		nns->parent=NULL;
>> 		nns->parent_len=0;
>> 	}
>> 	if(nns->fh){
>> 		g_free((gpointer)nns->fh);
>> 		nns->fh=NULL;
>> 		nns->fh_length=0;
>> 	}
>> 	return TRUE;
>> }
>>
>> static void
>> nfs_name_snoop_init(void)
>> {
>> 	if (nfs_name_snoop_unmatched != NULL) {
>> 		g_hash_table_foreach_remove(nfs_name_snoop_unmatched,
>> 				nfs_name_snoop_unmatched_free_all, NULL);
>> 	} else {
>> 		/* The fragment table does not exist. Create it */
>> 		nfs_name_snoop_unmatched=g_hash_table_new(nfs_name_snoop_unmatched_hash,
>> 			nfs_name_snoop_unmatched_equal);
>> 	}
>> 	if (nfs_name_snoop_matched != NULL) {
>> 		g_hash_table_foreach_remove(nfs_name_snoop_matched,
>> 				nfs_name_snoop_unmatched_free_all, NULL);
>> 	} else {
>> 		/* The fragment table does not exist. Create it */
>> 		nfs_name_snoop_matched=g_hash_table_new(nfs_name_snoop_matched_hash,
>> 			nfs_name_snoop_matched_equal);
>> 	}
>> }
>>
>> void
>> nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, int parent_offset, int parent_len, unsigned char *name)
>> {
>> 	nfs_name_snoop_t *nns, *old_nns;
>> 	const unsigned char *ptr=NULL;
>>
>> 	/* filter out all '.' and '..' names */
>> 	if(!name){
>> 		ptr=(const unsigned char *)tvb_get_ptr(tvb, name_offset, name_len);
>> 		if(ptr[0]=='.'){
>> 			if(ptr[1]==0){
>> 				return;
>> 			}
>> 			if(ptr[1]=='.'){
>> 				if(ptr[2]==0){
>> 					return;
>> 				}
>> 			}
>> 		}
>> 	}
>>
>> 	nns=se_alloc(sizeof(nfs_name_snoop_t));
>>
>> 	nns->fh_length=0;
>> 	nns->fh=NULL;
>>
>> 	if(parent_len){
>> 		nns->parent_len=parent_len;
>> 		nns->parent=tvb_memdup(tvb, parent_offset, parent_len);
>> 	} else {
>> 		nns->parent_len=0;
>> 		nns->parent=NULL;
>> 	}
>>
>> 	if(name){
>> 		nns->name_len=strlen(name);
>> 		nns->name=g_strdup(name);
>> 	} else {
>> 		nns->name_len=name_len;
>> 		nns->name=g_malloc(name_len+1);
>> 		memcpy(nns->name, ptr, name_len);
>> 	}
>> 	nns->name[nns->name_len]=0;
>>
>> 	nns->full_name_len=0;
>> 	nns->full_name=NULL;
>>
>> 	/* remove any old entry for this */
>> 	old_nns=g_hash_table_lookup(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
>> 	if(old_nns){
>> 		/* if we haven't seen the reply yet, then there are no
>> 		   matched entries for it, thus we can dealloc the arrays*/
>> 		if(!old_nns->fh){
>> 			g_free(old_nns->name);
>> 			old_nns->name=NULL;
>> 			old_nns->name_len=0;
>>
>> 			g_free(old_nns->parent);
>> 			old_nns->parent=NULL;
>> 			old_nns->parent_len=0;
>> 		}
>> 		g_hash_table_remove(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
>> 	}
>>
>> 	g_hash_table_insert(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid), nns);
>> }
>>
>> static void
>> nfs_name_snoop_add_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
>> {
>> 	unsigned char *fh;
>> 	nfs_name_snoop_t *nns, *old_nns;
>> 	nfs_name_snoop_key_t *key;
>>
>> 	/* find which request we correspond to */
>> 	nns=g_hash_table_lookup(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
>> 	if(!nns){
>> 		/* oops couldnt find matching request, bail out */
>> 		return;
>> 	}
>>
>> 	/* if we have already seen this response earlier */
>> 	if(nns->fh){
>> 		return;
>> 	}
>>
>> 	/* oki, we have a new entry */
>> 	fh=tvb_memdup(tvb, fh_offset, fh_length);
>> 	nns->fh=fh;
>> 	nns->fh_length=fh_length;
>>
>> 	key=se_alloc(sizeof(nfs_name_snoop_key_t));
>> 	key->key=0;
>> 	key->fh_length=nns->fh_length;
>> 	key->fh    =nns->fh;
>>
>> 	/* already have something matched for this fh, remove it from
>> 	   the table */
>> 	old_nns=g_hash_table_lookup(nfs_name_snoop_matched, key);
>> 	if(old_nns){
>> 		g_hash_table_remove(nfs_name_snoop_matched, key);
>> 	}
>>
>> 	g_hash_table_remove(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
>> 	g_hash_table_insert(nfs_name_snoop_matched, key, nns);
>> }
>>
>> static void
>> nfs_full_name_snoop(nfs_name_snoop_t *nns, int *len, unsigned char **name, unsigned char **pos)
>> {
>> 	nfs_name_snoop_t *parent_nns = NULL;
>> 	nfs_name_snoop_key_t key;
>>
>> 	/* check if the nns component ends with a '/' else we just allocate
>> 	   an extra byte to len to accommodate for it later */
>> 	if(nns->name[nns->name_len-1]!='/'){
>> 		(*len)++;
>> 	}
>>
>> 	(*len) += nns->name_len;
>>
>> 	if(nns->parent==NULL){
>> 		*name = g_malloc((*len)+1);
>> 		*pos = *name;
>>
>> 		*pos += g_snprintf(*pos, (*len)+1, "%s", nns->name);
>> 		return;
>> 	}
>>
>> 	key.key=0;
>> 	key.fh_length=nns->parent_len;
>> 	key.fh=nns->parent;
>>
>> 	parent_nns=g_hash_table_lookup(nfs_name_snoop_matched, &key);
>>
>> 	if(parent_nns){
>> 		nfs_full_name_snoop(parent_nns, len, name, pos);
>> 		if(*name){
>> 			/* make sure components are '/' separated */
>> 			*pos += g_snprintf(*pos, (*len)+1, "%s%s", ((*pos)[-1]!='/')?"/":"", nns->name);
>> 		}
>> 		return;
>> 	}
>>
>> 	return;
>> }
>>
>> static void
>> nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_offset, int fh_length, gboolean hidden)
>> {
>> 	nfs_name_snoop_key_t key;
>> 	nfs_name_snoop_t *nns = NULL;
>>
>> 	/* if this is a new packet, see if we can register the mapping */
>> 	if(!pinfo->fd->flags.visited){
>> 		key.key=0;
>> 		key.fh_length=fh_length;
>> 		key.fh=(const unsigned char *)tvb_get_ptr(tvb, fh_offset, fh_length);
>>
>> 		nns=g_hash_table_lookup(nfs_name_snoop_matched, &key);
>> 		if(nns){
>> 			guint32 fhlen;
>> 			emem_tree_key_t fhkey[3];
>>
>> 			fhlen=nns->fh_length;
>> 			fhkey[0].length=1;
>> 			fhkey[0].key=&fhlen;
>> 			fhkey[1].length=fhlen/4;
>> 			fhkey[1].key=(guint32 *)nns->fh;
>> 			fhkey[2].length=0;
>> 			se_tree_insert32_array(nfs_name_snoop_known, &fhkey[0], nns);
>>
>> 			if(nfs_file_name_full_snooping){
>> 				unsigned char *name=NULL, *pos=NULL;
>> 				int len=0;
>>
>> 				nfs_full_name_snoop(nns, &len, &name, &pos);
>> 				if(name){
>> 					nns->full_name=name;
>> 					nns->full_name_len=len;
>> 				}
>> 			}
>> 		}
>> 	}
>>
>> 	/* see if we know this mapping */
>> 	if(!nns){
>> 		guint32 fhlen;
>> 		emem_tree_key_t fhkey[3];
>>
>> 		fhlen=fh_length;
>> 		fhkey[0].length=1;
>> 		fhkey[0].key=&fhlen;
>> 		fhkey[1].length=fhlen/4;
>> 		fhkey[1].key=(guint32 *)tvb_get_ptr(tvb, fh_offset, fh_length);
>> 		fhkey[2].length=0;
>>
>> 		nns=se_tree_lookup32_array(nfs_name_snoop_known, &fhkey[0]);
>> 	}
>>
>> 	/* if we know the mapping, print the filename */
>> 	if(nns){
>> 		proto_item *fh_item;
>>
>> 		if(hidden){
>> 			fh_item=proto_tree_add_string_hidden(tree, hf_nfs_name, tvb,
>> 				fh_offset, 0, nns->name);
>> 		}else {
>> 			fh_item=proto_tree_add_string_format(tree, hf_nfs_name, tvb,
>> 				fh_offset, 0, nns->name, "Name: %s", nns->name);
>> 		}
>> 		PROTO_ITEM_SET_GENERATED(fh_item);
>>
>> 		if(nns->full_name){
>> 			if(hidden){
>> 				fh_item=proto_tree_add_string_hidden(tree, hf_nfs_full_name, tvb,
>> 					fh_offset, 0, nns->name);
>> 			} else {
>> 				fh_item=proto_tree_add_string_format(tree, hf_nfs_full_name, tvb,
>> 					fh_offset, 0, nns->name, "Full Name: %s", nns->full_name);
>> 			}
>> 			PROTO_ITEM_SET_GENERATED(fh_item);
>> 		}
>> 	}
>> }
>>
>> /* file handle dissection */
>>
>> 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)"			},
>> 	{	FHT_NETAPP,		"ONTAP 7G nfs v3 file handle"		},
>> 	{	FHT_NETAPP_V4,	 	"ONTAP 7G nfs v4 file handle"		},
>> 	{	FHT_NETAPP_GX_V3,	"ONTAP GX nfs v3 file handle"		},
>> 	{	0,			NULL					}
>> };
>>
>>
>> /* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45) */
>>
>> static void
>> dissect_fhandle_data_SVR4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	guint32 nof=0;
>>
>> 	/* 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, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	int offset=0;
>> 	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) */
>>
>> static void
>> dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	int offset=0;
>>
>> 	/* 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));
>> 			}
>> 		}
>> 	}
>> 	}
>> }
>>
>>
>> static void
>> dissect_fhandle_data_NETAPP(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	int offset=0;
>>
>> 	if (tree) {
>> 		guint32 mount = tvb_get_letohl(tvb, offset + 0);
>> 		guint32 mount_gen = tvb_get_letohl(tvb, offset + 4);
>> 		guint16 flags = tvb_get_letohs(tvb, offset + 8);
>> 		guint8 snapid = tvb_get_guint8(tvb, offset + 10);
>> 		guint8 unused = tvb_get_guint8(tvb, offset + 11);
>> 		guint32 inum = tvb_get_ntohl(tvb, offset + 12);
>> 		guint32 generation = tvb_get_letohl(tvb, offset + 16);
>> 		guint32 fsid = tvb_get_letohl(tvb, offset + 20);
>> 		guint32 export = tvb_get_letohl(tvb, offset + 24);
>> 		guint32 export_snapgen = tvb_get_letohl(tvb, offset + 28);
>> 		
>> 		proto_item *item;
>> 		proto_tree *subtree;
>> 		char *flag_string;
>> 		const char *strings[] = { " MNT_PNT", " SNAPDIR", " SNAPDIR_ENT",
>> 				    " EMPTY", " VBN_ACCESS", " MULTIVOLUME",
>> 				    " METADATA" };
>> 		guint16 bit = sizeof(strings) / sizeof(strings[0]);
>>
>> 		flag_string=ep_alloc(512);
>> 		flag_string[0]=0;
>> 		while (bit--)
>> 			if (flags & (1<<bit))
>> 				strcat(flag_string, strings[bit]);
>> 		item = proto_tree_add_text(tree, tvb, offset + 0, 8,
>> 					   "mount (inode %u)", mount);
>> 		subtree = proto_item_add_subtree(item, ett_nfs_fh_mount);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_mount_fileid,
>> 					   tvb, offset + 0, 4, mount);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_mount_generation,
>> 					   tvb, offset + 4, 4, mount_gen);
>> 		item = proto_tree_add_text(tree, tvb, offset + 8, 16,
>> 					   "file (inode %u)", inum);
>> 		subtree = proto_item_add_subtree(item, ett_nfs_fh_file);
>> 		item = proto_tree_add_uint_format(subtree, hf_nfs_fh_flags,
>> 						  tvb, offset + 8, 2, flags,
>> 						  "Flags: %#02x%s", flags,
>> 						  flag_string);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_snapid, tvb,
>> 					   offset + 10, 1, snapid);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_unused, tvb,
>> 					   offset + 11, 1, unused);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_fileid, tvb,
>> 					   offset + 12, 4, inum);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_generation, tvb,
>> 					   offset + 16, 4, generation);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_fsid, tvb,
>> 					   offset + 20, 4, fsid);
>> 		item = proto_tree_add_text(tree, tvb, offset + 24, 8,
>> 					   "export (inode %u)", export);
>> 		subtree = proto_item_add_subtree(item, ett_nfs_fh_export);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_export_fileid,
>> 					   tvb, offset + 24, 4, export);
>> 		item = proto_tree_add_uint(subtree,
>> 					   hf_nfs_fh_export_generation,
>> 					   tvb, offset + 28, 3,
>> 					   export_snapgen & 0xffffff);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_export_snapid,
>> 					   tvb, offset + 31, 1,
>> 					   export_snapgen >> 24);
>> 	}
>> }
>>
>> const value_string netapp_file_flag_vals[] =  {
>> 						{ 0x0000,	"Not set"},
>> 						{ 0x0001,	"Set"},
>> 						{ 0,		NULL}
>> 					       };
>>
>> static void
>> dissect_fhandle_data_NETAPP_V4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	int offset=0;
>> 	proto_item *item = NULL;
>> 	proto_tree *subtree = NULL;
>> 	guint8  snapid, unused;
>> 	guint16 flags;
>> 	guint32 fileid, snapgen, generation, fsid;
>> 	guint32 handle_type = tvb_get_ntohl(tvb, offset + 24);
>> 	guint32 inum = tvb_get_ntohl(tvb, offset + 12);
>> 		
>> 	char *handle_string=NULL;
>> 	const char *handle_type_strings [] = { "NORMAL",
>> 					       "UNEXP",
>> 					       "VOLDIR",
>> 					       "ROOT",
>> 					       "ABSENT",
>> 					       "INVALID"
>> 					     };
>>
>> 	char *flag_string;
>> 	const char *strings[] = { " MNT_PNT", 
>> 				  " SNAPDIR", 
>> 				  " SNAPDIR_ENT",
>> 				  " EMPTY", 
>> 				  " VBN_ACCESS", 
>> 				  " MULTIVOLUME",
>> 				  " METADATA",
>> 				  " ORPHAN",
>> 				  " FOSTER",
>> 				  " NAMED_ATTR",
>> 				  " EXP_SNAPDIR",
>> 				  " VFILER",
>> 				  " NS_AGGR",
>> 				  " STRIPED",
>> 				  " NS_PRIVATE",
>> 				  " NEXT_GEN_FH"
>> 				};
>> 	guint16 bit = sizeof(strings) / sizeof(strings[0]);
>> 	proto_tree *flag_tree = NULL;
>>
>> 	flag_string=ep_alloc(512);
>> 	flag_string[0]=0;
>>
>> 	if(tree){
>> 		if( handle_type !=0 && handle_type <= 255) {
>> 			fileid = tvb_get_ntohl(tvb, offset + 0);
>> 			snapgen = tvb_get_ntohl(tvb, offset + 4);
>> 			flags = tvb_get_ntohs(tvb, offset + 8);
>> 			snapid = tvb_get_guint8(tvb, offset + 10);
>> 			unused = tvb_get_guint8(tvb, offset + 11);
>> 			generation = tvb_get_ntohl(tvb, offset + 16);
>> 			fsid = tvb_get_ntohl(tvb, offset + 20);
>> 		} else {
>> 			fileid = tvb_get_letohl(tvb, offset + 0);
>> 			snapgen = tvb_get_letohl(tvb, offset + 4);
>> 			flags = tvb_get_letohs(tvb, offset + 8);
>> 			snapid = tvb_get_guint8(tvb, offset + 10);
>> 			unused = tvb_get_guint8(tvb, offset + 11);
>> 			generation = tvb_get_letohl(tvb, offset + 16);
>> 			fsid = tvb_get_letohl(tvb, offset + 20);
>> 			handle_type = tvb_get_letohl(tvb, offset + 24);
>> 		}
>>
>> 		if(handle_type <= 4) {
>> 			handle_string=handle_type_strings[handle_type];
>> 		} else {
>> 			handle_string=handle_type_strings[5];
>> 		}
>>
>> 		while (bit--) {
>> 			if (flags & (1<<bit)) {
>> 				strcat(flag_string, strings[bit]);
>> 			}
>> 		}
>>
>> 		item = proto_tree_add_text(tree, tvb, offset + 0, 8, "export (inode %u)", fileid);
>> 		subtree = proto_item_add_subtree(item, ett_nfsv4_fh_export);
>> 		
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_export_fileid,
>> 					   tvb, offset + 0, 4, fileid);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_export_generation,
>> 					   tvb, offset + 4, 4, snapgen);
>> 		item = proto_tree_add_text(tree, tvb, offset + 8, 16, "file (inode %u)", inum);
>> 		subtree = proto_item_add_subtree(item, ett_nfsv4_fh_file);
>> 		item = proto_tree_add_uint_format(subtree, hf_nfs_fh_flags,
>> 						  tvb, offset + 8, 2, flags,
>> 						  "Flags: %#02x%s", flags,
>> 						  flag_string);
>> 		flag_tree = proto_item_add_subtree(item, ett_nfsv4_fh_file_flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_mntpoint, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_snapdir, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_snapdir_ent, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_empty, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_vbn_access, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_multivolume, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_metadata, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_orphan, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_foster, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_named_attr, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_exp_snapdir, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_vfiler, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_aggr, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_striped, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_private, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(flag_tree, hf_nfs_fh_file_flag_next_gen, tvb, offset+8, 2, flags);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_snapid, tvb,
>> 					   offset + 10, 1, snapid);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_unused, tvb,
>> 					   offset + 11, 1, unused);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_fileid, tvb,
>> 					   offset + 12, 4, inum);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_generation, tvb,
>> 					   offset + 16, 4, generation);
>> 		item = proto_tree_add_uint(subtree, hf_nfs_fh_fsid, tvb,
>> 					   offset + 20, 4, fsid);
>> 		item = proto_tree_add_uint_format(tree, hf_nfs_fh_handle_type,
>> 						  tvb, offset+24, 4, handle_type,
>> 						  "Handle type: %s(%#02x)", handle_string, handle_type);
>> 	}
>> }
>>
>> #define NETAPP_GX_FH3_LENGTH		44
>> #define NFS3GX_FH_TREE_MASK		0x80
>> #define NFS3GX_FH_JUN_MASK		0x40
>> #define NFS3GX_FH_VER_MASK		0x3F
>> #define SPINNP_FH_FLAG_RESV1            0x80
>> #define SPINNP_FH_FLAG_RESV2            0x40
>> #define SPINNP_FH_FLAG_ONTAP_MASK	0x20
>> #define SPINNP_FH_FLAG_STRIPED_MASK	0x10
>> #define SPINNP_FH_FLAG_EMPTY_MASK	0x08
>> #define SPINNP_FH_FLAG_SNAPDIR_ENT_MASK 0x04
>> #define SPINNP_FH_FLAG_SNAPDIR_MASK	0x02
>> #define SPINNP_FH_FLAG_STREAMDIR_MASK	0x01
>>
>> static void
>> dissect_fhandle_data_NETAPP_GX_v3(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
>> {
>>     proto_tree *field_tree;
>>     proto_item *tf;
>>     guint16     cluster_id;
>>     guint16     epoch;
>>     guint32     export_id;
>>     guint32     export_uid;
>>     guint8      flags;
>>     guint8      reserved;
>>     guint32     local_dsid;
>>     guint32     spinfile_id;
>>     guint32     spinfile_uid;
>>     guint8      utility;
>>     guint8      volcnt;
>>     guint32	offset = 0;
>> 	 
>>     if (tree) {
>>         /* = utility = */		 
>>         utility = tvb_get_guint8(tvb, offset);	
>> 	tf = proto_tree_add_uint_format(tree, hf_gxfh3_utlfield, tvb,
>>                                         offset, 1, utility,
>> 		                        "  utility: 0x%02x",utility);
>>
>>
>>         field_tree = proto_item_add_subtree(tf, ett_nfs_gxfh3_utlfield);
>>         if (utility & NFS3GX_FH_TREE_MASK) {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_utlfield_tree_w, tvb, 
>> 	                            offset, 1, utility);
>> 	} 
>> 	else {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_utlfield_tree_r, tvb, 
>> 	                            offset, 1, utility);
>> 	}				                    	
>>         if (utility & NFS3GX_FH_JUN_MASK) {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_utlfield_jun, tvb, 
>> 	                            offset, 1, utility);
>> 	} 
>> 	else {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_utlfield_jun_not, tvb, 
>> 	                            offset, 1, utility);
>> 	}				                    	
>> 	proto_tree_add_uint(field_tree, hf_gxfh3_utlfield_ver, tvb, 
>> 	                            offset, 1, utility);
>> 	                            
>>         /* = volume count== */		 
>>         volcnt = tvb_get_guint8(tvb, offset+1);	
>> 	proto_tree_add_uint_format(tree, hf_gxfh3_volcnt, tvb,
>>                                    offset+1, 1, volcnt,
>> 		                   "  volume count: 0x%02x (%d)", volcnt, volcnt);
>>         /* = epoch = */		 
>>         epoch = tvb_get_letohs(tvb, offset+2);	
>> 	proto_tree_add_uint_format(tree, hf_gxfh3_epoch, tvb,
>>                                    offset+2, 2, epoch,
>> 		                   "  epoch: 0x%04x (%u)", epoch, epoch);       
>>         /* = spin file handle = */		 
>>         local_dsid   = tvb_get_letohl(tvb, offset+4); 
>>         cluster_id   = tvb_get_letohs(tvb, offset+8); 
>>         reserved     = tvb_get_guint8(tvb, offset+10);	
>>         flags        = tvb_get_guint8(tvb, offset+11);	
>>         spinfile_id  = tvb_get_letohl(tvb, offset+12); 
>>         spinfile_uid = tvb_get_letohl(tvb, offset+16); 
>>         
>> 	tf = proto_tree_add_text(tree, tvb, offset+4, 16, 
>> 	                         "  spin file handle");
>>         field_tree = proto_item_add_subtree(tf, ett_nfs_gxfh3_sfhfield);
>>         
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_ldsid, tvb, 
>> 	                           offset+4, 4, local_dsid,
>> 	                           " local dsid: 0x%08x (%u)", local_dsid, local_dsid);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_cid, tvb,
>>                                    offset+8, 2, cluster_id,
>>  	                           " cluster id: 0x%04x (%u)", cluster_id, cluster_id);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_resv, tvb,
>>                                    offset+10, 1, reserved,
>>  	                           " reserved: 0x%02x (%u)", reserved, reserved);
>>  	                           
>>  	                           
>>        	tf = proto_tree_add_uint_format(field_tree, hf_gxfh3_sfhflags, tvb,
>>                                         offset+11, 1, utility,
>> 		                        " flags: 0x%02x", flags);
>>         field_tree = proto_item_add_subtree(tf, ett_nfs_gxfh3_sfhflags);
>> 	proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_resv1, tvb, 
>> 	                    offset+11, 1, flags);
>> 	proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_resv2, tvb, 
>> 	                    offset+11, 1, flags);
>> 	                    
>>         if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_ontap7G, tvb, 
>> 	                            offset+11, 1, flags);
>> 	} 
>> 	else {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_ontapGX, tvb, 
>> 	                            offset+11, 1, flags);
>> 	}				                    	
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_striped, tvb, 
>> 	                            offset+11, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_empty, tvb, 
>> 	                            offset+11, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_snapdirent, tvb, 
>> 	                            offset+11, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_snapdir, tvb, 
>> 	                            offset+11, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_streamdir, tvb, 
>> 	                            offset+11, 1, flags);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_spinfid, tvb, 
>> 	                           offset+12, 4, spinfile_id,
>> 	                           "spin file id: 0x%08x (%u)", spinfile_id, spinfile_id);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_spinfuid, tvb, 
>> 	                           offset+16, 4, spinfile_id,
>> 	                           "spin file unique id: 0x%08x (%u)", spinfile_uid, spinfile_uid);
>>         
>>         /* = spin file handle (mount point) = */		 
>>         local_dsid   = tvb_get_letohl(tvb, offset+20); 
>>         cluster_id   = tvb_get_letohs(tvb, offset+24); 
>>         reserved     = tvb_get_guint8(tvb, offset+26);	
>>         flags        = tvb_get_guint8(tvb, offset+27);	
>>         spinfile_id  = tvb_get_letohl(tvb, offset+28); 
>>         spinfile_uid = tvb_get_letohl(tvb, offset+32); 
>>         
>> 	tf = proto_tree_add_text(tree, tvb, offset+20, 16, 
>> 	                         "  spin (mount point) file handle");
>>         field_tree = proto_item_add_subtree(tf, ett_nfs_gxfh3_sfhfield);
>>         
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_ldsid, tvb, 
>> 	                           offset+20, 4, local_dsid,
>> 	                           " local dsid: 0x%08x (%u)", local_dsid, local_dsid);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_cid, tvb,
>>                                    offset+24, 2, cluster_id,
>>  	                           " cluster id: 0x%04x (%u)", cluster_id, cluster_id);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_resv, tvb,
>>                                    offset+26, 1, reserved,
>>  	                           " reserved: 0x%02x (%u)", reserved, reserved);
>>  	                           
>>  	                           
>>        	tf = proto_tree_add_uint_format(field_tree, hf_gxfh3_sfhflags, tvb,
>>                                         offset+27, 1, utility,
>> 		                        " flags: 0x%02x", flags);
>>         field_tree = proto_item_add_subtree(tf, ett_nfs_gxfh3_sfhflags);
>> 	proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_resv1, tvb, 
>> 	                    offset+27, 1, flags);
>> 	proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_resv2, tvb, 
>> 	                    offset+27, 1, flags);
>> 	                    
>>         if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_ontap7G, tvb, 
>> 	                            offset+27, 1, flags);
>> 	} 
>> 	else {
>> 		proto_tree_add_uint(field_tree, hf_gxfh3_sfhflags_ontapGX, tvb, 
>> 	                            offset+27, 1, flags);
>> 	}				                    	
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_striped, tvb, 
>> 	                            offset+27, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_empty, tvb, 
>> 	                            offset+27, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_snapdirent, tvb, 
>> 	                            offset+27, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_snapdir, tvb, 
>> 	                            offset+27, 1, flags);
>> 	proto_tree_add_boolean(field_tree, hf_gxfh3_sfhflags_streamdir, tvb, 
>> 	                            offset+27, 1, flags);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_spinfid, tvb, 
>> 	                           offset+28, 4, spinfile_id,
>> 	                           "spin file id: 0x%08x (%u)", spinfile_id, spinfile_id);
>> 	proto_tree_add_uint_format(field_tree, hf_gxfh3_spinfuid, tvb, 
>> 	                           offset+32, 4, spinfile_id,
>> 	                           "spin file unique id: 0x%08x (%u)", spinfile_uid, spinfile_uid);    
>>         /* = export point id  = */		 
>>         export_id  = tvb_get_letohl(tvb, offset+36); 
>>         export_uid = tvb_get_letohl(tvb, offset+40); 
>> 	proto_tree_add_uint_format(tree, hf_gxfh3_exportptid, tvb, 
>> 	                           offset+36, 4, spinfile_id,
>> 	                           "  export point id: 0x%08x (%u)", export_id, export_id);
>>         /* = export point unique id  = */		 
>>         export_uid = tvb_get_letohl(tvb, offset+40); 
>> 	proto_tree_add_uint_format(tree, hf_gxfh3_exportptuid, tvb, 
>> 	                           offset+40, 4, spinfile_id,
>> 	                           "  export point unique id: 0x%08x (%u)", export_uid, export_uid);
>> 	                           
>>     }  /* end of (tree) */
>> }
>>
>> /* 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, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	int offset=0;
>> 	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, packet_info *pinfo _U_, proto_tree *tree)
>> {
>> 	guint fhlen=tvb_length(tvb);
>>
>> 	proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, fhlen, FALSE);
>> }
>>
>>
>> static void
>> dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
>>     proto_tree *tree, unsigned int fhlen, gboolean hidden, guint32 *hash)
>> {
>> 	/* this is to set up fhandle display filters to find both packets
>> 	   of an RPC call */
>> 	if(nfs_fhandle_reqrep_matching && (!hidden) ){
>> 		nfs_fhandle_data_t *old_fhd=NULL;
>>
>> 		if( !pinfo->fd->flags.visited ){
>> 			nfs_fhandle_data_t fhd;
>>
>> 			/* first check if we have seen this fhandle before */
>> 			fhd.len=fhlen;
>> 			fhd.fh=(const unsigned char *)tvb_get_ptr(tvb, offset, fhlen);
>> 			old_fhd=store_nfs_file_handle(&fhd);
>>
>> 			/* XXX here we should really check that we havent stored
>> 			   this fhandle for this frame number already.
>> 		   	   We should also make sure we can handle when we have multiple
>> 		   	   fhandles seen for the same frame, which WILL happen for certain
>> 		   	   nfs calls. For now, we dont handle this and those calls will
>> 		   	   not work properly with this feature
>> 			*/
>> 			se_tree_insert32(nfs_fhandle_frame_table, pinfo->fd->num, old_fhd);
>> 		}
>> 	}
>>
>> 	/* create a semiunique hash value for the filehandle */
>> 	{
>> 		guint32 fhhash;
>> 		guint32 i;
>> 		proto_item *fh_item;
>>
>> 		for(fhhash=0,i=0;i<(fhlen-3);i+=4){
>> 			guint32 val;
>> 			val = tvb_get_ntohl(tvb, offset+i);
>> 			fhhash ^= val;
>> 			fhhash += val;
>> 		}
>> 		if(hidden){
>> 			fh_item=proto_tree_add_uint_hidden(tree, hf_nfs_fh_hash, tvb, offset,
>> 				fhlen, fhhash);
>> 		} else {
>> 			fh_item=proto_tree_add_uint(tree, hf_nfs_fh_hash, tvb, offset,
>> 				fhlen, fhhash);
>> 		}
>> 		PROTO_ITEM_SET_GENERATED(fh_item);
>> 		if(hash){
>> 			*hash=fhhash;
>> 		}
>> 	}
>> 	if(nfs_file_name_snooping){
>> 		nfs_name_snoop_fh(pinfo, tree, tvb, offset, fhlen, hidden);
>> 	}
>>
>> 	if(!hidden){
>> 		tvbuff_t *fh_tvb;
>> 		int real_length;
>>
>> 		proto_tree_add_text(tree, tvb, offset, 0,
>> 			"decode type as: %s", val_to_str(default_nfs_fhandle_type, names_fhtype, "Unknown"));
>>
>>
>> 		real_length=fhlen;
>> 		if(real_length<tvb_length_remaining(tvb, offset)){
>> 			real_length=tvb_length_remaining(tvb, offset);
>> 		}
>> 		fh_tvb=tvb_new_subset(tvb, offset, real_length, fhlen);
>> 		if(!dissector_try_port(nfs_fhandle_table, default_nfs_fhandle_type, fh_tvb, pinfo, tree)){
>> 			dissect_fhandle_data_unknown(fh_tvb, pinfo, tree);
>> 		}
>> 	}
>> }
>>
>> void
>> dissect_fhandle_hidden(packet_info *pinfo, proto_tree *tree, int frame)
>> {
>> 	nfs_fhandle_data_t *nfd;
>>
>> 	nfd=se_tree_lookup32(nfs_fhandle_frame_table, frame);
>> 	if(nfd && nfd->len){
>> 		dissect_fhandle_data(nfd->tvb, 0, pinfo, tree, nfd->len, TRUE, NULL);
>> 	}
>> }
>>
>>
>> /***************************/
>> /* NFS Version 2, RFC 1094 */
>> /***************************/
>>
>>
>> /* RFC 1094, Page 12..14 */
>> static const value_string names_nfs_stat[] =
>> {
>> 	{	0,	"NFS_OK" },
>> 	{	1,	"NFSERR_PERM" },
>> 	{	2,	"NFSERR_NOENT" },
>> 	{	5,	"NFSERR_IO" },
>> 	{	6,	"NFSERR_NXIO" },
>> 	{	13,	"NFSERR_ACCES" },
>> 	{	17,	"NFSERR_EXIST" },
>> 	{	18,	"NFSERR_XDEV" },	/* not in spec, but can happen */
>> 	{	19,	"NFSERR_NODEV" },
>> 	{	20,	"NFSERR_NOTDIR" },
>> 	{	21,	"NFSERR_ISDIR" },
>> 	{	22,	"NFSERR_INVAL" },	/* not in spec, but I think it can happen */
>> 	{	26,	"NFSERR_TXTBSY" },	/* not in spec, but I think it can happen */
>> 	{	27,	"NFSERR_FBIG" },
>> 	{	28,	"NFSERR_NOSPC" },
>> 	{	30,	"NFSERR_ROFS" },
>> 	{	31,	"NFSERR_MLINK" },	/* not in spec, but can happen */
>> 	{	45,	"NFSERR_OPNOTSUPP" }, /* not in spec, but I think it can happen */
>> 	{	63,	"NFSERR_NAMETOOLONG" },
>> 	{	66,	"NFSERR_NOTEMPTY" },
>> 	{	69,	"NFSERR_DQUOT" },
>> 	{	70,	"NFSERR_STALE" },
>> 	{	99,	"NFSERR_WFLUSH" },
>> 	{	0,	NULL }
>> };
>>
>> /* RFC 1094, Page 12..14 */
>> static int
>> dissect_stat(tvbuff_t *tvb, int offset, proto_tree *tree,
>> 	guint32 *status)
>> {
>> 	guint32 stat;
>> 	proto_item *stat_item;
>>
>> 	stat = tvb_get_ntohl(tvb, offset+0);
>>
>> 	if (tree) {
>> 		proto_tree_add_uint(tree, hf_nfs_stat, tvb, offset+0, 4,
>> 			stat);
>> 		stat_item = proto_tree_add_uint(tree, hf_nfs_nfsstat, tvb,
>> 			offset+0, 4, stat);
>> 		PROTO_ITEM_SET_HIDDEN(stat_item);
>> 	}
>>
>> 	offset += 4;
>>
>> 	if (status) *status = stat;
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 12..14 */
>> static int
>> dissect_nfs2_rmdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			proto_item_append_text(tree, ", RMDIR Reply");
>> 			break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", RMDIR Reply  Error:%s", err);
>> 	}
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_symlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			proto_item_append_text(tree, ", SYMLINK Reply");
>> 			break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", SYMLINK Reply  Error:%s", err);
>> 	}
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_link_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			proto_item_append_text(tree, ", LINK Reply");
>> 			break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", LINK Reply  Error:%s", err);
>> 	}
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_rename_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			proto_item_append_text(tree, ", RENAME Reply");
>> 			break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", RENAME Reply  Error:%s", err);
>> 	}
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_remove_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			proto_item_append_text(tree, ", REMOVE Reply");
>> 			break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", REMOVE Reply  Error:%s", err);
>> 	}
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 15 */
>> static int
>> dissect_ftype(tvbuff_t *tvb, int offset, proto_tree *tree, const char* name)
>> {
>> 	guint32 ftype;
>> 	const 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,
>>     const char *name, guint32 *hash)
>> {
>> 	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);
>> 	}
>>
>> 	/* are we snooping fh to filenames ?*/
>> 	if((!pinfo->fd->flags.visited) && nfs_file_name_snooping){
>> 		rpc_call_info_value *civ=pinfo->private_data;
>>
>> 		/* NFS v2 LOOKUP, CREATE, MKDIR calls might give us a mapping*/
>> 		if( (civ->prog==100003)
>> 		  &&(civ->vers==2)
>> 		  &&(!civ->request)
>> 		  &&((civ->proc==4)||(civ->proc==9)||(civ->proc==14))
>> 		) {
>> 			nfs_name_snoop_add_fh(civ->xid, tvb,
>> 				offset, 32);
>> 		}
>>
>> 		/* MOUNT v1,v2 MNT replies might give us a filehandle*/
>> 		if( (civ->prog==100005)
>> 		  &&(civ->proc==1)
>> 		  &&((civ->vers==1)||(civ->vers==2))
>> 		  &&(!civ->request)
>> 		) {
>> 			nfs_name_snoop_add_fh(civ->xid, tvb,
>> 				offset, 32);
>> 		}
>> 	}
>>
>> 	dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE, FALSE, hash);
>>
>> 	offset += FHSIZE;
>> 	return offset;
>> }
>>
>> /* RFC 1094, Page 15 */
>> static int
>> dissect_nfs2_statfs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>>
>> 	offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
>> 	}
>> 	proto_item_append_text(tree, ", STATFS Call FH:0x%08x", hash);
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_readlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>>
>> 	offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
>> 	}
>> 	proto_item_append_text(tree, ", READLINK Call FH:0x%08x", hash);
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_getattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>>
>> 	offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
>> 	}
>> 	proto_item_append_text(tree, ", GETATTR Call FH:0x%08x", hash);
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 15 */
>> static int
>> dissect_timeval(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_time, int hf_time_sec, int hf_time_usec)
>> {
>> 	guint32	seconds;
>> 	guint32 useconds;
>> 	nstime_t ts;
>>
>> 	proto_item* time_item;
>> 	proto_tree* time_tree = NULL;
>>
>> 	seconds = tvb_get_ntohl(tvb, offset+0);
>> 	useconds = tvb_get_ntohl(tvb, offset+4);
>> 	ts.secs = seconds;
>> 	ts.nsecs = useconds*1000;
>>
>> 	if (tree) {
>> 		time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
>> 				&ts);
>> 		if (time_item)
>> 			time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval);
>> 	}
>>
>> 	if (time_tree) {
>> 		proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
>> 					seconds);
>> 		proto_tree_add_uint(time_tree, hf_time_usec, tvb, offset+4, 4,
>> 					useconds);
>> 	}
>> 	offset += 8;
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 16 */
>> static 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		},
>> };
>>
>> static int
>> dissect_mode(tvbuff_t *tvb, int offset, proto_tree *tree, const 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, proto_tree *tree, const 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, -1,
>> 			"%s", name);
>> 		fattr_tree = proto_item_add_subtree(fattr_item, ett_nfs_fattr);
>> 	}
>>
>> 	offset = dissect_ftype(tvb, offset, fattr_tree, "type");
>> 	offset = dissect_mode(tvb, offset, fattr_tree, "mode");
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_nlink, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_uid, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_gid, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_size, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_blocksize, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_rdev, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_blocks, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_fsid, offset);
>> 	offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs_fattr_fileid, offset);
>>
>> 	offset = dissect_timeval(tvb, offset, fattr_tree, hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
>> 	offset = dissect_timeval(tvb, offset, fattr_tree, hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
>> 	offset = dissect_timeval(tvb, offset, fattr_tree, hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_usec);
>>
>> 	/* 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 */
>> static int
>> dissect_sattr(tvbuff_t *tvb, int offset, proto_tree *tree, const 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, -1,
>> 			"%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, 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, 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, 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, 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, sattr_tree, hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
>> 	} 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, sattr_tree, hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
>> 	} 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 */
>> static int
>> dissect_filename(tvbuff_t *tvb, int offset,
>>     proto_tree *tree, int hf, char **string_ret)
>> {
>> 	offset = dissect_rpc_string(tvb, tree, hf, offset, string_ret);
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 17 */
>> static int
>> dissect_path(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, char **name)
>> {
>> 	offset = dissect_rpc_string(tvb, tree, hf, offset, name);
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 17,18 */
>> static int
>> dissect_attrstat(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, const char *funcname)
>> {
>> 	guint32 status;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			offset = dissect_fattr(tvb, offset, tree, "attributes");
>> 			proto_item_append_text(tree, ", %s Reply", funcname);
>> 		break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
>> 			}
>> 			proto_item_append_text(tree, ", %s Reply  Error:%s", funcname, err);
>> 		break;
>> 	}
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 17,18 */
>> static int
>> dissect_nfs2_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	offset = dissect_attrstat(tvb, offset, tree, pinfo, "WRITE");
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_setattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	offset = dissect_attrstat(tvb, offset, tree, pinfo, "SETATTR");
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_getattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
>> {
>> 	offset = dissect_attrstat(tvb, offset, tree, pinfo, "GETATTR");
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 18 */
>> static int
>> dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char* label, guint32 *hash, 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, -1,
>> 			"%s", label);
>> 		diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs);
>> 	}
>>
>> 	/* are we snooping fh to filenames ?*/
>> 	if((!pinfo->fd->flags.visited) && nfs_file_name_snooping){
>> 		/* v2 LOOKUP, CREATE, MKDIR calls might give us a mapping*/
>> 		rpc_call_info_value *civ=pinfo->private_data;
>>
>> 		if( (civ->prog==100003)
>> 		  &&(civ->vers==2)
>> 		  &&(civ->request)
>> 		  &&((civ->proc==4)||(civ->proc==9)||(civ->proc==14))
>> 		) {
>> 			nfs_name_snoop_add_name(civ->xid, tvb,
>> 				offset+36, tvb_get_ntohl(tvb, offset+32),
>> 				offset, 32, NULL);
>> 		}
>> 	}
>>
>> 	offset = dissect_fhandle(tvb, offset, pinfo, diropargs_tree, "dir", hash);
>> 	offset = dissect_filename(tvb, offset, diropargs_tree, hf_nfs_name, name);
>>
>> 	/* now we know, that diropargs is shorter */
>> 	if (diropargs_item) {
>> 		proto_item_set_len(diropargs_item, offset - old_offset);
>> 	}
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 18 */
>> static int
>> dissect_nfs2_rmdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>> 	char *name=NULL;
>>
>> 	offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
>> 	}
>> 	proto_item_append_text(tree, ", RMDIR Call DH:0x%08x/%s", hash, name);
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_remove_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>> 	char *name=NULL;
>>
>> 	offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
>> 	}
>> 	proto_item_append_text(tree, ", REMOVE Call DH:0x%08x/%s", hash, name);
>>
>> 	return offset;
>> }
>>
>> static int
>> dissect_nfs2_lookup_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
>> {
>> 	guint32 hash;
>> 	char *name=NULL;
>>
>> 	offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
>>
>> 	if (check_col(pinfo->cinfo, COL_INFO)) {
>> 		col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
>> 	}
>> 	proto_item_append_text(tree, ", LOOKUP Call DH:0x%08x/%s", hash, name);
>>
>> 	return offset;
>> }
>>
>>
>> /* RFC 1094, Page 18 */
>> static int
>> dissect_diropres(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *funcname)
>> {
>> 	guint32	status;
>> 	guint32 hash;
>> 	const char *err;
>>
>> 	offset = dissect_stat(tvb, offset, tree, &status);
>> 	switch (status) {
>> 		case 0:
>> 			offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash);
>> 			offset = dissect_fattr  (tvb, offset, tree, "attributes");
>> 			if (check_col(pinfo->cinfo, COL_INFO)) {
>> 				col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
>> 			}
>> 			proto_item_append_text(tree, ", %s Reply FH:0x%08x", funcname, hash);
>> 		break;
>> 		default:
>> 			err=val_to_str(status, names_nfs_stat, "Unknown e