[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