sensitivity of packet range options fine tuning:
[obnox/wireshark/wip.git] / packet-nfs.c
index 364095b2a75e7fb2f50669e0b7374ce68dd39e67..28dec3cb6d857bc6a9dce38b967f8db3b3d033d5 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for nfs dissection
  * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
  * Copyright 2000-2002, Mike Frisch <frisch@hummingbird.com> (NFSv4 decoding)
- * $Id: packet-nfs.c,v 1.73 2002/06/20 20:55:49 guy Exp $
+ * $Id: packet-nfs.c,v 1.94 2003/09/28 01:52:57 sahlberg Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 #endif
 
 
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
 #include <string.h>
 
 
 #include "packet-rpc.h"
 #include "packet-nfs.h"
 #include "prefs.h"
-
+#include "epan/int-64bit.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_fsid_major = -1;
@@ -256,6 +255,7 @@ 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;
@@ -282,6 +282,9 @@ 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;
 
 static gint ett_nfs = -1;
 static gint ett_nfs_fh_encoding = -1;
@@ -382,6 +385,9 @@ 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;
 
 
 /* fhandle displayfilters to match also corresponding request/response
@@ -395,8 +401,8 @@ GHashTable *nfs_fhandle_frame_table = NULL;
 static gint
 nfs_fhandle_data_equal(gconstpointer k1, gconstpointer k2)
 {
-       nfs_fhandle_data_t *key1 = (nfs_fhandle_data_t *)k1;
-       nfs_fhandle_data_t *key2 = (nfs_fhandle_data_t *)k2;
+       const nfs_fhandle_data_t *key1 = (const nfs_fhandle_data_t *)k1;
+       const nfs_fhandle_data_t *key2 = (const nfs_fhandle_data_t *)k2;
 
        return (key1->len==key2->len)
             &&(!memcmp(key1->fh, key2->fh, key1->len));
@@ -404,7 +410,7 @@ nfs_fhandle_data_equal(gconstpointer k1, gconstpointer k2)
 static guint
 nfs_fhandle_data_hash(gconstpointer k)
 {
-       nfs_fhandle_data_t *key = (nfs_fhandle_data_t *)k;
+       const nfs_fhandle_data_t *key = (const nfs_fhandle_data_t *)k;
        int i;
        int hash;
 
@@ -421,7 +427,7 @@ nfs_fhandle_data_free_all(gpointer key_arg _U_, gpointer value, gpointer user_da
 
        if(nns->fh){
                tvb_free(nns->tvb);
-               nns->tvb=NULL;          
+               nns->tvb=NULL;
                g_free((gpointer)nns->fh);
                nns->fh=NULL;
                nns->len=0;
@@ -432,15 +438,15 @@ nfs_fhandle_data_free_all(gpointer key_arg _U_, gpointer value, gpointer user_da
 static gint
 nfs_fhandle_frame_equal(gconstpointer k1, gconstpointer k2)
 {
-       int key1 = (int)k1;
-       int key2 = (int)k2;
+       guint32 key1 = (guint32)k1;
+       guint32 key2 = (guint32)k2;
 
        return key1==key2;
 }
 static guint
 nfs_fhandle_frame_hash(gconstpointer k)
 {
-       int key = (int)k;
+       guint32 key = (guint32)k;
 
        return key;
 }
@@ -480,7 +486,7 @@ nfs_fhandle_reqrep_matching_init(void)
                        nfs_fhandle_data_init_count * sizeof(nfs_fhandle_data_t),
                        G_ALLOC_ONLY);
        }
-               
+
 }
 
 
@@ -501,7 +507,7 @@ typedef struct nfs_name_snoop {
 typedef struct nfs_name_snoop_key {
        int key;
        int fh_length;
-       unsigned char *fh;
+       const unsigned char *fh;
 } nfs_name_snoop_key_t;
 
 static GMemChunk *nfs_name_snoop_chunk = NULL;
@@ -517,8 +523,8 @@ static GHashTable *nfs_name_snoop_known = NULL;
 static gint
 nfs_name_snoop_matched_equal(gconstpointer k1, gconstpointer k2)
 {
-       nfs_name_snoop_key_t *key1 = (nfs_name_snoop_key_t *)k1;
-       nfs_name_snoop_key_t *key2 = (nfs_name_snoop_key_t *)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)
@@ -527,9 +533,9 @@ nfs_name_snoop_matched_equal(gconstpointer k1, gconstpointer k2)
 static guint
 nfs_name_snoop_matched_hash(gconstpointer k)
 {
-       nfs_name_snoop_key_t *key = (nfs_name_snoop_key_t *)k;
+       const nfs_name_snoop_key_t *key = (const nfs_name_snoop_key_t *)k;
        int i;
-       int hash;
+       guint hash;
 
        hash=key->key;
        for(i=0;i<key->fh_length;i++)
@@ -627,18 +633,18 @@ nfs_name_snoop_init(void)
                        nfs_name_snoop_key_init_count * sizeof(nfs_name_snoop_key_t),
                        G_ALLOC_ONLY);
        }
-               
+
 }
 
 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;
-       unsigned char *ptr=NULL;
+       const unsigned char *ptr=NULL;
 
        /* filter out all '.' and '..' names */
        if(!name){
-               ptr=(unsigned char *)tvb_get_ptr(tvb, name_offset, name_len);
+               ptr=(const unsigned char *)tvb_get_ptr(tvb, name_offset, name_len);
                if(ptr[0]=='.'){
                        if(ptr[1]==0){
                                return;
@@ -680,7 +686,7 @@ nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, i
        /* remove any old entry for this */
        old_nns=g_hash_table_lookup(nfs_name_snoop_unmatched, (gconstpointer)xid);
        if(old_nns){
-               /* if we havnt seen the reply yet, then there are no
+               /* 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);
@@ -702,6 +708,7 @@ nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, i
 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;
 
@@ -718,10 +725,11 @@ nfs_name_snoop_add_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
        }
 
        /* oki, we have a new entry */
-       nns->fh=g_malloc(fh_length);
-       memcpy(nns->fh, tvb_get_ptr(tvb, fh_offset, fh_length), fh_length);
+       fh=g_malloc(fh_length);
+       memcpy(fh, tvb_get_ptr(tvb, fh_offset, fh_length), fh_length);
+       nns->fh=fh;
        nns->fh_length=fh_length;
-       
+
        key=g_mem_chunk_alloc(nfs_name_snoop_key_chunk);
        key->key=0;
        key->fh_length=nns->fh_length;
@@ -795,7 +803,7 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
        if(!pinfo->fd->flags.visited){
                key.key=0;
                key.fh_length=fh_length;
-               key.fh=(unsigned char *)tvb_get_ptr(tvb, fh_offset, 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){
@@ -823,7 +831,7 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
        if(!nns){
                key.key=pinfo->fd->num;
                key.fh_length=fh_length;
-               key.fh=(unsigned char *)tvb_get_ptr(tvb, fh_offset, fh_length);
+               key.fh=(const unsigned char *)tvb_get_ptr(tvb, fh_offset, fh_length);
 
                nns=g_hash_table_lookup(nfs_name_snoop_known, &key);
        }
@@ -831,18 +839,18 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
        /* if we know the mapping, print the filename */
        if(nns){
                if(hidden){
-                       proto_tree_add_string_hidden(tree, hf_nfs_name, tvb, 
+                       proto_tree_add_string_hidden(tree, hf_nfs_name, tvb,
                                fh_offset, 0, nns->name);
                }else {
-                       proto_tree_add_string_format(tree, hf_nfs_name, tvb, 
+                       proto_tree_add_string_format(tree, hf_nfs_name, tvb,
                                fh_offset, 0, nns->name, "Name: %s", nns->name);
                }
                if(nns->full_name){
                        if(hidden){
-                               proto_tree_add_string_hidden(tree, hf_nfs_full_name, tvb, 
+                               proto_tree_add_string_hidden(tree, hf_nfs_full_name, tvb,
                                        fh_offset, 0, nns->name);
                        } else {
-                               proto_tree_add_string_format(tree, hf_nfs_full_name, tvb, 
+                               proto_tree_add_string_format(tree, hf_nfs_full_name, tvb,
                                        fh_offset, 0, nns->name, "Full Name: %s", nns->full_name);
                        }
                }
@@ -892,12 +900,12 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
        if (tree) {
                proto_item* fsid_item = NULL;
                proto_tree* fsid_tree = NULL;
-       
+
                fsid_item = proto_tree_add_text(tree, tvb,
-                       fsid_O, fsid_L, 
+                       fsid_O, fsid_L,
                        "file system ID: %d,%d", fsid_major, fsid_minor);
                if (fsid_item) {
-                       fsid_tree = proto_item_add_subtree(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);
@@ -938,7 +946,7 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
        guint32 fn_data_gen_L;
        guint32 gen;
        guint32 fn_L;
-       
+
        fn_O = nof;
        fn_len_O = fn_O;
        fn_len_L = 2;
@@ -954,11 +962,11 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
        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, 
+                       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);
@@ -985,7 +993,7 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
        guint32 xfn_data_gen_L;
        guint32 xgen;
        guint32 xfn_L;
-       
+
        xfn_O = nof;
        xfn_len_O = xfn_O;
        xfn_len_L = 2;
@@ -1001,11 +1009,11 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
        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, 
+                       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);
@@ -1062,10 +1070,10 @@ dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
                proto_tree* fsid_tree = NULL;
 
                fsid_item = proto_tree_add_text(tree, tvb,
-                       offset+12, 4, 
+                       offset+12, 4,
                        "file system ID: %d,%d", fsid_major, fsid_minor);
                if (fsid_item) {
-                       fsid_tree = proto_item_add_subtree(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);
@@ -1080,10 +1088,10 @@ dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
                proto_tree* xfsid_tree = NULL;
 
                xfsid_item = proto_tree_add_text(tree, tvb,
-                       offset+16, 4, 
+                       offset+16, 4,
                        "exported file system ID: %d,%d", xfsid_major, xfsid_minor);
                if (xfsid_item) {
-                       xfsid_tree = proto_item_add_subtree(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);
@@ -1130,7 +1138,7 @@ dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
                                "hash path: %s",
                                tvb_bytes_to_str(tvb,offset+5,hashlen));
                if (hash_item) {
-                       hash_tree = proto_item_add_subtree(hash_item, 
+                       hash_tree = proto_item_add_subtree(hash_item,
                                        ett_nfs_fh_hp);
                        if (hash_tree) {
                                proto_tree_add_uint(hash_tree,
@@ -1217,7 +1225,7 @@ dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, int offset, proto_tree *tree
                        goto out;
                }
        }
-               
+
        switch (auth_type) {
                case 0: {
                        /* no authentication */
@@ -1244,11 +1252,11 @@ dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, int offset, proto_tree *tree
                        fsid_inode = tvb_get_letohl(tvb, offset + 4);
                        if (tree) {
                                proto_item* fsid_item = proto_tree_add_text(tree, tvb,
-                                       offset+0, 8, 
+                                       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, 
+                                       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,
@@ -1345,10 +1353,10 @@ out:
 
 static void
 dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree,
-    int fhlen)
+    guint fhlen)
 {
-       int sublen;
-       int bytes_left;
+       guint sublen;
+       guint bytes_left;
        gboolean first_line;
 
        bytes_left = fhlen;
@@ -1371,7 +1379,7 @@ dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree,
 
 static void
 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
-    proto_tree *tree, unsigned int fhlen, gboolean hidden)
+    proto_tree *tree, unsigned int fhlen, gboolean hidden, guint32 *hash)
 {
        unsigned int fhtype = FHT_UNKNOWN;
 
@@ -1385,32 +1393,34 @@ dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
           of an RPC call */
        if(nfs_fhandle_reqrep_matching && (!hidden) ){
                nfs_fhandle_data_t *old_fhd=NULL;
+               unsigned char *fh;
 
                if( !pinfo->fd->flags.visited ){
                        nfs_fhandle_data_t fhd;
 
                        /* first check if we have seen this fhandle before */
                        fhd.len=fhlen;
-                       fhd.fh=(unsigned char *)tvb_get_ptr(tvb, offset, fhlen);
-                       old_fhd=g_hash_table_lookup(nfs_fhandle_data_table, 
+                       fhd.fh=(const unsigned char *)tvb_get_ptr(tvb, offset, fhlen);
+                       old_fhd=g_hash_table_lookup(nfs_fhandle_data_table,
                                (gconstpointer)&fhd);
                        if(!old_fhd){
                                /* oh, a new fhandle, alloc struct and store it in the table*/
                                old_fhd=g_mem_chunk_alloc(nfs_fhandle_data_chunk);
                                old_fhd->len=fhlen;
-                               old_fhd->fh=g_malloc(fhlen);
-                               memcpy(old_fhd->fh, fhd.fh, fhlen);
+                               fh=g_malloc(fhlen);
+                               memcpy(fh, fhd.fh, fhlen);
+                               old_fhd->fh=fh;
                                old_fhd->tvb=tvb_new_real_data(old_fhd->fh, old_fhd->len, old_fhd->len);
-                               g_hash_table_insert(nfs_fhandle_data_table, 
+                               g_hash_table_insert(nfs_fhandle_data_table,
                                        (gpointer)old_fhd, (gpointer)old_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 
+                          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 
+                          not work properly with this feature
                        */
                        g_hash_table_insert(nfs_fhandle_frame_table,
                                        (gpointer)pinfo->fd->num,
@@ -1430,18 +1440,21 @@ dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        fhhash += val;
                }
                if(hidden){
-                       proto_tree_add_uint_hidden(tree, hf_nfs_fh_hash, tvb, offset, 
+                       proto_tree_add_uint_hidden(tree, hf_nfs_fh_hash, tvb, offset,
                                fhlen, fhhash);
                } else {
-                       proto_tree_add_uint(tree, hf_nfs_fh_hash, tvb, offset, 
+                       proto_tree_add_uint(tree, hf_nfs_fh_hash, tvb, offset,
                                fhlen, fhhash);
                }
+               if(hash){
+                       *hash=fhhash;
+               }
        }
        if(nfs_file_name_snooping){
                nfs_name_snoop_fh(pinfo, tree, tvb, offset, fhlen, hidden);
        }
 
-       if(!hidden){            
+       if(!hidden){
                /* calculate (heuristically) fhtype */
                switch (fhlen) {
                case 12:
@@ -1478,7 +1491,7 @@ dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                int wrong=0;
                                for (len2=5+len1;len2<32;len2++) {
                                        if (tvb_get_guint8(tvb,offset+len2)) {
-                                               wrong=1;        
+                                               wrong=1;
                                                break;
                                        }
                                }
@@ -1502,9 +1515,9 @@ dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
 type_ready:
 
        if(!hidden){
-               proto_tree_add_text(tree, tvb, offset, 0, 
+               proto_tree_add_text(tree, tvb, offset, 0,
                        "type: %s", val_to_str(fhtype, names_fhtype, "Unknown"));
-       
+
 
                switch (fhtype) {
                case FHT_SVR4:
@@ -1535,7 +1548,7 @@ void
 dissect_fhandle_hidden(packet_info *pinfo, proto_tree *tree, nfs_fhandle_data_t *nfd)
 {
        if(nfd && nfd->len){
-               dissect_fhandle_data(nfd->tvb, 0, pinfo, tree, nfd->len, TRUE);
+               dissect_fhandle_data(nfd->tvb, 0, pinfo, tree, nfd->len, TRUE, NULL);
        }
 }
 
@@ -1632,6 +1645,17 @@ static const value_string names_nfs_stat4[] = {
        {       10035,  "NFS4ERR_RECLAIM_CONFLICT"                      },
        {       10036,  "NFS4ERR_BADXDR"                                },
        {       10037,  "NFS4ERR_LOCKS_HELD"                            },
+       {       10038,  "NFS4ERR_OPENMODE"      },
+       {       10039,  "NFS4ERR_BADOWNER"      },
+       {       10040,  "NFS4ERR_BADCHAR"               },
+       {       10041,  "NFS4ERR_BADNAME"    },
+       {       10042,  "NFS4ERR_BAD_RANGE"     },
+       {       10043,  "NFS4ERR_LOCK_NOTSUPP"  },
+       {       10044,  "NFS4ERR_OP_ILLEGAL"    },
+       {       10045,  "NFS4ERR_DEADLOCK"      },
+       {       10046,  "NFS4ERR_FILE_OPEN"     },
+       {       10047,  "NFS4ERR_ADMIN_REVOKED" },
+       {       10048,  "NFS4ERR_CB_PATH_DOWN"  },
        { 0, NULL }
 };
 
@@ -1646,13 +1670,13 @@ dissect_stat_internal(tvbuff_t *tvb, int offset,
        guint32 stat;
 
        stat = tvb_get_ntohl(tvb, offset+0);
-       
+
        if (tree) {
                /* this gives the right NFSv2 number<->message relation */
                /* and makes it searchable via "nfs.status" */
                proto_tree_add_uint_format(tree, hf_nfs_nfsstat3, tvb,
-                       offset+0, 4, stat, "Status: %s (%u)", 
-                       val_to_str(stat, 
+                       offset+0, 4, stat, "Status: %s (%u)",
+                       val_to_str(stat,
                                (nfsvers != 4)? names_nfs_stat: names_nfs_stat4,"%u"), stat);
        }
 
@@ -1675,11 +1699,111 @@ dissect_stat(tvbuff_t *tvb, int offset, proto_tree *tree,
 
 /* RFC 1094, Page 12..14 */
 static int
-dissect_nfs2_stat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
+dissect_nfs2_rmdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
+{
+       guint32 status;
+       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;
+       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;
+       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;
+       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;
+       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;
 }
@@ -1713,7 +1837,7 @@ dissect_ftype(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
        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);
@@ -1727,7 +1851,7 @@ dissect_ftype(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 /* RFC 1094, Page 15 */
 int
 dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
-    char *name)
+    char *name, guint32 *hash)
 {
        proto_item* fitem;
        proto_tree* ftree = NULL;
@@ -1749,7 +1873,7 @@ dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                  &&(!civ->request)
                  &&((civ->proc==4)||(civ->proc==9)||(civ->proc==14))
                ) {
-                       nfs_name_snoop_add_fh(civ->xid, tvb, 
+                       nfs_name_snoop_add_fh(civ->xid, tvb,
                                offset, 32);
                }
 
@@ -1759,12 +1883,12 @@ dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                  &&((civ->vers==1)||(civ->vers==2))
                  &&(!civ->request)
                ) {
-                       nfs_name_snoop_add_fh(civ->xid, tvb, 
+                       nfs_name_snoop_add_fh(civ->xid, tvb,
                                offset, 32);
                }
        }
 
-       dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE, FALSE);
+       dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE, FALSE, hash);
 
        offset += FHSIZE;
        return offset;
@@ -1772,9 +1896,46 @@ dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
 
 /* RFC 1094, Page 15 */
 static int
-dissect_nfs2_fhandle_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+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)
 {
-       offset = dissect_fhandle(tvb, offset, pinfo, tree, "object");
+       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;
 }
@@ -1833,7 +1994,7 @@ dissect_mode(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        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);
@@ -1877,7 +2038,7 @@ dissect_mode(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
 
 /* RFC 1094, Page 15 */
-static int
+int
 dissect_fattr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 {
        proto_item* fattr_item = NULL;
@@ -1995,26 +2156,32 @@ dissect_filename(tvbuff_t *tvb, int offset,
 
 /* RFC 1094, Page 17 */
 static int
-dissect_path(tvbuff_t *tvb, int offset, proto_tree *tree, int hf)
+dissect_path(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, char **name)
 {
-       offset = dissect_rpc_string(tvb, tree, hf, offset, NULL);
+       offset = dissect_rpc_string(tvb, tree, hf, offset, name);
        return offset;
 }
 
 
 /* RFC 1094, Page 17,18 */
 static int
-dissect_attrstat(tvbuff_t *tvb, int offset, proto_tree *tree)
+dissect_attrstat(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, char *funcname)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_fattr(tvb, offset, tree, "attributes");
+                       proto_item_append_text(tree, ", %s Reply", funcname);
                break;
                default:
-                       /* do nothing */
+                       err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
+                       }
+                       proto_item_append_text(tree, ", %s Reply  Error:%s", funcname, err);
                break;
        }
 
@@ -2024,9 +2191,25 @@ dissect_attrstat(tvbuff_t *tvb, int offset, proto_tree *tree)
 
 /* RFC 1094, Page 17,18 */
 static int
-dissect_nfs2_attrstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
+dissect_nfs2_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
+{
+       offset = dissect_attrstat(tvb, offset, tree, pinfo, "WRITE");
+
+       return offset;
+}
+
+static int
+dissect_nfs2_setattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
 {
-       offset = dissect_attrstat(tvb, offset, tree);
+       offset = dissect_attrstat(tvb, offset, tree, pinfo, "SETATTR");
+
+       return offset;
+}
+
+static int
+dissect_nfs2_getattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree* tree)
+{
+       offset = dissect_attrstat(tvb, offset, tree, pinfo, "GETATTR");
 
        return offset;
 }
@@ -2034,7 +2217,7 @@ dissect_nfs2_attrstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, p
 
 /* RFC 1094, Page 18 */
 static int
-dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* name)
+dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char* label, guint32 *hash, char **name)
 {
        proto_item* diropargs_item = NULL;
        proto_tree* diropargs_tree = NULL;
@@ -2042,7 +2225,7 @@ dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tre
 
        if (tree) {
                diropargs_item = proto_tree_add_text(tree, tvb, offset, -1,
-                       "%s", name);
+                       "%s", label);
                diropargs_tree = proto_item_add_subtree(diropargs_item, ett_nfs_diropargs);
        }
 
@@ -2056,14 +2239,14 @@ dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tre
                  &&(civ->request)
                  &&((civ->proc==4)||(civ->proc==9)||(civ->proc==14))
                ) {
-                       nfs_name_snoop_add_name(civ->xid, tvb, 
+                       nfs_name_snoop_add_name(civ->xid, tvb,
                                offset+36, tvb_get_ntohl(tvb, offset+32),
                                offset, 32, NULL);
                }
        }
 
-       offset = dissect_fhandle (tvb,offset,pinfo,diropargs_tree,"dir");
-       offset = dissect_filename(tvb,offset,      diropargs_tree,hf_nfs_name,NULL);
+       offset = dissect_fhandle(tvb, offset, pinfo, diropargs_tree, "dir", hash);
+       offset = dissect_filename(tvb, offset, diropargs_tree, hf_nfs_name, name);
 
        /* now we know, that diropargs is shorter */
        if (diropargs_item) {
@@ -2076,9 +2259,52 @@ dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tre
 
 /* RFC 1094, Page 18 */
 static int
-dissect_nfs2_diropargs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_nfs2_rmdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", RMDIR Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
+
+static int
+dissect_nfs2_remove_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
 {
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where");
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", REMOVE Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
+
+static int
+dissect_nfs2_lookup_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", LOOKUP Call DH:0x%08x/%s", hash, name);
+       g_free(name);
 
        return offset;
 }
@@ -2086,18 +2312,28 @@ dissect_nfs2_diropargs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto
 
 /* RFC 1094, Page 18 */
 static int
-dissect_diropres(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_diropres(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, char *funcname)
 {
        guint32 status;
+       guint32 hash;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file");
+                       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash);
                        offset = dissect_fattr  (tvb, offset, tree, "attributes");
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+                       }
+                       proto_item_append_text(tree, ", %s Reply FH:0x%08x", funcname, hash);
                break;
                default:
-                       /* do nothing */
+                       err=val_to_str(status, names_nfs_stat, "Unknown error:%u");
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Error:%s", err);
+                       }
+                       proto_item_append_text(tree, ", %s Reply  Error:%s", funcname, err);
                break;
        }
 
@@ -2116,40 +2352,73 @@ dissect_nfsdata(tvbuff_t *tvb, int offset, proto_tree *tree, int hf)
 
 /* RFC 1094, Page 18 */
 static int
-dissect_nfs2_diropres_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_mkdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       offset = dissect_diropres(tvb, offset, pinfo, tree, "MKDIR");
+       return offset;
+}
+
+static int
+dissect_nfs2_create_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       offset = dissect_diropres(tvb, offset, pinfo, tree, "CREATE");
+       return offset;
+}
+
+static int
+dissect_nfs2_lookup_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_diropres(tvb, offset, pinfo, tree);
+       offset = dissect_diropres(tvb, offset, pinfo, tree, "LOOKUP");
        return offset;
 }
 
 
 /* RFC 1094, Page 6 */
 static int
-dissect_nfs2_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
-       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file"      );
+       guint32 hash;
+
+       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash);
        offset = dissect_sattr  (tvb, offset,        tree, "attributes");
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", SETATTR Call FH:0x%08x", hash);
        return offset;
 }
 
 
 /* RFC 1094, Page 6 */
 static int
-dissect_nfs2_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
+dissect_nfs2_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree *tree)
 {
        guint32 status;
+       char *err;
+       char *name=NULL;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_path(tvb, offset, tree, hf_nfs_readlink_data);
+                       offset = dissect_path(tvb, offset, tree, hf_nfs_readlink_data, &name);
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Path:%s", name);
+                       }
+                       proto_item_append_text(tree, ", READLINK Reply Path:%s", name);
+                       g_free(name);
                break;
                default:
-                       /* do nothing */
+                       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, ", READLINK Reply  Error:%s", err);
                break;
        }
 
@@ -2159,46 +2428,58 @@ dissect_nfs2_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1094, Page 7 */
 static int
-dissect_nfs2_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
        guint32 offset_value;
        guint32 count;
        guint32 totalcount;
+       guint32 hash;
 
-       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file"      );
+       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash);
        offset_value = tvb_get_ntohl(tvb, offset+0);
        count        = tvb_get_ntohl(tvb, offset+4);
        totalcount   = tvb_get_ntohl(tvb, offset+8);
        if (tree) {
-               proto_tree_add_uint(tree, hf_nfs_read_offset, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_read_offset, tvb,
                offset+0, 4, offset_value);
-               proto_tree_add_uint(tree, hf_nfs_read_count, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_read_count, tvb,
                offset+4, 4, count);
-               proto_tree_add_uint(tree, hf_nfs_read_totalcount, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_read_totalcount, tvb,
                offset+8, 4, totalcount);
        }
        offset += 12;
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x Offset:%d Count:%d TotalCount:%d", hash, offset_value, count, totalcount);
+       }
+       proto_item_append_text(tree, ", READ Call FH:0x%08x Offset:%d Count:%d TotalCount:%d", hash, offset_value, count, totalcount);
+
        return offset;
 }
 
 
 /* RFC 1094, Page 7 */
 static int
-dissect_nfs2_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
+dissect_nfs2_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_fattr(tvb, offset, tree, "attributes");
-                       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data); 
+                       proto_item_append_text(tree, ", READ Reply");
+                       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
                break;
                default:
-                       /* do nothing */
+                       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, ", READ Reply  Error:%s", err);
                break;
        }
 
@@ -2208,28 +2489,34 @@ dissect_nfs2_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1094, Page 8 */
 static int
-dissect_nfs2_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
        guint32 beginoffset;
        guint32 offset_value;
        guint32 totalcount;
+       guint32 hash;
 
-       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file"      );
+       offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash);
        beginoffset  = tvb_get_ntohl(tvb, offset+0);
        offset_value = tvb_get_ntohl(tvb, offset+4);
        totalcount   = tvb_get_ntohl(tvb, offset+8);
        if (tree) {
-               proto_tree_add_uint(tree, hf_nfs_write_beginoffset, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_write_beginoffset, tvb,
                offset+0, 4, beginoffset);
-               proto_tree_add_uint(tree, hf_nfs_write_offset, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_write_offset, tvb,
                offset+4, 4, offset_value);
-               proto_tree_add_uint(tree, hf_nfs_write_totalcount, tvb, 
+               proto_tree_add_uint(tree, hf_nfs_write_totalcount, tvb,
                offset+8, 4, totalcount);
        }
        offset += 12;
 
-       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data); 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x BeginOffset:%d Offset:%d TotalCount:%d", hash, beginoffset, offset_value, totalcount);
+       }
+       proto_item_append_text(tree, ", WRITE Call FH:0x%08x BeginOffset:%d Offset:%d TotalCount:%d", hash, beginoffset, offset_value, totalcount);
+
+       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
 
        return offset;
 }
@@ -2237,48 +2524,109 @@ dissect_nfs2_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 /* RFC 1094, Page 8 */
 static int
-dissect_nfs2_createargs_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_mkdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where"     );
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
        offset = dissect_sattr    (tvb, offset,        tree, "attributes");
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", MKDIR Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
+
+static int
+dissect_nfs2_create_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name);
+       offset = dissect_sattr    (tvb, offset,        tree, "attributes");
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", CREATE Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
        return offset;
 }
 
 
 /* RFC 1094, Page 9 */
 static int
-dissect_nfs2_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "from");
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "to"  );
+       guint32 from_hash;
+       char *from_name=NULL;
+       guint32 to_hash;
+       char *to_name=NULL;
 
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name);
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x/%s To DH:0x%08x/%s", from_hash, from_name, to_hash, to_name);
+       }
+       proto_item_append_text(tree, ", RENAME Call From DH:0x%08x/%s To DH:0x%08x/%s", from_hash, from_name, to_hash, to_name);
+
+       g_free(from_name);
+       g_free(to_name);
        return offset;
 }
 
 
 /* RFC 1094, Page 9 */
 static int
