aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-nfs.c240
-rw-r--r--epan/dissectors/packet-nfs.h2
2 files changed, 93 insertions, 149 deletions
diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c
index ee073f265d..89d0b23bb5 100644
--- a/epan/dissectors/packet-nfs.c
+++ b/epan/dissectors/packet-nfs.c
@@ -37,6 +37,7 @@
#include "packet-rpc.h"
#include "packet-nfs.h"
#include <epan/prefs.h>
+#include <epan/packet.h>
#include <epan/emem.h>
static int proto_nfs = -1;
@@ -46,6 +47,7 @@ static int hf_nfs_procedure_v3 = -1;
static int hf_nfs_procedure_v4 = -1;
static int hf_nfs_fh_length = -1;
static int hf_nfs_fh_hash = -1;
+static int hf_nfs_fh_fhandle_data = -1;
static int hf_nfs_fh_mount_fileid = -1;
static int hf_nfs_fh_mount_generation = -1;
static int hf_nfs_fh_snapid = -1;
@@ -410,6 +412,27 @@ static gint ett_nfs_clientaddr4 = -1;
static gint ett_nfs_aceflag4 = -1;
static gint ett_nfs_acemask4 = -1;
+/* what type of fhandles shoudl we dissect as */
+static dissector_table_t nfs_fhandle_table;
+
+
+#define FHT_UNKNOWN 0
+#define FHT_SVR4 1
+#define FHT_LINUX_KNFSD_LE 2
+#define FHT_LINUX_NFSD_LE 3
+#define FHT_LINUX_KNFSD_NEW 4
+#define FHT_NETAPP 5
+static enum_val_t nfs_fhandle_types[] = {
+ { "unknown", "Unknown", FHT_UNKNOWN },
+ { "svr4", "SVR4", FHT_SVR4 },
+ { "knfsd_le", "KNFSD_LE", FHT_LINUX_KNFSD_LE },
+ { "nfsd_le", "NFSD_LE", FHT_LINUX_NFSD_LE },
+ { "knfsd_new", "KNFSD_NEW", FHT_LINUX_KNFSD_NEW },
+ { "netapp", "NetApp", FHT_NETAPP },
+ { NULL, NULL, 0 }
+};
+/* decode all nfs filehandles as this type */
+gint default_nfs_fhandle_type=FHT_UNKNOWN;
/* For dissector helpers which take a "levels" argument to indicate how
* many expansions up they should populate the expansion items with
@@ -476,7 +499,7 @@ store_nfs_file_handle(nfs_fhandle_data_t *nfs_fh)
fhkey[0].length=1;
fhkey[0].key=&fhlen;
fhkey[1].length=fhlen;
- fhkey[1].key=nfs_fh->fh;
+ fhkey[1].key=(guint32 *)nfs_fh->fh;
fhkey[2].length=0;
new_nfs_fh=se_tree_lookup32_array(nfs_file_handles, &fhkey[0]);
@@ -493,7 +516,7 @@ store_nfs_file_handle(nfs_fhandle_data_t *nfs_fh)
fhkey[0].length=1;
fhkey[0].key=&fhlen;
fhkey[1].length=fhlen;
- fhkey[1].key=nfs_fh->fh;
+ fhkey[1].key=(guint32 *)nfs_fh->fh;
fhkey[2].length=0;
se_tree_insert32_array(nfs_file_handles, &fhkey[0], new_nfs_fh);
@@ -755,7 +778,7 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
fhkey[0].length=1;
fhkey[0].key=&fhlen;
fhkey[1].length=fhlen/4;
- fhkey[1].key=nns->fh;
+ fhkey[1].key=(guint32 *)nns->fh;
fhkey[2].length=0;
se_tree_insert32_array(nfs_name_snoop_known, &fhkey[0], nns);
@@ -781,7 +804,7 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
fhkey[0].length=1;
fhkey[0].key=&fhlen;
fhkey[1].length=fhlen/4;
- fhkey[1].key=tvb_get_ptr(tvb, fh_offset, fh_length);
+ fhkey[1].key=(guint32 *)tvb_get_ptr(tvb, fh_offset, fh_length);
fhkey[2].length=0;
nns=se_tree_lookup32_array(nfs_name_snoop_known, &fhkey[0]);
@@ -815,13 +838,6 @@ nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_of
/* file handle dissection */
-#define FHT_UNKNOWN 0
-#define FHT_SVR4 1
-#define FHT_LINUX_KNFSD_LE 2
-#define FHT_LINUX_NFSD_LE 3
-#define FHT_LINUX_KNFSD_NEW 4
-#define FHT_NETAPP 5
-
static const value_string names_fhtype[] =
{
{ FHT_UNKNOWN, "unknown" },
@@ -837,10 +853,9 @@ static const value_string names_fhtype[] =
/* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45) */
static void
-dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
- int fhlen _U_)
+dissect_fhandle_data_SVR4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- guint32 nof = offset;
+ guint32 nof=0;
/* file system id */
{
@@ -988,9 +1003,9 @@ dissect_fhandle_data_SVR4(tvbuff_t* tvb, int offset, proto_tree *tree,
/* Checked with RedHat Linux 6.2 (kernel 2.2.14 knfsd) */
static void
-dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
- int fhlen _U_)
+dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
{
+ int offset=0;
guint32 dentry;
guint32 inode;
guint32 dirinode;
@@ -1069,9 +1084,10 @@ dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
/* Checked with RedHat Linux 5.2 (nfs-server 2.2beta47 user-land nfsd) */
static void
-dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, int offset, proto_tree *tree,
- int fhlen _U_)
+dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
{
+ int offset=0;
+
/* pseudo inode */
{
guint32 pinode;
@@ -1139,9 +1155,10 @@ static const value_string fileid_type_names[] = {
};
static void
-dissect_fhandle_data_NETAPP(tvbuff_t* tvb, int offset, proto_tree *tree,
- int fhlen _U_)
+dissect_fhandle_data_NETAPP(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
{
+ int offset=0;
+
if (tree) {
guint32 mount = tvb_get_letohl(tvb, offset + 0);
guint32 mount_gen = tvb_get_letohl(tvb, offset + 4);
@@ -1203,9 +1220,9 @@ dissect_fhandle_data_NETAPP(tvbuff_t* tvb, int offset, proto_tree *tree,
}
static void
-dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, int offset, proto_tree *tree,
- int fhlen _U_)
+dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree)
{
+ int offset=0;
guint8 version;
guint8 auth_type;
guint8 fsid_type;
@@ -1374,28 +1391,11 @@ out:
static void
-dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree,
- guint fhlen)
+dissect_fhandle_data_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
- guint sublen;
- guint bytes_left;
- gboolean first_line;
+ guint fhlen=tvb_length(tvb);
- bytes_left = fhlen;
- first_line = TRUE;
- while (bytes_left != 0) {
- sublen = 16;
- if (sublen > bytes_left)
- sublen = bytes_left;
- proto_tree_add_text(tree, tvb, offset, sublen,
- "%s%s",
- first_line ? "data: " :
- " ",
- tvb_bytes_to_str(tvb,offset,sublen));
- bytes_left -= sublen;
- offset += sublen;
- first_line = FALSE;
- }
+ proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, -1, FALSE);
}
@@ -1403,14 +1403,6 @@ static void
dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, unsigned int fhlen, gboolean hidden, guint32 *hash)
{
- unsigned int fhtype = FHT_UNKNOWN;
-
- /* filehandle too long */
- if (fhlen>64) goto type_ready;
- /* Not all bytes there. Any attempt to deduce the type would be
- senseless. */
- if (!tvb_bytes_exist(tvb,offset,fhlen)) goto type_ready;
-
/* this is to set up fhandle display filters to find both packets
of an RPC call */
if(nfs_fhandle_reqrep_matching && (!hidden) ){
@@ -1464,109 +1456,20 @@ dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
if(!hidden){
- /* calculate (heuristically) fhtype */
- switch (fhlen) {
- case 12:
- if (tvb_get_ntohl(tvb,offset) == 0x01000000) {
- fhtype=FHT_LINUX_KNFSD_NEW;
- }
- break;
- case 20:
- if (tvb_get_ntohl(tvb,offset) == 0x01000001) {
- fhtype=FHT_LINUX_KNFSD_NEW;
- }
- break;
- case 24:
- if (tvb_get_ntohl(tvb,offset) == 0x01000002) {
- fhtype=FHT_LINUX_KNFSD_NEW;
- }
- break;
- case 32: {
- guint32 len1;
- guint32 len2;
- if (tvb_get_ntohs(tvb,offset+4) == 0) {
- len1=tvb_get_ntohs(tvb,offset+8);
- if (tvb_bytes_exist(tvb,offset+10+len1,2)) {
- len2=tvb_get_ntohs(tvb,
- offset+10+len1);
- if (fhlen==12+len1+len2) {
- fhtype=FHT_SVR4;
- goto type_ready;
- }
- }
- }
- /* For a NetApp filehandle, the flag bits must
- include WAFL_FH_MULTIVOLUME, and the fileid
- and generation number need to be nonzero in
- the mount point, file, and export. */
- if ((tvb_get_ntohl(tvb,offset+8) & 0x20000000)
- && tvb_get_ntohl(tvb,offset+0)
- && tvb_get_ntohl(tvb,offset+4)
- && tvb_get_ntohl(tvb,offset+12)
- && tvb_get_ntohl(tvb,offset+16)
- && tvb_get_ntohl(tvb,offset+24)
- && tvb_get_ntohl(tvb,offset+28)) {
- fhtype=FHT_NETAPP;
- goto type_ready;
- }
- len1 = tvb_get_guint8(tvb,offset+4);
- if (len1<28 && tvb_bytes_exist(tvb,offset+5,len1)) {
- int wrong=0;
- for (len2=5+len1;len2<32;len2++) {
- if (tvb_get_guint8(tvb,offset+len2)) {
- wrong=1;
- break;
- }
- }
- if (!wrong) {
- fhtype=FHT_LINUX_NFSD_LE;
- goto type_ready;
- }
- }
- if (tvb_get_ntohl(tvb,offset+28) == 0) {
- if (tvb_get_ntohs(tvb,offset+14) == 0) {
- if (tvb_get_ntohs(tvb,offset+18) == 0) {
- fhtype=FHT_LINUX_KNFSD_LE;
- goto type_ready;
- }
- }
- }
- } break;
- }
- }
+ tvbuff_t *fh_tvb;
+ int real_length;
-type_ready:
-
- if(!hidden){
proto_tree_add_text(tree, tvb, offset, 0,
- "type: %s", val_to_str(fhtype, names_fhtype, "Unknown"));
+ "decode type as: %s", val_to_str(default_nfs_fhandle_type, names_fhtype, "Unknown"));
- switch (fhtype) {
- case FHT_SVR4:
- dissect_fhandle_data_SVR4 (tvb, offset, tree,
- fhlen);
- break;
- case FHT_LINUX_KNFSD_LE:
- dissect_fhandle_data_LINUX_KNFSD_LE(tvb, offset, tree,
- fhlen);
- break;
- case FHT_LINUX_NFSD_LE:
- dissect_fhandle_data_LINUX_NFSD_LE (tvb, offset, tree,
- fhlen);
- break;
- case FHT_LINUX_KNFSD_NEW:
- dissect_fhandle_data_LINUX_KNFSD_NEW (tvb, offset, tree,
- fhlen);
- break;
- case FHT_NETAPP:
- dissect_fhandle_data_NETAPP (tvb, offset, tree,
- fhlen);
- break;
- case FHT_UNKNOWN:
- default:
- dissect_fhandle_data_unknown(tvb, offset, tree, fhlen);
- break;
+ real_length=fhlen;
+ if(real_length<tvb_length_remaining(tvb, offset)){
+ real_length=tvb_length_remaining(tvb, offset);
+ }
+ fh_tvb=tvb_new_subset(tvb, offset, real_length, fhlen);
+ if(!dissector_try_port(nfs_fhandle_table, default_nfs_fhandle_type, fh_tvb, pinfo, tree)){
+ dissect_fhandle_data_unknown(fh_tvb, pinfo, tree);
}
}
}
@@ -8718,6 +8621,10 @@ proto_register_nfs(void)
"r_addr", "nfs.r_addr", FT_BYTES, BASE_DEC, NULL, 0,
"r_addr", HFILL }},
+ { &hf_nfs_fh_fhandle_data, {
+ "filehandle", "nfs.fhandle", FT_BYTES, BASE_HEX, NULL, 0,
+ "Opaque nfs filehandle", HFILL }},
+
{ &hf_nfs_secinfo_arr4, {
"Flavors Info", "nfs.flavors.info", FT_NONE, BASE_NONE,
NULL, 0, "Flavors Info", HFILL }},
@@ -8854,19 +8761,54 @@ proto_register_nfs(void)
"Fhandle filters finds both request/response",
"With this option display filters for nfs fhandles (nfs.fh.{name|full_name|hash}) will find both the request and response packets for a RPC call, even if the actual fhandle is only present in one of the packets",
&nfs_fhandle_reqrep_matching);
+ nfs_fhandle_table = register_dissector_table("nfs_fhandle.type",
+ "NFS Filehandle types", FT_UINT8, BASE_HEX);
+
+ prefs_register_enum_preference(nfs_module,
+ "default_fhandle_type",
+ "Decode nfs fhandles as",
+ "Decode all NFS file handles as if they are of this type",
+ &default_nfs_fhandle_type,
+ nfs_fhandle_types,
+ FALSE);
+
nfs_name_snoop_known=se_tree_create(SE_TREE_TYPE_RED_BLACK, "nfs_name_snoop_known");
nfs_file_handles=se_tree_create(SE_TREE_TYPE_RED_BLACK, "nfs_file_handles");
nfs_fhandle_frame_table=se_tree_create(SE_TREE_TYPE_RED_BLACK, "nfs_fhandle_frame_table");
register_init_routine(nfs_name_snoop_init);
+
}
void
proto_reg_handoff_nfs(void)
{
+ dissector_handle_t fhandle_handle;
+
/* 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, 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);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_SVR4, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_SVR4, fhandle_handle);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_LE, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_LINUX_KNFSD_LE, fhandle_handle);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_LINUX_NFSD_LE, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_LINUX_NFSD_LE, fhandle_handle);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_NEW, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_LINUX_KNFSD_NEW, fhandle_handle);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_NETAPP, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_NETAPP, fhandle_handle);
+
+ fhandle_handle=create_dissector_handle(dissect_fhandle_data_unknown, proto_nfs);
+ dissector_add("nfs_fhandle.type", FHT_UNKNOWN, fhandle_handle);
+
+
}
+
diff --git a/epan/dissectors/packet-nfs.h b/epan/dissectors/packet-nfs.h
index f0da25b053..a97827ef7f 100644
--- a/epan/dissectors/packet-nfs.h
+++ b/epan/dissectors/packet-nfs.h
@@ -127,5 +127,7 @@ extern int dissect_fattr(tvbuff_t *tvb, int offset, proto_tree *tree,
extern int dissect_access(tvbuff_t *tvb, int offset, proto_tree *tree,
const char* name);
+extern gint default_nfs_fhandle_type;
+
#endif /* packet-nfs.h */