[pnfs] Wireshark: Yet another fix for draft 10

Benny Halevy bhalevy at panasas.com
Tue Jun 5 12:00:48 EDT 2007


Thanks!

I've copied these files onto http://wiki.linux-nfs.org/wiki/index.php/Wireshark_Patches
I didn't see how to upload the files as attachments onto the wiki...
clue anyone?

Benny

Tigran Mkrtchyan wrote:
> Benny Halevy wrote:
>> Tigran Mkrtchyan wrote:
>>> fixed GETDEVICEINFO for file layout.
>> Great.
>> Can you please send to the list one patch against the wireshark release
>> containing everything you got?
>>
> 
> 
> It's actulay las patch from Andy ( from 31.05.2007) + two fixes for 
> GETDEVICELIST and GETDEVICEINFO.
> 
> just copy both attached files into wireshark's epan/dissectors/ 
> directory (if you prefer patch, let me know).
> I have used latest form home page ( wireshark-0.99.5.tar.gz ).
> 
> 
>>> Benny, do you have object layout as well?
>> Not yet.
> 
> :(
> 
>>> What about merging?
>> I'm not sure what you mean.  If you're asking about merging
>> the object layout with the rest, then "not yet" again :)
>>
> 
> obsolete by prevision answer.
> 
>>> Regards,
>>> 	TIgran.
>>>
>>>
>>> ________________________________________________________________________
>>> Tigran Mkrtchyan                               DESY, IT,
>>> tigran.mkrtchyan at desy.de                       Notkestrasse 85,
>>> Tel: + 49 40 89983946                          Hamburg 22607,
>>> Fax: + 49 40 89984429                          Germany.
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> /* 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_layoutlen = -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_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_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;
>>> static int hf_nfs_exch_id_flags4 = -1;
>>> static int hf_nfs_nii_domain4 = -1;
>>> static int hf_nfs_nii_name4 = -1;
>>> static int hf_nfs_create_session_flags4 = -1;
>>> static int hf_nfs_cachethis4 = -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);
>&g