-dissect_nfs2_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
-       offset = dissect_fhandle  (tvb, offset, pinfo, tree, "from");
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "to"  );
+       guint32 from_hash;
+       guint32 to_hash;
+       char *to_name=NULL;
+
+       offset = dissect_fhandle(tvb, offset, pinfo, tree, "from", &from_hash);
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name);
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x To DH:0x%08x/%s", from_hash, to_hash, to_name);
+       }
+       proto_item_append_text(tree, ", LINK Call From DH:0x%08x To DH:0x%08x/%s", from_hash, to_hash, to_name);
+
+       g_free(to_name);
        return offset;
 }
 
 
 /* RFC 1094, Page 10 */
 static int
-dissect_nfs2_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
-       offset = dissect_diropargs(tvb, offset, pinfo, tree, "from"           );
-       offset = dissect_path     (tvb, offset,        tree, hf_nfs_symlink_to);
-       offset = dissect_sattr    (tvb, offset,        tree, "attributes"     );
+       guint32 from_hash;
+       char *from_name=NULL;
+       char *to_name=NULL;
+
+       offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name);
+       offset = dissect_path(tvb, offset, tree, hf_nfs_symlink_to, &to_name);
+       offset = dissect_sattr(tvb, offset, tree, "attributes");
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x/%s To %s", from_hash, from_name, to_name);
+       }
+       proto_item_append_text(tree, ", SYMLINK Call From DH:0x%08x/%s To %s", from_hash, from_name, to_name);
+       g_free(from_name);
+       g_free(to_name);
 
        return offset;
 }
@@ -2286,13 +2634,14 @@ dissect_nfs2_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 /* RFC 1094, Page 11 */
 static int
-dissect_nfs2_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
        guint32 cookie;
        guint32 count;
+       guint32 hash;
 
-       offset = dissect_fhandle (tvb, offset, pinfo, tree, "dir");
+       offset = dissect_fhandle(tvb, offset, pinfo, tree, "dir", &hash);
        cookie  = tvb_get_ntohl(tvb, offset+ 0);
        count = tvb_get_ntohl(tvb, offset+ 4);
        if (tree) {
@@ -2303,13 +2652,18 @@ dissect_nfs2_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        }
        offset += 8;
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", READDIR Call FH:0x%08x", hash);
+
        return offset;
 }
 
 
 /* RFC 1094, Page 11 */
 static int
-dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
+dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        proto_item* entry_item = NULL;
@@ -2337,7 +2691,7 @@ dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                proto_item_set_text(entry_item, "Entry: file ID %u, name %s",
                fileid, name);
        g_free(name);
-       
+
        cookie = tvb_get_ntohl(tvb, offset + 0);
        if (entry_tree)
                proto_tree_add_uint(entry_tree, hf_nfs_readdir_entry_cookie, tvb,
@@ -2354,16 +2708,19 @@ dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1094, Page 11 */
 static int
-dissect_nfs2_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs2_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
        guint32 eof_value;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_rpc_list(tvb, pinfo, tree, offset, 
+                       proto_item_append_text(tree, ", READDIR Reply");
+
+                       offset = dissect_rpc_list(tvb, pinfo, tree, offset,
                                dissect_readdir_entry);
                        eof_value = tvb_get_ntohl(tvb, offset+0);
                        if (tree)
@@ -2372,7 +2729,11 @@ dissect_nfs2_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        offset += 4;
                break;
                default:
-                       /* do nothing */
+                       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, ", READDIR Reply  Error:%s", err);
                break;
        }
 
@@ -2391,6 +2752,7 @@ dissect_nfs2_statfs_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        guint32 blocks;
        guint32 bfree;
        guint32 bavail;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
@@ -2413,9 +2775,14 @@ dissect_nfs2_statfs_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                        offset+16, 4, bavail);
                        }
                        offset += 20;
+                       proto_item_append_text(tree, ", STATFS Reply");
                break;
                default:
-                       /* do nothing */
+                       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, ", STATFS Reply  Error:%s", err);
                break;
        }
 
@@ -2429,41 +2796,64 @@ static const vsff nfs2_proc[] = {
        { 0,    "NULL",         /* OK */
        NULL,                           NULL },
        { 1,    "GETATTR",      /* OK */
-       dissect_nfs2_fhandle_call,      dissect_nfs2_attrstat_reply },
+       dissect_nfs2_getattr_call,      dissect_nfs2_getattr_reply },
        { 2,    "SETATTR",      /* OK */
-       dissect_nfs2_setattr_call,      dissect_nfs2_attrstat_reply },
+       dissect_nfs2_setattr_call,      dissect_nfs2_setattr_reply },
        { 3,    "ROOT",         /* OK */
        NULL,                           NULL },
        { 4,    "LOOKUP",       /* OK */
-       dissect_nfs2_diropargs_call,    dissect_nfs2_diropres_reply },
+       dissect_nfs2_lookup_call,       dissect_nfs2_lookup_reply },
        { 5,    "READLINK",     /* OK */
-       dissect_nfs2_fhandle_call,      dissect_nfs2_readlink_reply },
+       dissect_nfs2_readlink_call,     dissect_nfs2_readlink_reply },
        { 6,    "READ",         /* OK */
        dissect_nfs2_read_call,         dissect_nfs2_read_reply },
        { 7,    "WRITECACHE",   /* OK */
        NULL,                           NULL },
        { 8,    "WRITE",        /* OK */
-       dissect_nfs2_write_call,        dissect_nfs2_attrstat_reply },
+       dissect_nfs2_write_call,        dissect_nfs2_write_reply },
        { 9,    "CREATE",       /* OK */
-       dissect_nfs2_createargs_call,   dissect_nfs2_diropres_reply },
+       dissect_nfs2_create_call,       dissect_nfs2_create_reply },
        { 10,   "REMOVE",       /* OK */
-       dissect_nfs2_diropargs_call,    dissect_nfs2_stat_reply },
+       dissect_nfs2_remove_call,       dissect_nfs2_remove_reply },
        { 11,   "RENAME",       /* OK */
-       dissect_nfs2_rename_call,       dissect_nfs2_stat_reply },
+       dissect_nfs2_rename_call,       dissect_nfs2_rename_reply },
        { 12,   "LINK",         /* OK */
-       dissect_nfs2_link_call,         dissect_nfs2_stat_reply },
+       dissect_nfs2_link_call,         dissect_nfs2_link_reply },
        { 13,   "SYMLINK",      /* OK */
-       dissect_nfs2_symlink_call,      dissect_nfs2_stat_reply },
+       dissect_nfs2_symlink_call,      dissect_nfs2_symlink_reply },
        { 14,   "MKDIR",        /* OK */
-       dissect_nfs2_createargs_call,   dissect_nfs2_diropres_reply },
+       dissect_nfs2_mkdir_call,        dissect_nfs2_mkdir_reply },
        { 15,   "RMDIR",        /* OK */
-       dissect_nfs2_diropargs_call,    dissect_nfs2_stat_reply },
+       dissect_nfs2_rmdir_call,        dissect_nfs2_rmdir_reply },
        { 16,   "READDIR",      /* OK */
        dissect_nfs2_readdir_call,      dissect_nfs2_readdir_reply },
        { 17,   "STATFS",       /* OK */
-       dissect_nfs2_fhandle_call,      dissect_nfs2_statfs_reply },
+       dissect_nfs2_statfs_call,       dissect_nfs2_statfs_reply },
        { 0,NULL,NULL,NULL }
 };
+
+static const value_string nfsv2_proc_vals[] = {
+       { 0,    "NULL" },
+       { 1,    "GETATTR" },
+       { 2,    "SETATTR" },
+       { 3,    "ROOT" },
+       { 4,    "LOOKUP" },
+       { 5,    "READLINK" },
+       { 6,    "READ" },
+       { 7,    "WRITECACHE" },
+       { 8,    "WRITE" },
+       { 9,    "CREATE" },
+       { 10,   "REMOVE" },
+       { 11,   "RENAME" },
+       { 12,   "LINK" },
+       { 13,   "SYMLINK" },
+       { 14,   "MKDIR" },
+       { 15,   "RMDIR" },
+       { 16,   "READDIR" },
+       { 17,   "STATFS" },
+       { 0,    NULL }
+};
+
 /* end of NFS Version 2 */
 
 
@@ -2484,9 +2874,9 @@ dissect_filename3(tvbuff_t *tvb, int offset,
 
 /* RFC 1813, Page 15 */
 static int
-dissect_nfspath3(tvbuff_t *tvb, int offset, proto_tree *tree, int hf)
+dissect_nfspath3(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, char **name)
 {
-       offset = dissect_rpc_string(tvb, tree, hf, offset, NULL);
+       offset = dissect_rpc_string(tvb, tree, hf, offset, name);
        return offset;
 }
 
@@ -2531,7 +2921,7 @@ dissect_mode3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        proto_tree* mode3_tree = NULL;
 
        mode3 = tvb_get_ntohl(tvb, offset+0);
-       
+
        if (tree) {
                mode3_item = proto_tree_add_text(tree, tvb, offset, 4,
                        "%s: 0%o", name, mode3);
@@ -2615,7 +3005,7 @@ dissect_nfsstat3(tvbuff_t *tvb, int offset,
        guint32 nfsstat3;
 
        nfsstat3 = tvb_get_ntohl(tvb, offset+0);
-       
+
        if (tree) {
                proto_tree_add_uint(tree, hf_nfs_nfsstat3, tvb,
                        offset, 4, nfsstat3);
@@ -2648,7 +3038,7 @@ dissect_ftype3(tvbuff_t *tvb, int offset, proto_tree *tree,
        guint32 type;
 
        type = tvb_get_ntohl(tvb, offset+0);
-       
+
        if (tree) {
                proto_tree_add_uint(tree, hf, tvb, offset, 4, type);
        }
@@ -2671,7 +3061,7 @@ dissect_specdata3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
        specdata1 = tvb_get_ntohl(tvb, offset+0);
        specdata2 = tvb_get_ntohl(tvb, offset+4);
-       
+
        if (tree) {
                specdata3_item = proto_tree_add_text(tree, tvb, offset, 8,
                        "%s: %u,%u", name, specdata1, specdata2);
@@ -2694,8 +3084,8 @@ dissect_specdata3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
 /* RFC 1813, Page 21 */
 int
-dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo, 
-       proto_tree *tree, char *name)
+dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree, char *name, guint32 *hash)
 {
        guint fh3_len;
        guint fh3_len_full;
@@ -2707,7 +3097,7 @@ dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
        fh3_len = tvb_get_ntohl(tvb, offset+0);
        fh3_len_full = rpc_roundup(fh3_len);
        fh3_fill = fh3_len_full - fh3_len;
-       
+
        if (tree) {
                fitem = proto_tree_add_text(tree, tvb, offset, 4+fh3_len_full,
                        "%s", name);
@@ -2727,7 +3117,7 @@ dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
                ) {
                        fh_length=tvb_get_ntohl(tvb, offset);
                        fh_offset=offset+4;
-                       nfs_name_snoop_add_fh(civ->xid, tvb, 
+                       nfs_name_snoop_add_fh(civ->xid, tvb,
                                fh_offset, fh_length);
                }
 
@@ -2739,16 +3129,24 @@ dissect_nfs_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
                ) {
                        fh_length=tvb_get_ntohl(tvb, offset);
                        fh_offset=offset+4;
-                       nfs_name_snoop_add_fh(civ->xid, tvb, 
+                       nfs_name_snoop_add_fh(civ->xid, tvb,
                                fh_offset, fh_length);
                }
        }
 
        proto_tree_add_uint(ftree, hf_nfs_fh_length, tvb, offset+0, 4,
                        fh3_len);
-       dissect_fhandle_data(tvb, offset+4, pinfo, ftree, fh3_len, FALSE);
 
-       offset += 4 + fh3_len_full;
+       /* Handle WebNFS requests where filehandle may be 0 length */
+       if (fh3_len > 0)
+       {
+               dissect_fhandle_data(tvb, offset+4, pinfo, ftree, fh3_len, FALSE, hash);
+
+               offset += fh3_len_full;
+       }
+
+       offset += 4;
+
        return offset;
 }
 
@@ -2769,7 +3167,7 @@ dissect_nfstime3(tvbuff_t *tvb, int offset,
        nseconds = tvb_get_ntohl(tvb, offset+4);
        ts.secs = seconds;
        ts.nsecs = nseconds;
-       
+
        if (tree) {
                time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
                                &ts);
@@ -2789,8 +3187,8 @@ dissect_nfstime3(tvbuff_t *tvb, int offset,
 
 
 /* RFC 1813, Page 22 */
-static int
-dissect_fattr3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
+int
+dissect_nfs_fattr3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 {
        proto_item* fattr3_item = NULL;
        proto_tree* fattr3_tree = NULL;
@@ -2811,7 +3209,7 @@ dissect_fattr3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
                offset);
        offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs_fattr3_gid,
                offset);
-       offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs_fattr3_size, 
+       offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs_fattr3_size,
                offset);
        offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs_fattr3_used,
                offset);
@@ -2842,8 +3240,9 @@ static const value_string value_follows[] =
 
 
 /* RFC 1813, Page 23 */
-static int
-dissect_post_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
+int
+dissect_nfs_post_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, 
+               char* name)
 {
        proto_item* post_op_attr_item = NULL;
        proto_tree* post_op_attr_tree = NULL;
@@ -2853,25 +3252,25 @@ dissect_post_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                post_op_attr_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s", name);
-               post_op_attr_tree = proto_item_add_subtree(post_op_attr_item, 
+               post_op_attr_tree = proto_item_add_subtree(post_op_attr_item,
                        ett_nfs_post_op_attr);
        }
 
        attributes_follow = tvb_get_ntohl(tvb, offset+0);
        proto_tree_add_text(post_op_attr_tree, tvb, offset, 4,
-               "attributes_follow: %s (%u)", 
+               "attributes_follow: %s (%u)",
                val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
        offset += 4;
        switch (attributes_follow) {
                case TRUE:
-                       offset = dissect_fattr3(tvb, offset, post_op_attr_tree,
+                       offset = dissect_nfs_fattr3(tvb, offset, post_op_attr_tree,
                                        "attributes");
                break;
                case FALSE:
                        /* void */
                break;
        }
-       
+
        /* now we know, that post_op_attr_tree is shorter */
        if (post_op_attr_item) {
                proto_item_set_len(post_op_attr_item, offset - old_offset);
@@ -2892,11 +3291,11 @@ dissect_wcc_attr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                wcc_attr_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s", name);
-               wcc_attr_tree = proto_item_add_subtree(wcc_attr_item, 
+               wcc_attr_tree = proto_item_add_subtree(wcc_attr_item,
                        ett_nfs_wcc_attr);
        }
 
-       offset = dissect_rpc_uint64(tvb, wcc_attr_tree, hf_nfs_wcc_attr_size, 
+       offset = dissect_rpc_uint64(tvb, wcc_attr_tree, hf_nfs_wcc_attr_size,
                offset);
        offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_nsec);
        offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
@@ -2921,13 +3320,13 @@ dissect_pre_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                pre_op_attr_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s", name);
-               pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item, 
+               pre_op_attr_tree = proto_item_add_subtree(pre_op_attr_item,
                        ett_nfs_pre_op_attr);
        }
 
        attributes_follow = tvb_get_ntohl(tvb, offset+0);
        proto_tree_add_text(pre_op_attr_tree, tvb, offset, 4,
-               "attributes_follow: %s (%u)", 
+               "attributes_follow: %s (%u)",
                val_to_str(attributes_follow,value_follows,"Unknown"), attributes_follow);
        offset += 4;
        switch (attributes_follow) {
@@ -2939,7 +3338,7 @@ dissect_pre_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
                        /* void */
                break;
        }
-       
+
        /* now we know, that pre_op_attr_tree is shorter */
        if (pre_op_attr_item) {
                proto_item_set_len(pre_op_attr_item, offset - old_offset);
@@ -2960,12 +3359,12 @@ dissect_wcc_data(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                wcc_data_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s", name);
-               wcc_data_tree = proto_item_add_subtree(wcc_data_item, 
+               wcc_data_tree = proto_item_add_subtree(wcc_data_item,
                        ett_nfs_wcc_data);
        }
 
        offset = dissect_pre_op_attr (tvb, offset, wcc_data_tree, "before");
-       offset = dissect_post_op_attr(tvb, offset, wcc_data_tree, "after" );
+       offset = dissect_nfs_post_op_attr(tvb, offset, wcc_data_tree, "after" );
 
        /* now we know, that wcc_data is shorter */
        if (wcc_data_item) {
@@ -2978,7 +3377,7 @@ dissect_wcc_data(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
 /* RFC 1813, Page 25 */
 static int
-dissect_post_op_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_post_op_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree, char* name)
 {
        proto_item* post_op_fh3_item = NULL;
@@ -2989,25 +3388,25 @@ dissect_post_op_fh3(tvbuff_t *tvb, int offset, packet_info *pinfo,
        if (tree) {
                post_op_fh3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s", name);
-               post_op_fh3_tree = proto_item_add_subtree(post_op_fh3_item, 
+               post_op_fh3_tree = proto_item_add_subtree(post_op_fh3_item,
                        ett_nfs_post_op_fh3);
        }
 
        handle_follows = tvb_get_ntohl(tvb, offset+0);
        proto_tree_add_text(post_op_fh3_tree, tvb, offset, 4,
-               "handle_follows: %s (%u)", 
+               "handle_follows: %s (%u)",
                val_to_str(handle_follows,value_follows,"Unknown"), handle_follows);
        offset += 4;
        switch (handle_follows) {
                case TRUE:
                        offset = dissect_nfs_fh3(tvb, offset, pinfo, post_op_fh3_tree,
-                                       "handle");
+                                       "handle", NULL);
                break;
                case FALSE:
                        /* void */
                break;
        }
-       
+
        /* now we know, that post_op_fh3_tree is shorter */
        if (post_op_fh3_item) {
                proto_item_set_len(post_op_fh3_item, offset - old_offset);
@@ -3033,7 +3432,7 @@ dissect_set_mode3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_mode3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_mode3_tree = proto_item_add_subtree(set_mode3_item, 
+               set_mode3_tree = proto_item_add_subtree(set_mode3_item,
                        ett_nfs_set_mode3);
        }
 
@@ -3052,7 +3451,7 @@ dissect_set_mode3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
                        /* void */
                break;
        }
-       
+
        /* now we know, that set_mode3 is shorter */
        if (set_mode3_item) {
                proto_item_set_len(set_mode3_item, offset - old_offset);
@@ -3078,7 +3477,7 @@ dissect_set_uid3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_uid3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_uid3_tree = proto_item_add_subtree(set_uid3_item, 
+               set_uid3_tree = proto_item_add_subtree(set_uid3_item,
                        ett_nfs_set_uid3);
        }
 
@@ -3123,7 +3522,7 @@ dissect_set_gid3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_gid3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_gid3_tree = proto_item_add_subtree(set_gid3_item, 
+               set_gid3_tree = proto_item_add_subtree(set_gid3_item,
                        ett_nfs_set_gid3);
        }
 
@@ -3135,7 +3534,7 @@ dissect_set_gid3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
        switch (set_it) {
                case 1:
-                       offset = dissect_rpc_uint32(tvb, set_gid3_tree, 
+                       offset = dissect_rpc_uint32(tvb, set_gid3_tree,
                                hf_nfs_gid3, offset);
                break;
                default:
@@ -3168,7 +3567,7 @@ dissect_set_size3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_size3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_size3_tree = proto_item_add_subtree(set_size3_item, 
+               set_size3_tree = proto_item_add_subtree(set_size3_item,
                        ett_nfs_set_size3);
        }
 
@@ -3227,7 +3626,7 @@ dissect_set_atime(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_atime_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_atime_tree = proto_item_add_subtree(set_atime_item, 
+               set_atime_tree = proto_item_add_subtree(set_atime_item,
                        ett_nfs_set_atime);
        }
 
@@ -3274,7 +3673,7 @@ dissect_set_mtime(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
        if (tree) {
                set_mtime_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, set_it_name);
-               set_mtime_tree = proto_item_add_subtree(set_mtime_item, 
+               set_mtime_tree = proto_item_add_subtree(set_mtime_item,
                        ett_nfs_set_mtime);
        }
 
@@ -3337,8 +3736,8 @@ dissect_sattr3(tvbuff_t *tvb, int offset, proto_tree *tree, char* name)
 
 /* RFC 1813, Page 27 */
 static int
-dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo, 
-       proto_tree *tree, char* name)
+dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree, char* label, guint32 *hash, char **name)
 {
        proto_item* diropargs3_item = NULL;
        proto_tree* diropargs3_tree = NULL;
@@ -3348,18 +3747,18 @@ dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        if (tree) {
                diropargs3_item = proto_tree_add_text(tree, tvb, offset, -1,
-                       "%s", name);
-               diropargs3_tree = proto_item_add_subtree(diropargs3_item, 
+                       "%s", label);
+               diropargs3_tree = proto_item_add_subtree(diropargs3_item,
                        ett_nfs_diropargs3);
        }
 
        parent_offset=offset+4;
        parent_len=tvb_get_ntohl(tvb, offset);
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, diropargs3_tree, "dir");
+       offset = dissect_nfs_fh3(tvb, offset, pinfo, diropargs3_tree, "dir", hash);
        name_offset=offset+4;
        name_len=tvb_get_ntohl(tvb, offset);
-       offset = dissect_filename3(tvb, offset, diropargs3_tree, 
-               hf_nfs_name, NULL);
+       offset = dissect_filename3(tvb, offset, diropargs3_tree,
+               hf_nfs_name, name);
 
        /* are we snooping fh to filenames ?*/
        if((!pinfo->fd->flags.visited) && nfs_file_name_snooping){
@@ -3371,7 +3770,7 @@ dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo,
                  &&(civ->request)
                  &&((civ->proc==3)||(civ->proc==8)||(civ->proc==9))
                ) {
-                       nfs_name_snoop_add_name(civ->xid, tvb, 
+                       nfs_name_snoop_add_name(civ->xid, tvb,
                                name_offset, name_len,
                                parent_offset, parent_len, NULL);
                }
@@ -3386,20 +3785,63 @@ dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo,
        return offset;
 }
 
+static int
+dissect_nfs3_remove_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", REMOVE Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
 
-/* RFC 1813, Page 27 */
 static int
-dissect_nfs3_diropargs3_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_null_call(tvbuff_t *tvb _U_, int offset, packet_info *pinfo _U_,
        proto_tree *tree)
 {
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object");
+       proto_item_append_text(tree, ", NULL Call");
 
        return offset;
 }
 
+static int
+dissect_nfs3_null_reply(tvbuff_t *tvb _U_, int offset, packet_info *pinfo _U_,
+       proto_tree *tree)
+{
+       proto_item_append_text(tree, ", NULL Reply");
+
+       return offset;
+}
 
-/* RFC 1813, Page 40 */
 static int
+dissect_nfs3_rmdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", RMDIR Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
+
+
+/* RFC 1813, Page 40 */
+int
 dissect_access(tvbuff_t *tvb, int offset, proto_tree *tree,
        char* name)
 {
@@ -3408,7 +3850,7 @@ dissect_access(tvbuff_t *tvb, int offset, proto_tree *tree,
        proto_tree* access_tree = NULL;
 
        access = tvb_get_ntohl(tvb, offset+0);
-       
+
        if (tree) {
                access_item = proto_tree_add_text(tree, tvb, offset, 4,
                        "%s: 0x%02x", name, access);
@@ -3436,43 +3878,49 @@ dissect_access(tvbuff_t *tvb, int offset, proto_tree *tree,
 }
 
 
-/* NFS3 file handle dissector */
+/* RFC 1813, Page 32,33 */
 static int
-dissect_nfs3_nfs_fh3_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_getattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object");
-       return offset;
-}
+       guint32 hash;
 
+       offset = dissect_nfs_fh3(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);
 
-/* RFC 1813, Page 32,33 */
-static int
-dissect_nfs3_getattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
-       proto_tree* tree)
-{
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object");
        return offset;
 }
 
 
 /* RFC 1813, Page 32,33 */
 static int
-dissect_nfs3_getattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
+dissect_nfs3_getattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_fattr3(tvb, offset, tree, "obj_attributes");
+                       offset = dissect_nfs_fattr3(tvb, offset, tree, "obj_attributes");
+                       proto_item_append_text(tree, ", GETATTR Reply");
                break;
                default:
                        /* void */
+
+                       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, ", GETATTR Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
@@ -3493,7 +3941,7 @@ dissect_sattrguard3(tvbuff_t *tvb, int offset, proto_tree* tree, char *name)
        if (tree) {
                sattrguard3_item = proto_tree_add_text(tree, tvb, offset, -1,
                        "%s: %s", name, check_name);
-               sattrguard3_tree = proto_item_add_subtree(sattrguard3_item, 
+               sattrguard3_tree = proto_item_add_subtree(sattrguard3_item,
                        ett_nfs_sattrguard3);
        }
 
@@ -3524,12 +3972,20 @@ dissect_sattrguard3(tvbuff_t *tvb, int offset, proto_tree* tree, char *name)
 
 /* RFC 1813, Page 33..36 */
 static int
-dissect_nfs3_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_setattr_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "object");
+       guint32 hash;
+
+       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "object", &hash);
        offset = dissect_sattr3     (tvb, offset,        tree, "new_attributes");
        offset = dissect_sattrguard3(tvb, offset,        tree, "guard");
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", SETATTR Call FH:0x%08x", hash);
+
        return offset;
 }
 
@@ -3540,65 +3996,103 @@ dissect_nfs3_setattr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_wcc_data(tvb, offset, tree, "obj_wcc");
+                       proto_item_append_text(tree, ", SETATTR Reply");
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "obj_wcc");
+
+                       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, ", SETATTR Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 37..39 */
 static int
-dissect_nfs3_lookup_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_lookup_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "what");
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "what", &hash, &name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", LOOKUP Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
        return offset;
 }
 
 
 /* RFC 1813, Page 37..39 */
 static int
-dissect_nfs3_lookup_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_lookup_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
+       guint32 hash;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object");
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object", &hash);
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
+
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+                       }
+                       proto_item_append_text(tree, ", LOOKUP Reply FH:0x%08x", hash);
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
+
+                       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, ", LOOKUP Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 40..43 */
 static int
-dissect_nfs3_access_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_access_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object");
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "object", &hash);
        offset = dissect_access (tvb, offset,        tree, "access");
 
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", ACCESS Call FH:0x%08x", hash);
+
        return offset;
 }
 
@@ -3609,58 +4103,110 @@ dissect_nfs3_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
                        offset = dissect_access(tvb, offset, tree, "access");
+
+                       proto_item_append_text(tree, ", ACCESS Reply");
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
+
+                       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, ", ACCESS Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 44,45 */
 static int
+dissect_nfs3_readlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(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_nfs3_readlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
+       char *name=NULL;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "symlink_attributes");
-                       offset = dissect_nfspath3(tvb, offset, tree, 
-                               hf_nfs_readlink_data);
+                       offset = dissect_nfspath3(tvb, offset, tree,
+                               hf_nfs_readlink_data, &name);
+
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Path:%s", name);
+                       }
+                       proto_item_append_text(tree, ", READLINK Reply Path:%s", name);
+                       g_free(name);
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "symlink_attributes");
+
+                       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, ", READLINK Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 46..48 */
 static int
-dissect_nfs3_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_read_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file");
+       unsigned char *off;
+       guint32 len;
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file", &hash);
+
+       off=u64toa(tvb_get_ptr(tvb, offset, 8));
        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_offset3, offset);
+
+       len=tvb_get_ntohl(tvb, offset);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, offset);
 
+       
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x Offset:%s Len:%d", hash, off, len);
+       }
+       proto_item_append_text(tree, ", READ Call FH:0x%08x Offset:%s Len:%d", hash, off, len);
+
        return offset;
 }
 
@@ -3671,24 +4217,37 @@ dissect_nfs3_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       guint32 len;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "file_attributes");
-                       offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, 
+                       len=tvb_get_ntohl(tvb, offset);
+                       offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3,
                                offset);
-                       offset = dissect_rpc_bool(tvb, tree, hf_nfs_read_eof, 
+                       offset = dissect_rpc_bool(tvb, tree, hf_nfs_read_eof,
                                offset);
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Len:%d", len);
+                       }
+                       proto_item_append_text(tree, ", READ Reply Len:%d", len);
                        offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "file_attributes");
+
+                       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, ", READ Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
@@ -3711,7 +4270,7 @@ dissect_stable_how(tvbuff_t *tvb, int offset, proto_tree* tree, int hfindex)
        stable_how = tvb_get_ntohl(tvb,offset+0);
        if (tree) {
                proto_tree_add_uint(tree, hfindex, tvb,
-                       offset, 4, stable_how); 
+                       offset, 4, stable_how);
        }
        offset += 4;
 
@@ -3721,13 +4280,30 @@ dissect_stable_how(tvbuff_t *tvb, int offset, proto_tree* tree, int hfindex)
 
 /* RFC 1813, Page 49..54 */
 static int
-dissect_nfs3_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_write_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3   (tvb, offset, pinfo, tree, "file");
+       unsigned char *off;
+       guint32 len;
+       guint32 stable;
+       guint32 hash;
+
+       offset = dissect_nfs_fh3   (tvb, offset, pinfo, tree, "file", &hash);
+
+       off=u64toa(tvb_get_ptr(tvb, offset, 8));
        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_offset3, offset);
+
+       len=tvb_get_ntohl(tvb, offset);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, offset);
+
+       stable=tvb_get_ntohl(tvb, offset);
        offset = dissect_stable_how(tvb, offset, tree, hf_nfs_write_stable);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x Offset:%s Len:%d %s", hash, off, len, val_to_str(stable, names_stable_how, "Stable:%u"));
+       }
+       proto_item_append_text(tree, ", WRITE Call FH:0x%08x Offset:%s Len:%d %s", hash, off, len, val_to_str(stable, names_stable_how, "Stable:%u"));
+
        offset = dissect_nfsdata   (tvb, offset, tree, hf_nfs_data);
 
        return offset;
@@ -3740,22 +4316,38 @@ dissect_nfs3_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       guint32 len;
+       guint32 stable;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_wcc_data  (tvb, offset, tree, "file_wcc");
-                       offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, 
+                       len=tvb_get_ntohl(tvb, offset);
+                       offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3,
                                offset);
+                       stable=tvb_get_ntohl(tvb, offset);
                        offset = dissect_stable_how(tvb, offset, tree,
                                hf_nfs_write_committed);
                        offset = dissect_writeverf3(tvb, offset, tree);
+
+                       if (check_col(pinfo->cinfo, COL_INFO)) {
+                               col_append_fstr(pinfo->cinfo, COL_INFO," Len:%d %s", len, val_to_str(stable, names_stable_how, "Stable:%u"));
+                       }
+                       proto_item_append_text(tree, ", WRITE Reply Len:%d %s", len, val_to_str(stable, names_stable_how, "Stable:%u"));
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "file_wcc");
+
+                       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, ", WRITE Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
@@ -3774,7 +4366,7 @@ static int
 dissect_createmode3(tvbuff_t *tvb, int offset, proto_tree* tree, guint32* mode)
 {
        guint32 mode_value;
-       
+
        mode_value = tvb_get_ntohl(tvb, offset + 0);
        if (tree) {
                proto_tree_add_uint(tree, hf_nfs_createmode3, tvb,
@@ -3789,12 +4381,14 @@ dissect_createmode3(tvbuff_t *tvb, int offset, proto_tree* tree, guint32* mode)
 
 /* RFC 1813, Page 54..58 */
 static int
-dissect_nfs3_create_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_create_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 mode;
+       guint32 hash;
+       char *name=NULL;
 
-       offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "where");
+       offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "where", &hash, &name);
        offset = dissect_createmode3(tvb, offset, tree, &mode);
        switch (mode) {
                case UNCHECKED:
@@ -3805,68 +4399,164 @@ dissect_nfs3_create_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        offset = dissect_createverf3(tvb, offset, tree);
                break;
        }
-       
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s Mode:%s", hash, name, val_to_str(mode, names_createmode3, "Unknown Mode:%u"));
+       }
+       proto_item_append_text(tree, ", CREATE Call DH:0x%08x/%s Mode:%s", hash, name, val_to_str(mode, names_createmode3, "Unknown Mode:%u"));
+       g_free(name);
+
+       return offset;
+}
+
+
+/* RFC 1813, Page 54..58 */
+static int
+dissect_nfs3_create_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 status;
+       char *err;
+
+       offset = dissect_nfsstat3(tvb, offset, tree, &status);
+       switch (status) {
+               case 0:
+                       offset = dissect_post_op_fh3 (tvb, offset, pinfo, tree, "obj");
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
+                               "obj_attributes");
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", CREATE Reply");
+               break;
+               default:
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+
+                       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, ", CREATE Reply  Error:%s", err);
+               break;
+       }
+
+       return offset;
+}
+
+
+/* RFC 1813, Page 58..60 */
+static int
+dissect_nfs3_mkdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 hash;
+       char *name=NULL;
+
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name);
+       offset = dissect_sattr3    (tvb, offset, tree, "attributes");
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", DH:0x%08x/%s", hash, name);
+       }
+       proto_item_append_text(tree, ", MKDIR Call DH:0x%08x/%s", hash, name);
+       g_free(name);
+
+       return offset;
+}
+
+static int
+dissect_nfs3_mkdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 status;
+       char *err;
+
+       offset = dissect_nfsstat3(tvb, offset, tree, &status);
+       switch (status) {
+               case 0:
+                       offset = dissect_post_op_fh3 (tvb, offset, pinfo, tree, "obj");
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
+                               "obj_attributes");
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", MKDIR Reply");
+               break;
+               default:
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+
+                       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, ", MKDIR Reply  Error:%s", err);
+               break;
+       }
+
+       return offset;
+}
+
+
+/* RFC 1813, Page 61..63 */
+static int
+dissect_nfs3_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 from_hash;
+       char *from_name=NULL;
+       char *to_name=NULL;
+
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &from_hash, &from_name);
+       offset = dissect_sattr3    (tvb, offset,        tree, "symlink_attributes");
+       offset = dissect_nfspath3  (tvb, offset,        tree, hf_nfs_symlink_to, &to_name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x/%s To %s", from_hash, from_name, to_name);
+       }
+       proto_item_append_text(tree, ", SYMLINK Call From DH:0x%08x/%s To %s", from_hash, from_name, to_name);
+       g_free(from_name);
+       g_free(to_name);
+
        return offset;
 }
-
-
-/* RFC 1813, Page 54..58 */
 static int
-dissect_nfs3_create_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_symlink_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_post_op_fh3 (tvb, offset, pinfo, tree, "obj");
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
                        offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", SYMLINK Reply");
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+
+                       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);
                break;
        }
-               
-       return offset;
-}
-
-
-/* RFC 1813, Page 58..60 */
-static int
-dissect_nfs3_mkdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
-       proto_tree* tree)
-{
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where");
-       offset = dissect_sattr3    (tvb, offset, tree, "attributes");
-       
-       return offset;
-}
-
 
-/* RFC 1813, Page 61..63 */
-static int
-dissect_nfs3_symlink_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
-       proto_tree* tree)
-{
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where");
-       offset = dissect_sattr3    (tvb, offset,        tree, "symlink_attributes");
-       offset = dissect_nfspath3  (tvb, offset,        tree, hf_nfs_symlink_to);
-       
        return offset;
 }
 
 
 /* RFC 1813, Page 63..66 */
 static int
-dissect_nfs3_mknod_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_mknod_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 type;
+       guint32 hash;
+       char *name=NULL;
+       char *type_str;
 
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where");
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name);
        offset = dissect_ftype3(tvb, offset, tree, hf_nfs_ftype3, &type);
        switch (type) {
                case NF3CHR:
@@ -3882,7 +4572,43 @@ dissect_nfs3_mknod_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        /* nothing to do */
                break;
        }
-       
+
+       type_str=val_to_str(type, names_nfs_ftype3, "Unknown type:%u");
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x/%s %s", hash, name, type_str);
+       }
+       proto_item_append_text(tree, ", MKNOD Call FH:0x%08x/%s %s", hash, name, type_str);
+       g_free(name);
+
+       return offset;
+}
+static int
+dissect_nfs3_mknod_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 status;
+       char *err;
+
+       offset = dissect_nfsstat3(tvb, offset, tree, &status);
+       switch (status) {
+               case 0:
+                       offset = dissect_post_op_fh3 (tvb, offset, pinfo, tree, "obj");
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
+                               "obj_attributes");
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", MKNOD Reply");
+               break;
+               default:
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+
+                       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, ", MKNOD Reply  Error:%s", err);
+               break;
+       }
+
        return offset;
 }
 
@@ -3893,29 +4619,73 @@ dissect_nfs3_remove_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
+
+       offset = dissect_nfsstat3(tvb, offset, tree, &status);
+       switch (status) {
+               case 0:
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", REMOVE Reply");
+               break;
+               default:
+                       offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       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);
+               break;
+       }
+
+       return offset;
+}
+static int
+dissect_nfs3_rmdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+       proto_tree* tree)
+{
+       guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       proto_item_append_text(tree, ", RMDIR Reply");
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "dir_wcc");
+                       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);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 71..74 */
 static int
-dissect_nfs3_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_rename_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "from");
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "to");
-       
+       guint32 from_hash;
+       char *from_name=NULL;
+       guint32 to_hash;
+       char *to_name=NULL;
+
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "from", &from_hash, &from_name);
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "to", &to_hash, &to_name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x/%s To DH:0x%08x/%s", from_hash, from_name, to_hash, to_name);
+       }
+       proto_item_append_text(tree, ", RENAME Call From DH:0x%08x/%s To DH:0x%08x/%s", from_hash, from_name, to_hash, to_name);
+
+       g_free(from_name);
+       g_free(to_name);
        return offset;
 }
 
@@ -3926,31 +4696,49 @@ dissect_nfs3_rename_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_wcc_data(tvb, offset, tree, "fromdir_wcc");
                        offset = dissect_wcc_data(tvb, offset, tree, "todir_wcc");
+                       proto_item_append_text(tree, ", RENAME Reply");
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "fromdir_wcc");
                        offset = dissect_wcc_data(tvb, offset, tree, "todir_wcc");
+
+                       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);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 74..76 */
 static int
-dissect_nfs3_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_link_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3   (tvb, offset, pinfo, tree, "file");
-       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "link");
-       
+       guint32 from_hash;
+       guint32 to_hash;
+       char *to_name=NULL;
+
+       offset = dissect_nfs_fh3   (tvb, offset, pinfo, tree, "file", &from_hash);
+       offset = dissect_diropargs3(tvb, offset, pinfo, tree, "link", &to_hash, &to_name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", From DH:0x%08x To DH:0x%08x/%s", from_hash, to_hash, to_name);
+       }
+       proto_item_append_text(tree, ", LINK Call From DH:0x%08x To DH:0x%08x/%s", from_hash, to_hash, to_name);
+
+       g_free(to_name);
        return offset;
 }
 
@@ -3961,35 +4749,50 @@ dissect_nfs3_link_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "file_attributes");
                        offset = dissect_wcc_data(tvb, offset, tree, "linkdir_wcc");
+                       proto_item_append_text(tree, ", LINK Reply");
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "file_attributes");
                        offset = dissect_wcc_data(tvb, offset, tree, "linkdir_wcc");
+
+                       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);
                break;
        }
-               
+
        return offset;
 }
 
 
 /* RFC 1813, Page 76..80 */
 static int
-dissect_nfs3_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_readdir_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "dir");
+       guint32 hash;
+
+       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "dir", &hash);
        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_cookie3, offset);
        offset = dissect_cookieverf3(tvb, offset, tree);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, offset);
-       
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", READDIR Call FH:0x%08x", hash);
+
        return offset;
 }
 
@@ -4002,7 +4805,7 @@ dissect_entry3(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_item* entry_item = NULL;
        proto_tree* entry_tree = NULL;
        int old_offset = offset;
-       char *name;
+       char *name=NULL;
 
        if (tree) {
                entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb,
@@ -4017,9 +4820,13 @@ dissect_entry3(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                hf_nfs_readdir_entry3_name, &name);
        if (entry_item)
                proto_item_set_text(entry_item, "Entry: name %s", name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO," %s", name);
+       }
        g_free(name);
 
-       offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs_readdir_entry3_cookie, 
+       offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs_readdir_entry3_cookie,
                offset);
 
        /* now we know, that a readdir entry is shorter */
@@ -4033,19 +4840,22 @@ dissect_entry3(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1813, Page 76..80 */
 static int
-dissect_nfs3_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
        guint32 eof_value;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       proto_item_append_text(tree, ", READDIR Reply");
+
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
                        offset = dissect_cookieverf3(tvb, offset, tree);
-                       offset = dissect_rpc_list(tvb, pinfo, tree, offset, 
+                       offset = dissect_rpc_list(tvb, pinfo, tree, offset,
                                dissect_entry3);
                        eof_value = tvb_get_ntohl(tvb, offset+0);
                        if (tree)
@@ -4054,8 +4864,14 @@ dissect_nfs3_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        offset += 4;
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
+
+                       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, ", READDIR Reply  Error:%s", err);
                break;
        }
 
@@ -4065,30 +4881,37 @@ dissect_nfs3_readdir_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 /* RFC 1813, Page 80..83 */
 static int
-dissect_nfs3_readdirplus_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_readdirplus_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "dir");
+       guint32 hash;
+
+       offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "dir", &hash);
        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_cookie3, offset);
        offset = dissect_cookieverf3(tvb, offset, tree);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3_dircount,
                offset);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3_maxcount,
                offset);
-       
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", READDIRPLUS Call FH:0x%08x", hash);
+
        return offset;
 }
 
 
 /* RFC 1813, Page 80..83 */
 static int
-dissect_entryplus3(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_entryplus3(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        proto_item* entry_item = NULL;
        proto_tree* entry_tree = NULL;
        int old_offset = offset;
-       char *name;
+       char *name=NULL;
 
        if (tree) {
                entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb,
@@ -4103,12 +4926,16 @@ dissect_entryplus3(tvbuff_t *tvb, int offset, packet_info *pinfo,
                hf_nfs_readdirplus_entry_name, &name);
        if (entry_item)
                proto_item_set_text(entry_item, "Entry: name %s", name);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO," %s", name);
+       }
        g_free(name);
 
        offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs_readdirplus_entry_cookie,
                offset);
 
-       offset = dissect_post_op_attr(tvb, offset, entry_tree, 
+       offset = dissect_nfs_post_op_attr(tvb, offset, entry_tree,
                "name_attributes");
        offset = dissect_post_op_fh3(tvb, offset, pinfo, entry_tree, "name_handle");
 
@@ -4123,19 +4950,22 @@ dissect_entryplus3(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 /* RFC 1813, Page 80..83 */
 static int
-dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
        guint32 eof_value;
+       char *err;
 
        offset = dissect_stat(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       proto_item_append_text(tree, ", READDIRPLUS Reply");
+
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
                        offset = dissect_cookieverf3(tvb, offset, tree);
-                       offset = dissect_rpc_list(tvb, pinfo, tree, offset, 
+                       offset = dissect_rpc_list(tvb, pinfo, tree, offset,
                                dissect_entryplus3);
                        eof_value = tvb_get_ntohl(tvb, offset+0);
                        if (tree)
@@ -4144,8 +4974,14 @@ dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        offset += 4;
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "dir_attributes");
+
+                       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, ", READDIRPLUS Reply  Error:%s", err);
                break;
        }
 
@@ -4154,17 +4990,34 @@ dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 
 /* RFC 1813, Page 84..86 */
+static int
+dissect_nfs3_fsstat_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(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, ", FSSTAT Call DH:0x%08x", hash);
+       return offset;
+}
+
+
 static int
 dissect_nfs3_fsstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
        guint32 invarsec;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
                        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_fsstat3_resok_tbytes,
                                offset);
@@ -4183,10 +5036,18 @@ dissect_nfs3_fsstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                proto_tree_add_uint(tree, hf_nfs_fsstat_invarsec, tvb,
                                offset+0, 4, invarsec);
                        offset += 4;
+
+                       proto_item_append_text(tree, ", FSSTAT Reply");
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
+
+                       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, ", FSSTAT Reply  Error:%s", err);
                break;
        }
 
@@ -4202,6 +5063,20 @@ dissect_nfs3_fsstat_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1813, Page 86..90 */
 static int
+dissect_nfs3_fsinfo_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(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, ", FSINFO Call DH:0x%08x", hash);
+       return offset;
+}
+static int
 dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
@@ -4216,11 +5091,12 @@ dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        guint32 properties;
        proto_item*     properties_item = NULL;
        proto_tree*     properties_tree = NULL;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
                        rtmax = tvb_get_ntohl(tvb, offset+0);
                        if (tree)
@@ -4258,7 +5134,7 @@ dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                offset+0, 4, dtpref);
                        offset += 4;
 
-                       offset = dissect_rpc_uint64(tvb, tree, 
+                       offset = dissect_rpc_uint64(tvb, tree,
                                hf_nfs_fsinfo_maxfilesize, offset);
                        offset = dissect_nfstime3(tvb, offset, tree, hf_nfs_dtime, hf_nfs_dtime_sec, hf_nfs_dtime_nsec);
                        properties = tvb_get_ntohl(tvb, offset+0);
@@ -4266,8 +5142,8 @@ dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                properties_item = proto_tree_add_uint(tree,
                                hf_nfs_fsinfo_properties,
                                tvb, offset+0, 4, properties);
-                               if (properties_item) 
-                                       properties_tree = proto_item_add_subtree(properties_item, 
+                               if (properties_item)
+                                       properties_tree = proto_item_add_subtree(properties_item,
                                                ett_nfs_fsinfo_properties);
                                if (properties_tree) {
                                        proto_tree_add_text(properties_tree, tvb,
@@ -4300,10 +5176,18 @@ dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                }
                        }
                        offset += 4;
+
+                       proto_item_append_text(tree, ", FSINFO Reply");
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
+
+                       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, ", FSINFO Reply  Error:%s", err);
                break;
        }
 
@@ -4313,17 +5197,32 @@ dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1813, Page 90..92 */
 static int
+dissect_nfs3_pathconf_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree* tree)
+{
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(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, ", PATHCONF Call DH:0x%08x", hash);
+       return offset;
+}
+static int
 dissect_nfs3_pathconf_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
        guint32 linkmax;
        guint32 name_max;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
                        linkmax = tvb_get_ntohl(tvb, offset + 0);
                        if (tree)
@@ -4335,18 +5234,26 @@ dissect_nfs3_pathconf_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
                                proto_tree_add_uint(tree, hf_nfs_pathconf_name_max, tvb,
                                offset+0, 4, name_max);
                        offset += 4;
-                       offset = dissect_rpc_bool(tvb, tree, 
+                       offset = dissect_rpc_bool(tvb, tree,
                                hf_nfs_pathconf_no_trunc, offset);
-                       offset = dissect_rpc_bool(tvb, tree, 
+                       offset = dissect_rpc_bool(tvb, tree,
                                hf_nfs_pathconf_chown_restricted, offset);
-                       offset = dissect_rpc_bool(tvb, tree, 
+                       offset = dissect_rpc_bool(tvb, tree,
                                hf_nfs_pathconf_case_insensitive, offset);
-                       offset = dissect_rpc_bool(tvb, tree, 
+                       offset = dissect_rpc_bool(tvb, tree,
                                hf_nfs_pathconf_case_preserving, offset);
+
+                       proto_item_append_text(tree, ", PATHCONF Reply");
                break;
                default:
-                       offset = dissect_post_op_attr(tvb, offset, tree, 
+                       offset = dissect_nfs_post_op_attr(tvb, offset, tree,
                                "obj_attributes");
+
+                       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, ", PATHCONF Reply  Error:%s", err);
                break;
        }
 
@@ -4356,12 +5263,20 @@ dissect_nfs3_pathconf_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
 /* RFC 1813, Page 92..95 */
 static int
-dissect_nfs3_commit_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs3_commit_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
-       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file");
+       guint32 hash;
+
+       offset = dissect_nfs_fh3(tvb, offset, pinfo, tree, "file", &hash);
        offset = dissect_rpc_uint64(tvb, tree, hf_nfs_offset3, offset);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_count3, offset);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,", FH:0x%08x", hash);
+       }
+       proto_item_append_text(tree, ", COMMIT Call FH:0x%08x", hash);
+
        return offset;
 }
 
@@ -4372,18 +5287,27 @@ dissect_nfs3_commit_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree* tree)
 {
        guint32 status;
+       char *err;
 
        offset = dissect_nfsstat3(tvb, offset, tree, &status);
        switch (status) {
                case 0:
                        offset = dissect_wcc_data  (tvb, offset, tree, "file_wcc");
                        offset = dissect_writeverf3(tvb, offset, tree);
+
+                       proto_item_append_text(tree, ", COMMIT Reply");
                break;
                default:
                        offset = dissect_wcc_data(tvb, offset, tree, "file_wcc");
+
+                       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, ", COMMIT Reply  Error:%s", err);
                break;
        }
-               
+
        return offset;
 }
 
@@ -4429,11 +5353,11 @@ dissect_nfs_lock_owner4(tvbuff_t *tvb, int offset, proto_tree *tree)
 
        fitem = proto_tree_add_text(tree, tvb, offset, 4, "Owner");
 
-       if (fitem) 
+       if (fitem)
        {
                newftree = proto_item_add_subtree(fitem, ett_nfs_lock_owner4);
 
-               if (newftree) 
+               if (newftree)
                {
                        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_clientid4, offset);
                        offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs_data);
@@ -4451,18 +5375,18 @@ dissect_nfs_pathname4(tvbuff_t *tvb, int offset, proto_tree *tree)
        proto_tree *newftree = NULL;
 
        comp_count=tvb_get_ntohl(tvb, offset);
-       fitem = proto_tree_add_text(tree, tvb, offset, 4, 
+       fitem = proto_tree_add_text(tree, tvb, offset, 4,
                "pathname components (%u)", comp_count);
        offset += 4;
 
-       if (fitem) 
+       if (fitem)
        {
                newftree = proto_item_add_subtree(fitem, ett_nfs_pathname4);
 
-               if (newftree) 
+               if (newftree)
                {
                        for (i = 0; i < comp_count; i++)
-                               offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                               offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                        hf_nfs_component4, NULL);
                }
        }
@@ -4494,13 +5418,13 @@ dissect_nfs_settime4(tvbuff_t *tvb, int offset,
        guint32 set_it;
 
        set_it = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_uint(tree, hf_nfs_time_how4, tvb, offset+0, 
+       proto_tree_add_uint(tree, hf_nfs_time_how4, tvb, offset+0,
                4, set_it);
        offset += 4;
 
        if (set_it == SET_TO_CLIENT_TIME4)
                offset = dissect_nfs_nfstime4(tvb, offset, tree);
-       
+
        return offset;
 }
 
@@ -4526,16 +5450,153 @@ dissect_nfs_fsid4(tvbuff_t *tvb, int offset, proto_tree *tree, char *name)
        return offset;
 }
 
+static const value_string names_acetype4[] = {
+#define ACE4_ACCESS_ALLOWED_ACE_TYPE   0x00000000
+       {       ACE4_ACCESS_ALLOWED_ACE_TYPE, "ACE4_ACCESS_ALLOWED_ACE_TYPE"  },
+#define ACE4_ACCESS_DENIED_ACE_TYPE            0x00000001
+       {       ACE4_ACCESS_DENIED_ACE_TYPE, "ACE4_ACCESS_DENIED_ACE_TYPE" },
+#define ACE4_SYSTEM_AUDIT_ACE_TYPE             0x00000002
+       {       ACE4_SYSTEM_AUDIT_ACE_TYPE, "ACE4_SYSTEM_AUDIT_ACE_TYPE" },
+#define ACE4_SYSTEM_ALARM_ACE_TYPE             0x00000003
+       {       ACE4_SYSTEM_ALARM_ACE_TYPE, "ACE4_SYSTEM_ALARM_ACE_TYPE"        },
+       { 0, NULL }
+};
+
+/* ACE mask values */
+#define ACE4_READ_DATA                         0x00000001
+#define ACE4_LIST_DIRECTORY            0x00000001
+#define ACE4_WRITE_DATA                                0x00000002
+#define ACE4_ADD_FILE                          0x00000002
+#define ACE4_APPEND_DATA                       0x00000004
+#define ACE4_ADD_SUBDIRECTORY          0x00000004
+#define ACE4_READ_NAMED_ATTRS          0x00000008
+#define ACE4_WRITE_NAMED_ATTRS 0x00000010
+#define ACE4_EXECUTE                                   0x00000020
+#define ACE4_DELETE_CHILD                      0x00000040
+#define ACE4_READ_ATTRIBUTES           0x00000080
+#define ACE4_WRITE_ATTRIBUTES          0x00000100
+#define ACE4_DELETE                                    0x00010000
+#define ACE4_READ_ACL                          0x00020000
+#define ACE4_WRITE_ACL                         0x00040000
+#define ACE4_WRITE_OWNER                       0x00080000
+#define ACE4_SYNCHRONIZE                       0x00100000
+
+static int
+dissect_nfs_acemask4(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       guint32 acemask;
+       proto_item *acemask_item = NULL;
+       proto_tree *acemask_tree = NULL;
+
+       acemask = tvb_get_ntohl(tvb, offset);
+
+       acemask_item = proto_tree_add_text(tree, tvb, offset, 4,
+               "acemask: 0x%08x", acemask);
+
+       if (acemask_item)
+               acemask_tree = proto_item_add_subtree(acemask_item, ett_nfs_acemask4);
+
+       if (acemask_tree)
+       {
+               if (acemask & ACE4_READ_DATA)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_READ_DATA/ACE4_LIST_DIRECTORY (0x%08x)",
+                               ACE4_READ_DATA);
+
+               if (acemask & ACE4_WRITE_DATA)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_WRITE_DATA/ACE4_ADD_FILE (0x%08x)",
+                               ACE4_WRITE_DATA);
+
+               if (acemask & ACE4_APPEND_DATA)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_ADD_FILE/ACE4_ADD_SUBDIRECTORY (0x%08x)",
+                               ACE4_APPEND_DATA);
+
+               if (acemask & ACE4_READ_NAMED_ATTRS)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_READ_NAMED_ATTRS (0x%08x)",
+                               ACE4_READ_NAMED_ATTRS);
+
+               if (acemask & ACE4_WRITE_NAMED_ATTRS)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_WRITE_NAMED_ATTRS (0x%08x)",
+                               ACE4_WRITE_NAMED_ATTRS);
+
+               if (acemask & ACE4_EXECUTE)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_EXECUTE (0x%08x)",
+                               ACE4_EXECUTE);
+
+               if (acemask & ACE4_DELETE_CHILD)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_DELETE_CHILD (0x%08x)",
+                               ACE4_DELETE_CHILD);
+
+               if (acemask & ACE4_READ_ATTRIBUTES)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_READ_ATTRIBUTES (0x%08x)",
+                               ACE4_READ_ATTRIBUTES);
+
+               if (acemask & ACE4_WRITE_ATTRIBUTES)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_WRITE_ATTRIBUTES (0x%08x)",
+                               ACE4_WRITE_ATTRIBUTES);
+
+               if (acemask & ACE4_DELETE)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_DELETE (0x%08x)",
+                               ACE4_DELETE);
+
+               if (acemask & ACE4_READ_ACL)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_READ_ACL (0x%08x)",
+                               ACE4_READ_ACL);
+
+               if (acemask & ACE4_WRITE_ACL)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_WRITE_ACL (0x%08x)",
+                               ACE4_WRITE_ACL);
+
+               if (acemask & ACE4_WRITE_OWNER)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_WRITE_OWNER (0x%08x)",
+                               ACE4_WRITE_OWNER);
+
+               if (acemask & ACE4_SYNCHRONIZE)
+                       proto_tree_add_text(acemask_tree, tvb, offset, 4,
+                               "ACE4_SYNCHRONIZE (0x%08x)",
+                               ACE4_SYNCHRONIZE);
+       }
+
+       offset += 4;
+
+       return offset;
+}
+
+/* ACE flag values */
+#define ACE4_FILE_INHERIT_ACE                                  0x00000001
+#define ACE4_DIRECTORY_INHERIT_ACE                     0x00000002
+#define ACE4_NO_PROPAGATE_INHERIT_ACE          0x00000004
+#define ACE4_INHERIT_ONLY_ACE                                  0x00000008
+#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG        0x00000010
+#define ACE4_FAILED_ACCESS_ACE_FLAG                    0x00000020
+#define ACE4_IDENTIFIER_GROUP                                  0x00000040
+
+
 static int
-dissect_nfs_ace4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
+dissect_nfs_ace4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        proto_tree *tree)
 {
        proto_item* ace_item = NULL;
        proto_tree* ace_tree = NULL;
+       proto_item *aceflag_item = NULL;
+       proto_tree *aceflag_tree = NULL;
+       guint32 aceflag4;
 
        if (tree) {
-               ace_item = proto_tree_add_text(tree, tvb, offset, 4, 
-                       "Access Control Entry");
+               ace_item = proto_tree_add_text(tree, tvb, offset, 4,
+                       "ACE");
 
                if (ace_item)
                        ace_tree = proto_item_add_subtree(ace_item, ett_nfs_ace4);
@@ -4543,8 +5604,53 @@ dissect_nfs_ace4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 
        if (ace_tree) {
                offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_acetype4, offset);
-               offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_aceflag4, offset);
-               offset = dissect_rpc_uint32(tvb, ace_tree, hf_nfs_acemask4, offset);
+
+               aceflag4 = tvb_get_ntohl(tvb, offset);
+
+               aceflag_item = proto_tree_add_text(ace_tree, tvb, offset, 4,
+                       "aceflag: 0x%08x", aceflag4);
+
+               if (aceflag_item)
+               {
+                       aceflag_tree = proto_item_add_subtree(aceflag_item, ett_nfs_aceflag4);
+
+                       if (aceflag_tree)
+                       {
+                               if (aceflag4 & ACE4_FILE_INHERIT_ACE)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_FILE_INHERIT_ACE (0x%08x)", ACE4_FILE_INHERIT_ACE);
+
+                               if (aceflag4 & ACE4_DIRECTORY_INHERIT_ACE)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_DIRECTORY_INHERIT_ACE (0x%08x)",
+                                                ACE4_DIRECTORY_INHERIT_ACE);
+
+                               if (aceflag4 & ACE4_INHERIT_ONLY_ACE)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_INHERIT_ONLY_ACE (0x%08x)",
+                                               ACE4_INHERIT_ONLY_ACE);
+
+                               if (aceflag4 & ACE4_SUCCESSFUL_ACCESS_ACE_FLAG)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_SUCCESSFUL_ACCESS_ACE_FLAG (0x%08x)",
+                                               ACE4_SUCCESSFUL_ACCESS_ACE_FLAG);
+
+                               if (aceflag4 & ACE4_FAILED_ACCESS_ACE_FLAG)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_FAILED_ACCESS_ACE_FLAG (0x%08x)",
+                                               ACE4_FAILED_ACCESS_ACE_FLAG);
+
+                               if (aceflag4 & ACE4_IDENTIFIER_GROUP)
+                                       proto_tree_add_text(aceflag_tree, tvb, offset, 4,
+                                               "ACE4_IDENTIFIER_GROUP (0x%08x)",
+                                               ACE4_IDENTIFIER_GROUP);
+                       }
+               }
+
+               offset += 4;
+
+               offset = dissect_nfs_acemask4(tvb, offset, ace_tree);
+
                offset = dissect_nfs_utf8string(tvb, offset, ace_tree, hf_nfs_who, NULL);
        }
 
@@ -4563,7 +5669,7 @@ static int
 dissect_nfs_fh4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree, char *name)
 {
-       return dissect_nfs_fh3(tvb, offset, pinfo, tree, name);
+       return dissect_nfs_fh3(tvb, offset, pinfo, tree, name, NULL);
 }
 
 static int
@@ -4603,7 +5709,7 @@ dissect_nfs_fs_locations4(tvbuff_t *tvb, packet_info *pinfo, int offset,
 
        offset = dissect_nfs_pathname4(tvb, offset, newftree);
 
-       offset = dissect_rpc_list(tvb, pinfo, tree, offset, 
+       offset = dissect_rpc_list(tvb, pinfo, tree, offset,
                dissect_nfs_fs_location4);
 
        return offset;
@@ -4645,7 +5751,7 @@ dissect_nfs_fattr4_fh_expire_type(tvbuff_t *tvb, int offset, proto_tree *tree)
                expire_type_item = proto_tree_add_text(tree, tvb, offset, 4,
                        "fattr4_fh_expire_type: 0x%08x", expire_type);
                if (expire_type_item)
-                       expire_type_tree = proto_item_add_subtree(expire_type_item, 
+                       expire_type_tree = proto_item_add_subtree(expire_type_item,
                                ett_nfs_fattr4_fh_expire_type);
        }
 
@@ -4654,7 +5760,7 @@ dissect_nfs_fattr4_fh_expire_type(tvbuff_t *tvb, int offset, proto_tree *tree)
                if (expire_type == FH4_PERSISTENT)
                {
                        proto_tree_add_text(expire_type_tree, tvb, offset, 4, "%s",
-                               decode_enumerated_bitfield(expire_type, FH4_PERSISTENT, 8, 
+                               decode_enumerated_bitfield(expire_type, FH4_PERSISTENT, 8,
                                nfs4_fattr4_fh_expire_type_names, "%s"));
                }
                else
@@ -4793,6 +5899,8 @@ static const value_string names_fattr4[] = {
        {       FATTR4_TIME_MODIFY, "FATTR4_TIME_MODIFY"        },
 #define FATTR4_TIME_MODIFY_SET     54
        {       FATTR4_TIME_MODIFY_SET, "FATTR4_TIME_MODIFY_SET"        },
+#define FATTR4_MOUNTED_ON_FILEID   55
+       {       FATTR4_MOUNTED_ON_FILEID, "FATTR4_MOUNTED_ON_FILEID"    },
        {       0,      NULL    }
 };
 
@@ -4828,7 +5936,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        attr_vals_offset = offset + 4 + bitmap_len * 4;
 
-       bitmap = g_malloc(bitmap_len * sizeof(guint32));        
+       bitmap = g_malloc(bitmap_len * sizeof(guint32));
        if (bitmap == NULL) return offset;
 
        for (i = 0; i < bitmap_len; i++)
@@ -4850,8 +5958,8 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        if (bitmap[i] & sl)
                        {
                                /* switch label if attribute is recommended vs. mandatory */
-                               attr_fitem = proto_tree_add_uint(newftree, 
-                                       (fattr < FATTR4_ACL)? hf_nfs_mand_attr: hf_nfs_recc_attr, 
+                               attr_fitem = proto_tree_add_uint(newftree,
+                                       (fattr < FATTR4_ACL)? hf_nfs_mand_attr: hf_nfs_recc_attr,
                                        tvb, offset, 4, fattr);
 
                                if (attr_fitem == NULL) break;
@@ -4866,11 +5974,11 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                        switch(fattr)
                                        {
                                        case FATTR4_SUPPORTED_ATTRS:
-                                               attr_vals_offset = dissect_nfs_attributes(tvb, 
-                                                       attr_vals_offset, pinfo, attr_newftree, 
+                                               attr_vals_offset = dissect_nfs_attributes(tvb,
+                                                       attr_vals_offset, pinfo, attr_newftree,
                                                        FATTR4_BITMAP_ONLY);
                                                break;
-                                               
+
                                        case FATTR4_TYPE:
                                                attr_vals_offset = dissect_rpc_uint32(tvb,
                                                        attr_newftree, hf_nfs_ftype4, attr_vals_offset);
@@ -4882,7 +5990,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                                break;
 
                                        case FATTR4_CHANGE:
-                                               attr_vals_offset = dissect_rpc_uint64(tvb, attr_newftree, 
+                                               attr_vals_offset = dissect_rpc_uint64(tvb, attr_newftree,
                                                        hf_nfs_changeid4, attr_vals_offset);
                                                break;
 
@@ -4893,13 +6001,13 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_LINK_SUPPORT:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_link_support, 
+                                                       attr_newftree, hf_nfs_fattr4_link_support,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_SYMLINK_SUPPORT:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_symlink_support, 
+                                                       attr_newftree, hf_nfs_fattr4_symlink_support,
                                                        attr_vals_offset);
                                                break;
 
@@ -4915,34 +6023,35 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_UNIQUE_HANDLES:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_unique_handles, 
+                                                       attr_newftree, hf_nfs_fattr4_unique_handles,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_LEASE_TIME:
                                                attr_vals_offset = dissect_rpc_uint32(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_lease_time, 
+                                                       attr_newftree, hf_nfs_fattr4_lease_time,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_RDATTR_ERROR:
-                                               attr_vals_offset = dissect_nfs_nfsstat4(tvb, attr_vals_offset,
-                                                       attr_newftree, NULL);
+                                               attr_vals_offset = dissect_nfs_nfsstat4(tvb,
+                                                       attr_vals_offset, attr_newftree, NULL);
                                                break;
 
                                        case FATTR4_ACL:
-                                               attr_vals_offset = dissect_nfs_fattr4_acl(tvb, 
+                                               attr_vals_offset = dissect_nfs_fattr4_acl(tvb,
                                                        attr_vals_offset, pinfo, attr_newftree);
                                                break;
 
                                        case FATTR4_ACLSUPPORT:
                                                attr_vals_offset = dissect_rpc_uint32(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_aclsupport, offset);
+                                                       attr_newftree, hf_nfs_fattr4_aclsupport,
+                                                       attr_vals_offset);
                                                break;
 
                                        case FATTR4_ARCHIVE:
-                                               attr_vals_offset = dissect_rpc_bool(tvb, 
-                                                       attr_newftree, hf_nfs_fattr4_archive, 
+                                               attr_vals_offset = dissect_rpc_bool(tvb,
+                                                       attr_newftree, hf_nfs_fattr4_archive,
                                                        attr_vals_offset);
                                                break;
 
@@ -4953,19 +6062,19 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_CASE_INSENSITIVE:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_case_insensitive, 
+                                                       attr_newftree, hf_nfs_fattr4_case_insensitive,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_CASE_PRESERVING:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_case_preserving, 
+                                                       attr_newftree, hf_nfs_fattr4_case_preserving,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_CHOWN_RESTRICTED:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_chown_restricted, 
+                                                       attr_newftree, hf_nfs_fattr4_chown_restricted,
                                                        attr_vals_offset);
                                                break;
 
@@ -4976,7 +6085,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_FILES_AVAIL:
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_files_avail, 
+                                                       attr_newftree, hf_nfs_fattr4_files_avail,
                                                        attr_vals_offset);
                                                break;
 
@@ -4992,13 +6101,13 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_FILES_TOTAL:
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_files_total, 
+                                                       attr_newftree, hf_nfs_fattr4_files_total,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_FS_LOCATIONS:
                                                attr_vals_offset = dissect_nfs_fs_locations4(tvb, pinfo,
-                                                       attr_vals_offset, attr_newftree, 
+                                                       attr_vals_offset, attr_newftree,
                                                        "fattr4_fs_locations");
                                                break;
 
@@ -5009,13 +6118,13 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_HOMOGENEOUS:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_homogeneous, 
+                                                       attr_newftree, hf_nfs_fattr4_homogeneous,
                                                        attr_vals_offset);
                                                break;
 
                                        case FATTR4_MAXFILESIZE:
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_maxfilesize, 
+                                                       attr_newftree, hf_nfs_fattr4_maxfilesize,
                                                        attr_vals_offset);
                                                break;
 
@@ -5040,11 +6149,11 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                                break;
 
                                        case FATTR4_MIMETYPE:
-                                               attr_vals_offset = dissect_nfs_utf8string(tvb, 
-                                                       attr_vals_offset, attr_newftree, 
+                                               attr_vals_offset = dissect_nfs_utf8string(tvb,
+                                                       attr_vals_offset, attr_newftree,
                                                        hf_nfs_fattr4_mimetype, NULL);
                                                break;
-                                       
+
                                        case FATTR4_MODE:
                                                attr_vals_offset = dissect_nfs_mode4(tvb,
                                                        attr_vals_offset, attr_newftree, "fattr4_mode");
@@ -5061,15 +6170,15 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                                break;
 
                                        case FATTR4_OWNER:
-                                               attr_vals_offset = dissect_nfs_utf8string(tvb, 
-                                                       attr_vals_offset, attr_newftree, 
+                                               attr_vals_offset = dissect_nfs_utf8string(tvb,
+                                                       attr_vals_offset, attr_newftree,
                                                        hf_nfs_fattr4_owner,
                                                        NULL);
                                                break;
 
                                        case FATTR4_OWNER_GROUP:
-                                               attr_vals_offset = dissect_nfs_utf8string(tvb, 
-                                                       attr_vals_offset, attr_newftree, 
+                                               attr_vals_offset = dissect_nfs_utf8string(tvb,
+                                                       attr_vals_offset, attr_newftree,
                                                        hf_nfs_fattr4_owner_group, NULL);
                                                break;
 
@@ -5089,13 +6198,13 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                                break;
 
                                        case FATTR4_RAWDEV:
-                                               attr_vals_offset = dissect_nfs_specdata4(tvb, 
+                                               attr_vals_offset = dissect_nfs_specdata4(tvb,
                                                        attr_vals_offset, attr_newftree);
                                                break;
 
                                        case FATTR4_SPACE_AVAIL:
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_space_avail, 
+                                                       attr_newftree, hf_nfs_fattr4_space_avail,
                                                        attr_vals_offset);
                                                break;
 
@@ -5106,7 +6215,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_SPACE_TOTAL:
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
-                                                       attr_newftree, hf_nfs_fattr4_space_total, 
+                                                       attr_newftree, hf_nfs_fattr4_space_total,
                                                        attr_vals_offset);
                                                break;
 
@@ -5114,7 +6223,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                                attr_vals_offset = dissect_rpc_uint64(tvb,
                                                        attr_newftree, hf_nfs_fattr4_space_used, attr_vals_offset);
                                                break;
-                                       
+
                                        case FATTR4_SYSTEM:
                                                attr_vals_offset = dissect_rpc_bool(tvb,
                                                        attr_newftree, hf_nfs_fattr4_system, attr_vals_offset);
@@ -5132,7 +6241,7 @@ dissect_nfs_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                                        case FATTR4_TIME_ACCESS_SET:
                                        case FATTR4_TIME_MODIFY_SET:
-                                               attr_vals_offset = dissect_nfs_settime4(tvb, 
+                                               attr_vals_offset = dissect_nfs_settime4(tvb,
                                                        attr_vals_offset, attr_newftree, "settime4");
                                                break;
 
@@ -5168,7 +6277,7 @@ dissect_nfs_fattr4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        if (newftree == NULL) return offset;
 
-       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, 
+       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                FATTR4_FULL_DISSECT);
 
        offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_attrlist4);
@@ -5178,7 +6287,7 @@ dissect_nfs_fattr4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
 static const value_string names_open4_share_access[] = {
 #define OPEN4_SHARE_ACCESS_READ 0x00000001
-       { OPEN4_SHARE_ACCESS_READ, "OPEN4_SHARE_ACCESS_READ" }, 
+       { OPEN4_SHARE_ACCESS_READ, "OPEN4_SHARE_ACCESS_READ" },
 #define OPEN4_SHARE_ACCESS_WRITE 0x00000002
        { OPEN4_SHARE_ACCESS_WRITE, "OPEN4_SHARE_ACCESS_WRITE" },
 #define OPEN4_SHARE_ACCESS_BOTH 0x00000003
@@ -5193,7 +6302,7 @@ dissect_nfs_open4_share_access(tvbuff_t *tvb, int offset,
        guint share_access;
 
        share_access = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_uint(tree, hf_nfs_open4_share_access, tvb, offset, 4, 
+       proto_tree_add_uint(tree, hf_nfs_open4_share_access, tvb, offset, 4,
                share_access);
        offset += 4;
 
@@ -5239,7 +6348,7 @@ static int
 dissect_nfs_open_claim_delegate_cur4(tvbuff_t *tvb, int offset,
        proto_tree *tree)
 {
-       offset = dissect_rpc_uint64(tvb, tree, 
+       offset = dissect_rpc_uint64(tvb, tree,
                hf_nfs_stateid4_delegate_stateid, offset);
        offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs_component4, NULL);
 
@@ -5284,7 +6393,7 @@ dissect_nfs_open_claim4(tvbuff_t *tvb, int offset,
                                break;
 
                        case CLAIM_PREVIOUS:
-                               offset = dissect_rpc_uint32(tvb, newftree, 
+                               offset = dissect_rpc_uint32(tvb, newftree,
                                        hf_nfs_delegate_type, offset);
                                break;
 
@@ -5316,7 +6425,7 @@ dissect_nfs_createhow4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        mode = tvb_get_ntohl(tvb, offset);
        proto_tree_add_uint(tree, hf_nfs_createmode3, tvb, offset, 4, mode);
        offset += 4;
-       
+
        switch(mode)
        {
        case UNCHECKED:         /* UNCHECKED4 */
@@ -5327,7 +6436,7 @@ dissect_nfs_createhow4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        case EXCLUSIVE:         /* EXCLUSIVE4 */
                offset = dissect_rpc_uint64(tvb, tree, hf_nfs_verifier4, offset);
                break;
-       
+
        default:
                break;
        }
@@ -5379,19 +6488,29 @@ dissect_nfs_openflag4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 static int
 dissect_nfs_clientaddr4(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
-       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
-       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
+       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_r_netid);
+       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_r_addr);
 
        return offset;
 }
-       
+
 
 static int
-dissect_nfs_cb_client4(tvbuff_t *tvb, int offset,
-       proto_tree *tree)
+dissect_nfs_cb_client4(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
+       proto_tree *cb_location = NULL;
+       proto_item *fitem = NULL;
+
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_cb_program, offset);
-       offset = dissect_nfs_clientaddr4(tvb, offset, tree);
+
+       fitem = proto_tree_add_text(tree, tvb, offset, 0, "cb_location");
+
+       if (fitem)
+       {
+               cb_location = proto_item_add_subtree(fitem, ett_nfs_clientaddr4);
+
+               offset = dissect_nfs_clientaddr4(tvb, offset, cb_location);
+       }
 
        return offset;
 }
@@ -5435,6 +6554,7 @@ static const value_string names_nfsv4_operation[] = {
        {       NFS4_OP_LOCKT,                                          "LOCKT" },
        {       NFS4_OP_LOCKU,                                          "LOCKU" },
        {       NFS4_OP_LOOKUP,                                 "LOOKUP"        },
+       {       NFS4_OP_LOOKUPP,                                        "LOOKUPP" },
        {       NFS4_OP_NVERIFY,                                        "NVERIFY"       },
        {       NFS4_OP_OPEN,                                           "OPEN"  },
        {       NFS4_OP_OPENATTR,                                       "OPENATTR"      },
@@ -5497,7 +6617,7 @@ gint *nfsv4_operation_ett[] =
         &ett_nfs_setclientid4 ,
         &ett_nfs_setclientid_confirm4 ,
         &ett_nfs_verify4 ,
-        &ett_nfs_write4 
+        &ett_nfs_write4
 };
 
 static int
@@ -5539,11 +6659,11 @@ dissect_nfs_change_info4(tvbuff_t *tvb, int offset,
                newftree = proto_item_add_subtree(fitem, ett_nfs_change_info4);
 
                if (newftree) {
-                       offset = dissect_rpc_bool(tvb, newftree, 
+                       offset = dissect_rpc_bool(tvb, newftree,
                                hf_nfs_change_info4_atomic, offset);
-                       offset = dissect_rpc_uint64(tvb, tree, hf_nfs_changeid4_before, 
+                       offset = dissect_rpc_uint64(tvb, tree, hf_nfs_changeid4_before,
                                offset);
-                       offset = dissect_rpc_uint64(tvb, tree, hf_nfs_changeid4_after, 
+                       offset = dissect_rpc_uint64(tvb, tree, hf_nfs_changeid4_after,
                                offset);
                }
        }
@@ -5580,13 +6700,13 @@ dissect_nfs_lock4denied(tvbuff_t *tvb, int offset, proto_tree *tree)
 
 static const value_string names_open4_result_flags[] = {
 #define OPEN4_RESULT_MLOCK 0x00000001
-       { OPEN4_RESULT_MLOCK, "OPEN4_RESULT_MLOCK" }, 
+       { OPEN4_RESULT_MLOCK, "OPEN4_RESULT_MLOCK" },
 #define OPEN4_RESULT_CONFIRM 0x00000002
        { OPEN4_RESULT_CONFIRM, "OPEN4_RESULT_CONFIRM" },
        { 0, NULL }
 };
 
-static int 
+static int
 dissect_nfs_open4_rflags(tvbuff_t *tvb, int offset,
        proto_tree *tree, char *name)
 {
@@ -5603,7 +6723,7 @@ dissect_nfs_open4_rflags(tvbuff_t *tvb, int offset,
 
                if (rflags_item)
                {
-                       rflags_tree = proto_item_add_subtree(rflags_item, 
+                       rflags_tree = proto_item_add_subtree(rflags_item,
                                ett_nfs_open4_result_flags);
 
                        if (rflags_tree)
@@ -5618,7 +6738,7 @@ dissect_nfs_open4_rflags(tvbuff_t *tvb, int offset,
                        }
                }
        }
-       
+
        offset += 4;
 
        return offset;
@@ -5639,7 +6759,7 @@ dissect_nfs_stateid4(tvbuff_t *tvb, int offset,
        if (fitem) {
                newftree = proto_item_add_subtree(fitem, ett_nfs_stateid4);
                if (newftree) {
-                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4, 
+                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4,
                                offset);
 
                        bytes_left = 12;
@@ -5666,7 +6786,7 @@ dissect_nfs_stateid4(tvbuff_t *tvb, int offset,
 }
 
 static int
-dissect_nfs_open_read_delegation4(tvbuff_t *tvb, int offset, 
+dissect_nfs_open_read_delegation4(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree)
 {
        offset = dissect_nfs_stateid4(tvb, offset, tree);
@@ -5706,7 +6826,7 @@ dissect_nfs_space_limit4(tvbuff_t *tvb, int offset,
        switch(limitby)
        {
        case NFS_LIMIT_SIZE:
-               offset = dissect_rpc_uint64(tvb, tree, hf_nfs_filesize, 
+               offset = dissect_rpc_uint64(tvb, tree, hf_nfs_filesize,
                        offset);
                break;
 
@@ -5722,7 +6842,7 @@ dissect_nfs_space_limit4(tvbuff_t *tvb, int offset,
 }
 
 static int
-dissect_nfs_open_write_delegation4(tvbuff_t *tvb, int offset, 
+dissect_nfs_open_write_delegation4(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree)
 {
        offset = dissect_nfs_stateid4(tvb, offset, tree);
@@ -5752,7 +6872,7 @@ dissect_nfs_open_delegation4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_item *fitem = NULL;
 
        delegation_type = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_uint(tree, hf_nfs_open_delegation_type4, tvb, offset+0, 
+       proto_tree_add_uint(tree, hf_nfs_open_delegation_type4, tvb, offset+0,
                4, delegation_type);
        offset += 4;
 
@@ -5785,9 +6905,10 @@ dissect_nfs_open_delegation4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 static int
 dissect_nfs_rpcsec_gss_info(tvbuff_t *tvb, int offset, proto_tree *tree)
 {
-       offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_sec_oid4); 
+       offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
+            hf_nfs_sec_oid4, FALSE, 0, FALSE, NULL, NULL);
        offset = dissect_rpc_uint32(tvb, tree, hf_nfs_qop4, offset);
-       offset = dissect_rpc_uint32(tvb, tree, 
+       offset = dissect_rpc_uint32(tvb, tree,
                hf_nfs_secinfo_rpcsec_gss_info_service, offset);
 
        return offset;
@@ -5820,7 +6941,7 @@ dissect_nfs_locker4(tvbuff_t *tvb, int offset, proto_tree *tree)
 
        new_lock_owner = tvb_get_ntohl(tvb, offset);
        offset = dissect_rpc_bool(tvb, tree, hf_nfs_new_lock_owner, offset);
-       
+
        if (new_lock_owner)
                offset = dissect_nfs_open_to_lock_owner4(tvb, offset, tree);
        else
@@ -5830,7 +6951,16 @@ dissect_nfs_locker4(tvbuff_t *tvb, int offset, proto_tree *tree)
 }
 
 static int
-dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs_client_id4(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+       offset = dissect_rpc_uint64(tvb, tree, hf_nfs_verifier4, offset);
+       offset = dissect_rpc_data(tvb, tree, hf_nfs_client_id4_id, offset);
+
+       return offset;
+}
+
+static int
+dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
        guint32 ops, ops_counter;
@@ -5841,7 +6971,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        ops = tvb_get_ntohl(tvb, offset+0);
 
-       fitem = proto_tree_add_text(tree, tvb, offset, 4, 
+       fitem = proto_tree_add_text(tree, tvb, offset, 4,
                "Operations (count: %u)", ops);
        offset += 4;
 
@@ -5855,7 +6985,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        {
                opcode = tvb_get_ntohl(tvb, offset);
 
-               fitem = proto_tree_add_uint(ftree, hf_nfs_argop4, tvb, offset, 4, 
+               fitem = proto_tree_add_uint(ftree, hf_nfs_argop4, tvb, offset, 4,
                        opcode);
                offset += 4;
 
@@ -5891,16 +7021,16 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                guint create_type;
 
                                create_type = tvb_get_ntohl(tvb, offset);
-                               offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_ftype4, 
+                               offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_ftype4,
                                        offset);
 
                                switch(create_type)
                                {
                                case NF4LNK:
-                                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                                hf_nfs_linktext4, NULL);
                                        break;
-                               
+
                                case NF4BLK:
                                case NF4CHR:
                                        offset = dissect_nfs_specdata4(tvb, offset, newftree);
@@ -5930,7 +7060,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_GETATTR:
-                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, 
+                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                                FATTR4_BITMAP_ONLY);
                        break;
 
@@ -5938,7 +7068,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_LINK:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
                        break;
 
@@ -5966,7 +7096,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_LOOKUP:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
                        break;
 
@@ -5978,7 +7108,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_OPEN:
-                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4, 
+                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4,
                                offset);
                        offset = dissect_nfs_open4_share_access(tvb, offset, newftree);
                        offset = dissect_nfs_open4_share_deny(tvb, offset, newftree);
@@ -5994,13 +7124,13 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                case NFS4_OP_OPEN_CONFIRM:
                        offset = dissect_nfs_stateid4(tvb, offset, newftree);
-                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4, 
+                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4,
                                offset);
                        break;
 
                case NFS4_OP_OPEN_DOWNGRADE:
                        offset = dissect_nfs_stateid4(tvb, offset, newftree);
-                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4, 
+                       offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_seqid4,
                                offset);
                        offset = dissect_nfs_open4_share_access(tvb, offset, newftree);
                        offset = dissect_nfs_open4_share_deny(tvb, offset, newftree);
@@ -6027,11 +7157,11 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                offset);
                        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_cookieverf4,
                                offset);
-                       offset = dissect_rpc_uint32(tvb, newftree, 
+                       offset = dissect_rpc_uint32(tvb, newftree,
                                hf_nfs_count4_dircount, offset);
                        offset = dissect_rpc_uint32(tvb, newftree,
                                hf_nfs_count4_maxcount, offset);
-                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, 
+                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                                FATTR4_BITMAP_ONLY);
                        break;
 
@@ -6039,27 +7169,27 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_REMOVE:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
                        break;
 
                case NFS4_OP_RENAME:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
                        break;
 
                case NFS4_OP_RENEW:
                        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_clientid4, offset);
                        break;
-       
+
                case NFS4_OP_RESTOREFH:
                case NFS4_OP_SAVEFH:
                        break;
 
                case NFS4_OP_SECINFO:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_component4, NULL);
                        break;
 
@@ -6071,35 +7201,37 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                case NFS4_OP_SETCLIENTID:
                        {
                                proto_tree *client_tree = NULL;
+                               proto_tree *callback_tree = NULL;
 
                                fitem = proto_tree_add_text(newftree, tvb, offset, 0, "client");
-
-                               if (fitem) 
+                               if (fitem)
                                {
                                        client_tree = proto_item_add_subtree(fitem, ett_nfs_client_id4);
 
-                                       if (newftree)
-                                       {
-                                               offset = dissect_rpc_uint64(tvb, ftree, hf_nfs_clientid4, 
-                                                       offset);
-                                               offset = dissect_nfsdata(tvb, offset, client_tree, 
-                                                       hf_nfs_client_id4_id); 
-                                       }
+                                       if (client_tree)
+                                               offset = dissect_nfs_client_id4(tvb, offset, client_tree);
                                }
 
                                fitem = proto_tree_add_text(newftree, tvb, offset, 0, "callback");
-                               if (fitem) {
-                                       newftree = proto_item_add_subtree(fitem, ett_nfs_cb_client4);
-                                       if (newftree)
-                                               offset = dissect_nfs_cb_client4(tvb, offset, newftree);
+                               if (fitem)
+                               {
+                                       callback_tree = proto_item_add_subtree(fitem,
+                                               ett_nfs_cb_client4);
+
+                                       if (callback_tree)
+                                               offset = dissect_nfs_cb_client4(tvb, offset, callback_tree);
                                }
+
+                               offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_callback_ident,
+                                       offset);
                        }
                        break;
 
                case NFS4_OP_SETCLIENTID_CONFIRM:
                        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_clientid4, offset);
+                       offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4, offset);
                        break;
-               
+
                case NFS4_OP_VERIFY:
                        offset = dissect_nfs_fattr4(tvb, offset, pinfo, newftree);
                        break;
@@ -6110,7 +7242,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        offset = dissect_nfs_stable_how4(tvb, offset, newftree, "stable");
                        offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs_data);
                        break;
-               
+
                default:
                        break;
                }
@@ -6120,7 +7252,7 @@ dissect_nfs_argop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 }
 
 static int
-dissect_nfs4_compound_call(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs4_compound_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs_tag4, NULL);
@@ -6137,13 +7269,13 @@ dissect_nfs_secinfo4_res(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
        guint flavor;
        proto_item *fitem;
        proto_tree *secftree;
-                               
+
        flavor = tvb_get_ntohl(tvb, offset);
-       fitem = proto_tree_add_uint(tree, hf_nfs_secinfo_flavor, tvb, offset, 4, 
+       fitem = proto_tree_add_uint(tree, hf_nfs_secinfo_flavor, tvb, offset, 4,
                flavor);
        offset += 4;
 
-       if (fitem) 
+       if (fitem)
        {
                switch(flavor)
                {
@@ -6162,7 +7294,7 @@ dissect_nfs_secinfo4_res(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
 }
 
 static int
-dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree *tree)
 {
        guint32 ops, ops_counter;
@@ -6174,7 +7306,7 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        ops = tvb_get_ntohl(tvb, offset+0);
 
-       fitem = proto_tree_add_text(tree, tvb, offset, 4, 
+       fitem = proto_tree_add_text(tree, tvb, offset, 4,
                "Operations (count: %u)", ops);
        offset += 4;
 
@@ -6191,7 +7323,7 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                /* sanity check for bogus packets */
                if (opcode < NFS4_OP_ACCESS || opcode > NFS4_OP_WRITE)  break;
 
-               fitem = proto_tree_add_uint(ftree, hf_nfs_resop4, tvb, offset, 4, 
+               fitem = proto_tree_add_uint(ftree, hf_nfs_resop4, tvb, offset, 4,
                        opcode);
                offset += 4;
 
@@ -6205,9 +7337,9 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                offset = dissect_nfs_nfsstat4(tvb, offset, newftree, &status);
 
                /*
-                * With the exception of NFS4_OP_LOCK, NFS4_OP_LOCKT, and 
+                * With the exception of NFS4_OP_LOCK, NFS4_OP_LOCKT, and
                 * NFS4_OP_SETATTR, all other ops do *not* return data with the
-                * failed status code.
+                * failed status code. 
                 */
                if ((status != NFS4_OK) &&
                        ((opcode != NFS4_OP_LOCK) && (opcode != NFS4_OP_LOCKT) &&
@@ -6227,12 +7359,12 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_COMMIT:
-                       offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4, 
+                       offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4,
                                offset);
                        break;
 
                case NFS4_OP_CREATE:
-                       offset = dissect_nfs_change_info4(tvb, offset, newftree, 
+                       offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "change_info");
                        offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                                FATTR4_BITMAP_ONLY);
@@ -6247,7 +7379,7 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_LINK:
-                       offset = dissect_nfs_change_info4(tvb, offset, newftree, 
+                       offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "change_info");
                        break;
 
@@ -6269,11 +7401,11 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
                case NFS4_OP_OPEN:
                        offset = dissect_nfs_stateid4(tvb, offset, newftree);
-                       offset = dissect_nfs_change_info4(tvb, offset, newftree, 
+                       offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "change_info");
-                       offset = dissect_nfs_open4_rflags(tvb, offset, newftree, 
+                       offset = dissect_nfs_open4_rflags(tvb, offset, newftree,
                                "result_flags");
-                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, 
+                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                                FATTR4_BITMAP_ONLY);
                        offset = dissect_nfs_open_delegation4(tvb, offset, pinfo, newftree);
                        break;
@@ -6294,36 +7426,40 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        break;
 
                case NFS4_OP_READLINK:
-                       offset = dissect_nfs_utf8string(tvb, offset, newftree, 
+                       offset = dissect_nfs_utf8string(tvb, offset, newftree,
                                hf_nfs_linktext4, NULL);
                        break;
 
                case NFS4_OP_REMOVE:
-                       offset = dissect_nfs_change_info4(tvb, offset, newftree, 
+                       offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "change_info");
                        break;
 
                case NFS4_OP_RENAME:
-                       offset = dissect_nfs_change_info4(tvb, offset, newftree, 
+                       offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "source_cinfo");
                        offset = dissect_nfs_change_info4(tvb, offset, newftree,
                                "target_cinfo");
                        break;
 
                case NFS4_OP_SECINFO:
-                       offset = dissect_rpc_list(tvb, pinfo, tree, offset, 
-                               dissect_nfs_secinfo4_res);
+                       offset = dissect_rpc_array(tvb, pinfo, newftree, offset,
+                               dissect_nfs_secinfo4_res, hf_nfs_secinfo_arr4);
                        break;
 
                case NFS4_OP_SETATTR:
-                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree, 
+                       offset = dissect_nfs_attributes(tvb, offset, pinfo, newftree,
                                FATTR4_BITMAP_ONLY);
                        break;
 
                case NFS4_OP_SETCLIENTID:
                        if (status == NFS4_OK)
-                               offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_clientid4, 
+                       {
+                               offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_clientid4,
+                                       offset);
+                               offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4,
                                        offset);
+                       }
                        else
                        if (status == NFS4ERR_CLID_INUSE)
                                offset = dissect_nfs_clientaddr4(tvb, offset, newftree);
@@ -6332,9 +7468,9 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
                case NFS4_OP_WRITE:
                        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs_count4,
                                offset);
-                       offset = dissect_nfs_stable_how4(tvb, offset, newftree, 
+                       offset = dissect_nfs_stable_how4(tvb, offset, newftree,
                                "committed");
-                       offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4, 
+                       offset = dissect_rpc_uint64(tvb, newftree, hf_nfs_verifier4,
                                offset);
                        break;
 
@@ -6347,7 +7483,7 @@ dissect_nfs_resop4(tvbuff_t *tvb, int offset, packet_info *pinfo,
 }
 
 static int
-dissect_nfs4_compound_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+dissect_nfs4_compound_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
        proto_tree* tree)
 {
        guint32 status;
@@ -6364,7 +7500,7 @@ dissect_nfs4_compound_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
 /* NULL as function pointer means: type of arguments is "void". */
 static const vsff nfs3_proc[] = {
        { 0,    "NULL",         /* OK */
-       NULL,                           NULL },
+       dissect_nfs3_null_call,         dissect_nfs3_null_reply },
        { 1,    "GETATTR",      /* OK */
        dissect_nfs3_getattr_call,      dissect_nfs3_getattr_reply },
        { 2,    "SETATTR",      /* OK */
@@ -6374,7 +7510,7 @@ static const vsff nfs3_proc[] = {
        { 4,    "ACCESS",       /* OK */
        dissect_nfs3_access_call,       dissect_nfs3_access_reply },
        { 5,    "READLINK",     /* OK */
-       dissect_nfs3_nfs_fh3_call,      dissect_nfs3_readlink_reply },
+       dissect_nfs3_readlink_call,     dissect_nfs3_readlink_reply },
        { 6,    "READ",         /* OK */
        dissect_nfs3_read_call,         dissect_nfs3_read_reply },
        { 7,    "WRITE",        /* OK */
@@ -6382,15 +7518,15 @@ static const vsff nfs3_proc[] = {
        { 8,    "CREATE",       /* OK */
        dissect_nfs3_create_call,       dissect_nfs3_create_reply },
        { 9,    "MKDIR",        /* OK */
-       dissect_nfs3_mkdir_call,        dissect_nfs3_create_reply },
+       dissect_nfs3_mkdir_call,        dissect_nfs3_mkdir_reply },
        { 10,   "SYMLINK",      /* OK */
-       dissect_nfs3_symlink_call,      dissect_nfs3_create_reply },
+       dissect_nfs3_symlink_call,      dissect_nfs3_symlink_reply },
        { 11,   "MKNOD",        /* OK */
-       dissect_nfs3_mknod_call,        dissect_nfs3_create_reply },
+       dissect_nfs3_mknod_call,        dissect_nfs3_mknod_reply },
        { 12,   "REMOVE",       /* OK */
-       dissect_nfs3_diropargs3_call,   dissect_nfs3_remove_reply },
+       dissect_nfs3_remove_call,       dissect_nfs3_remove_reply },
        { 13,   "RMDIR",        /* OK */
-       dissect_nfs3_diropargs3_call,   dissect_nfs3_remove_reply },
+       dissect_nfs3_rmdir_call,        dissect_nfs3_rmdir_reply },
        { 14,   "RENAME",       /* OK */
        dissect_nfs3_rename_call,       dissect_nfs3_rename_reply },
        { 15,   "LINK",         /* OK */
@@ -6400,15 +7536,42 @@ static const vsff nfs3_proc[] = {
        { 17,   "READDIRPLUS",  /* OK */
        dissect_nfs3_readdirplus_call,  dissect_nfs3_readdirplus_reply },
        { 18,   "FSSTAT",       /* OK */
-       dissect_nfs3_nfs_fh3_call,      dissect_nfs3_fsstat_reply },
+       dissect_nfs3_fsstat_call,       dissect_nfs3_fsstat_reply },
        { 19,   "FSINFO",       /* OK */
-       dissect_nfs3_nfs_fh3_call,      dissect_nfs3_fsinfo_reply },
+       dissect_nfs3_fsinfo_call,       dissect_nfs3_fsinfo_reply },
        { 20,   "PATHCONF",     /* OK */
-       dissect_nfs3_nfs_fh3_call,      dissect_nfs3_pathconf_reply },
+       dissect_nfs3_pathconf_call,     dissect_nfs3_pathconf_reply },
        { 21,   "COMMIT",       /* OK */
        dissect_nfs3_commit_call,       dissect_nfs3_commit_reply },
        { 0,NULL,NULL,NULL }
 };
+
+static const value_string nfsv3_proc_vals[] = {
+       { 0,    "NULL" },
+       { 1,    "GETATTR" },
+       { 2,    "SETATTR" },
+       { 3,    "LOOKUP" },
+       { 4,    "ACCESS" },
+       { 5,    "READLINK" },
+       { 6,    "READ" },
+       { 7,    "WRITE" },
+       { 8,    "CREATE" },
+       { 9,    "MKDIR" },
+       { 10,   "SYMLINK" },
+       { 11,   "MKNOD" },
+       { 12,   "REMOVE" },
+       { 13,   "RMDIR" },
+       { 14,   "RENAME" },
+       { 15,   "LINK" },
+       { 16,   "READDIR" },
+       { 17,   "READDIRPLUS" },
+       { 18,   "FSSTAT" },
+       { 19,   "FSINFO" },
+       { 20,   "PATHCONF" },
+       { 21,   "COMMIT" },
+       { 0,    NULL }
+};
+
 /* end of NFS Version 3 */
 
 static const vsff nfs4_proc[] = {
@@ -6419,6 +7582,11 @@ static const vsff nfs4_proc[] = {
        { 0, NULL, NULL, NULL }
 };
 
+static const value_string nfsv4_proc_vals[] = {
+       { 0, "NULL" },
+       { 1, "COMPOUND" },
+       { 0, NULL }
+};
 
 static struct true_false_string yesno = { "Yes", "No" };
 
@@ -6427,6 +7595,15 @@ void
 proto_register_nfs(void)
 {
        static hf_register_info hf[] = {
+               { &hf_nfs_procedure_v2, {
+                       "V2 Procedure", "nfs.procedure_v2", FT_UINT32, BASE_DEC,
+                       VALS(nfsv2_proc_vals), 0, "V2 Procedure", HFILL }},
+               { &hf_nfs_procedure_v3, {
+                       "V3 Procedure", "nfs.procedure_v3", FT_UINT32, BASE_DEC,
+                       VALS(nfsv3_proc_vals), 0, "V3 Procedure", HFILL }},
+               { &hf_nfs_procedure_v4, {
+                       "V4 Procedure", "nfs.procedure_v4", FT_UINT32, BASE_DEC,
+                       VALS(nfsv4_proc_vals), 0, "V4 Procedure", HFILL }},
                { &hf_nfs_fh_length, {
                        "length", "nfs.fh.length", FT_UINT32, BASE_DEC,
                        NULL, 0, "file handle length", HFILL }},
@@ -6665,13 +7842,13 @@ proto_register_nfs(void)
                        "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE,
                        &yesno, 0, "No long file name truncation", HFILL }},
                { &hf_nfs_pathconf_chown_restricted, {
-                       "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, 
+                       "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "chown is restricted to root", HFILL }},
                { &hf_nfs_pathconf_case_insensitive, {
-                       "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, 
+                       "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "file names are treated case insensitive", HFILL }},
                { &hf_nfs_pathconf_case_preserving, {
-                       "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, 
+                       "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "file name cases are preserved", HFILL }},
 
                { &hf_nfs_fattr_type, {
@@ -6901,11 +8078,11 @@ proto_register_nfs(void)
                        NULL, 0, "attr_vals", HFILL }},
 
                { &hf_nfs_fattr4_link_support, {
-                       "fattr4_link_support", "nfs.fattr4_link_support", FT_BOOLEAN, 
+                       "fattr4_link_support", "nfs.fattr4_link_support", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_link_support", HFILL }},
 
                { &hf_nfs_fattr4_symlink_support, {
-                       "fattr4_symlink_support", "nfs.fattr4_symlink_support", FT_BOOLEAN, 
+                       "fattr4_symlink_support", "nfs.fattr4_symlink_support", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_symlink_support", HFILL }},
 
                { &hf_nfs_fattr4_named_attr, {
@@ -6913,35 +8090,35 @@ proto_register_nfs(void)
                        &yesno, 0, "nfs.fattr4_named_attr", HFILL }},
 
                { &hf_nfs_fattr4_unique_handles, {
-                       "fattr4_unique_handles", "nfs.fattr4_unique_handles", FT_BOOLEAN, 
+                       "fattr4_unique_handles", "nfs.fattr4_unique_handles", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_unique_handles", HFILL }},
 
                { &hf_nfs_fattr4_archive, {
-                       "fattr4_archive", "nfs.fattr4_archive", FT_BOOLEAN, 
+                       "fattr4_archive", "nfs.fattr4_archive", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_archive", HFILL }},
 
                { &hf_nfs_fattr4_cansettime, {
-                       "fattr4_cansettime", "nfs.fattr4_cansettime", FT_BOOLEAN, 
+                       "fattr4_cansettime", "nfs.fattr4_cansettime", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_cansettime", HFILL }},
 
                { &hf_nfs_fattr4_case_insensitive, {
-                       "fattr4_case_insensitive", "nfs.fattr4_case_insensitive", FT_BOOLEAN, 
+                       "fattr4_case_insensitive", "nfs.fattr4_case_insensitive", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_case_insensitive", HFILL }},
 
                { &hf_nfs_fattr4_case_preserving, {
-                       "fattr4_case_preserving", "nfs.fattr4_case_preserving", FT_BOOLEAN, 
+                       "fattr4_case_preserving", "nfs.fattr4_case_preserving", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_case_preserving", HFILL }},
 
                { &hf_nfs_fattr4_chown_restricted, {
-                       "fattr4_chown_restricted", "nfs.fattr4_chown_restricted", FT_BOOLEAN, 
+                       "fattr4_chown_restricted", "nfs.fattr4_chown_restricted", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_chown_restricted", HFILL }},
 
                { &hf_nfs_fattr4_hidden, {
-                       "fattr4_hidden", "nfs.fattr4_hidden", FT_BOOLEAN, 
+                       "fattr4_hidden", "nfs.fattr4_hidden", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_hidden", HFILL }},
 
                { &hf_nfs_fattr4_homogeneous, {
-                       "fattr4_homogeneous", "nfs.fattr4_homogeneous", FT_BOOLEAN, 
+                       "fattr4_homogeneous", "nfs.fattr4_homogeneous", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_homogeneous", HFILL }},
 
                { &hf_nfs_fattr4_mimetype, {
@@ -6949,11 +8126,11 @@ proto_register_nfs(void)
                        NULL, 0, "nfs.fattr4_mimetype", HFILL }},
 
                { &hf_nfs_fattr4_no_trunc, {
-                       "fattr4_no_trunc", "nfs.fattr4_no_trunc", FT_BOOLEAN, 
+                       "fattr4_no_trunc", "nfs.fattr4_no_trunc", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_no_trunc", HFILL }},
 
                { &hf_nfs_fattr4_system, {
-                       "fattr4_system", "nfs.fattr4_system", FT_BOOLEAN, 
+                       "fattr4_system", "nfs.fattr4_system", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.fattr4_system", HFILL }},
 
                { &hf_nfs_who, {
@@ -7001,7 +8178,7 @@ proto_register_nfs(void)
                        VALS(names_nfs_lock_type4), 0, "nfs.locktype4", HFILL }},
 
                { &hf_nfs_reclaim4, {
-                       "reclaim", "nfs.reclaim4", FT_BOOLEAN, 
+                       "reclaim", "nfs.reclaim4", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "Reclaim", HFILL }},
 
                { &hf_nfs_length4, {
@@ -7038,7 +8215,7 @@ proto_register_nfs(void)
 
                { &hf_nfs_acetype4, {
                        "acetype", "nfs.acetype4", FT_UINT32, BASE_DEC,
-                       NULL, 0, "nfs.acetype4", HFILL }},
+                       VALS(names_acetype4), 0, "nfs.acetype4", HFILL }},
 
                { &hf_nfs_aceflag4, {
                        "aceflag", "nfs.aceflag4", FT_UINT32, BASE_DEC,
@@ -7153,7 +8330,7 @@ proto_register_nfs(void)
                        NULL, 0, "nfs.delegate_stateid", HFILL }},
 
                { &hf_nfs_verifier4, {
-                       "verifier", "nfs.verifier4", FT_UINT64, BASE_DEC,
+                       "verifier", "nfs.verifier4", FT_UINT64, BASE_HEX,
                        NULL, 0, "nfs.verifier4", HFILL }},
 
                { &hf_nfs_cookie4, {
@@ -7169,11 +8346,11 @@ proto_register_nfs(void)
                        NULL, 0, "nfs.cb_location", HFILL }},
 
                { &hf_nfs_cb_program, {
-                       "cb_program", "nfs.cb_program", FT_UINT32, BASE_DEC,
+                       "cb_program", "nfs.cb_program", FT_UINT32, BASE_HEX,
                        NULL, 0, "nfs.cb_program", HFILL }},
 
                { &hf_nfs_recall4, {
-                       "recall", "nfs.recall4", FT_BOOLEAN, 
+                       "recall", "nfs.recall4", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.recall4", HFILL }},
 
                { &hf_nfs_filesize, {
@@ -7269,15 +8446,15 @@ proto_register_nfs(void)
                        BASE_DEC, VALS(rpc_authgss_svc), 0, "service", HFILL }},
 
                { &hf_nfs_attrdircreate, {
-                       "attribute dir create", "nfs.openattr4.createdir", FT_BOOLEAN, 
+                       "attribute dir create", "nfs.openattr4.createdir", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.openattr4.createdir", HFILL }},
 
                { &hf_nfs_new_lock_owner, {
-                       "new lock owner?", "nfs.lock.locker.new_lock_owner", FT_BOOLEAN, 
+                       "new lock owner?", "nfs.lock.locker.new_lock_owner", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.lock.locker.new_lock_owner", HFILL }},
 
                { &hf_nfs_lock4_reclaim, {
-                       "reclaim?", "nfs.lock.reclaim", FT_BOOLEAN, 
+                       "reclaim?", "nfs.lock.reclaim", FT_BOOLEAN,
                        BASE_NONE, &yesno, 0, "nfs.lock.reclaim", HFILL }},
 
                { &hf_nfs_sec_oid4, {
@@ -7285,20 +8462,36 @@ proto_register_nfs(void)
                        BASE_DEC, NULL, 0, "oid", HFILL }},
 
                { &hf_nfs_qop4, {
-                       "qop", "nfs.secinfo.flavor_info.rpcsec_gss_info.qop", FT_UINT32, 
+                       "qop", "nfs.secinfo.flavor_info.rpcsec_gss_info.qop", FT_UINT32,
                        BASE_DEC, NULL, 0, "qop", HFILL }},
 
                { &hf_nfs_client_id4_id, {
-                       "Data", "nfs.nfs_client_id4.id", FT_BYTES, BASE_DEC,
-                       NULL, 0, "Data", HFILL }},
+                       "id", "nfs.nfs_client_id4.id", FT_BYTES, BASE_DEC,
+                       NULL, 0, "nfs.nfs_client_id4.id", HFILL }},
 
                { &hf_nfs_stateid4_other, {
                        "Data", "nfs.stateid4.other", FT_BYTES, BASE_DEC,
                        NULL, 0, "Data", HFILL }},
 
                { &hf_nfs_acl4, {
-                       "Access Control List", "nfs.acl", FT_NONE, BASE_NONE,
+                       "ACL", "nfs.acl", FT_NONE, BASE_NONE,
                        NULL, 0, "Access Control List", HFILL }},
+
+               { &hf_nfs_callback_ident, {
+                       "callback_ident", "nfs.callback.ident", FT_UINT32, BASE_HEX,
+                       NULL, 0, "Callback Identifier", HFILL }},
+
+               { &hf_nfs_r_netid, {
+                       "r_netid", "nfs.r_netid", FT_BYTES, BASE_DEC, NULL, 0,
+                       "r_netid", HFILL }},
+
+               { &hf_nfs_r_addr, {
+                       "r_addr", "nfs.r_addr", FT_BYTES, BASE_DEC, NULL, 0,
+                       "r_addr", HFILL }},
+
+               { &hf_nfs_secinfo_arr4, {
+                       "Flavors Info", "nfs.flavors.info", FT_NONE, BASE_NONE,
+                       NULL, 0, "Flavors Info", HFILL }},
        };
 
        static gint *ett[] = {
@@ -7398,7 +8591,10 @@ proto_register_nfs(void)
                &ett_nfs_secinfo4_flavor_info,
                &ett_nfs_stateid4,
                &ett_nfs_fattr4_fh_expire_type,
-               &ett_nfs_ace4
+               &ett_nfs_ace4,
+               &ett_nfs_clientaddr4,
+               &ett_nfs_aceflag4,
+               &ett_nfs_acemask4,
        };
        module_t *nfs_module;
 
@@ -7429,7 +8625,7 @@ proto_reg_handoff_nfs(void)
        /* Register the protocol as RPC */
        rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs);
        /* Register the procedure tables */
-       rpc_init_proc_table(NFS_PROGRAM, 2, nfs2_proc);
-       rpc_init_proc_table(NFS_PROGRAM, 3, nfs3_proc);
-       rpc_init_proc_table(NFS_PROGRAM, 4, nfs4_proc);
+       rpc_init_proc_table(NFS_PROGRAM, 2, nfs2_proc, hf_nfs_procedure_v2);
+       rpc_init_proc_table(NFS_PROGRAM, 3, nfs3_proc, hf_nfs_procedure_v3);
+       rpc_init_proc_table(NFS_PROGRAM, 4, nfs4_proc, hf_nfs_procedure_v4);
 }