Wireshark-dev: [Wireshark-dev] [PATCH 15/16] NFS: Use 64-bit key for filename snooping hashtabl
From: Pali Rohár <pali@xxxxxxxxxx>
Date: Fri, 13 Sep 2024 23:08:50 +0200
Preparation for NFSv4 filename snooping, 32-bit wide key is not enough for NFSv4.
---
epan/dissectors/packet-nfs.c | 53 ++++++++++++++----------------------
epan/dissectors/packet-nfs.h | 2 +-
2 files changed, 22 insertions(+), 33 deletions(-)
diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c
index 9bb59ff18d96..57339df19dde 100644
--- a/epan/dissectors/packet-nfs.c
+++ b/epan/dissectors/packet-nfs.c
@@ -1155,25 +1155,6 @@ nfs_name_snoop_matched_hash(const void *k)
}
-static int
-nfs_name_snoop_unmatched_equal(const void *k1, const void *k2)
-{
- uint32_t key1 = GPOINTER_TO_UINT(k1);
- uint32_t key2 = GPOINTER_TO_UINT(k2);
-
- return key1 == key2;
-}
-
-
-static unsigned
-nfs_name_snoop_unmatched_hash(const void *k)
-{
- uint32_t key = GPOINTER_TO_UINT(k);
-
- return key;
-}
-
-
static void
nfs_name_snoop_value_destroy(void *value)
{
@@ -1191,12 +1172,12 @@ static void
nfs_name_snoop_init(void)
{
nfs_name_snoop_readdir =
- g_hash_table_new_full(nfs_name_snoop_unmatched_hash,
- nfs_name_snoop_unmatched_equal,
+ g_hash_table_new_full(g_int64_hash,
+ g_int64_equal,
NULL, nfs_name_snoop_value_destroy);
nfs_name_snoop_unmatched =
- g_hash_table_new_full(nfs_name_snoop_unmatched_hash,
- nfs_name_snoop_unmatched_equal,
+ g_hash_table_new_full(g_int64_hash,
+ g_int64_equal,
NULL, nfs_name_snoop_value_destroy);
nfs_name_snoop_matched =
g_hash_table_new_full(nfs_name_snoop_matched_hash,
@@ -1214,11 +1195,12 @@ nfs_name_snoop_cleanup(void)
void
-nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, int parent_offset,
+nfs_name_snoop_add_name(uint64_t id, tvbuff_t *tvb, int name_offset, int name_len, int parent_offset,
int parent_len, const char *name)
{
nfs_name_snoop_t *nns;
const char *ptr;
+ uint64_t *key;
if (name_len <= 0) {
/* Do we need some way to signal an error here? This could be
@@ -1272,19 +1254,22 @@ nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, i
nns->fs_cycle = false;
/* any old entry will be deallocated and removed */
- g_hash_table_insert(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid), nns);
+ key = g_new0(uint64_t, 1);
+ *key = id;
+ g_hash_table_insert(nfs_name_snoop_unmatched, key, nns);
}
static void
-nfs_name_snoop_add_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
+nfs_name_snoop_add_fh(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length)
{
unsigned char *fh;
nfs_name_snoop_t *nns;
nfs_name_snoop_key_t *key;
+ gpointer stolen_key;
/* find which request we correspond to */
- nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
+ nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_unmatched, &id);
if (!nns) {
/* oops couldn't find matching request, bail out */
return;
@@ -1305,15 +1290,17 @@ nfs_name_snoop_add_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
key->fh_length = nns->fh_length;
key->fh = nns->fh;
- g_hash_table_steal(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
+ g_hash_table_steal_extended(nfs_name_snoop_unmatched, &id, &stolen_key, NULL);
+ g_free(stolen_key);
g_hash_table_replace(nfs_name_snoop_matched, key, nns);
}
static void
-nfs_name_snoop_readdir_add_parent_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
+nfs_name_snoop_readdir_add_parent_fh(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length)
{
nfs_name_snoop_t *nns;
unsigned char *fh;
+ uint64_t *key;
fh = (unsigned char *)tvb_memdup(NULL, tvb, fh_offset, fh_length);
@@ -1321,11 +1308,13 @@ nfs_name_snoop_readdir_add_parent_fh(int xid, tvbuff_t *tvb, int fh_offset, int
nns->parent_len = fh_length;
nns->parent = fh;
- g_hash_table_insert(nfs_name_snoop_readdir, GINT_TO_POINTER(xid), nns);
+ key = g_new0(uint64_t, 1);
+ *key = id;
+ g_hash_table_insert(nfs_name_snoop_readdir, key, nns);
}
static void
-nfs_name_snoop_readdir_add_child_fh_name(int xid, tvbuff_t *tvb, int fh_offset, int fh_length, const char *name)
+nfs_name_snoop_readdir_add_child_fh_name(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length, const char *name)
{
nfs_name_snoop_t *readdir_nns;
unsigned char *fh;
@@ -1335,7 +1324,7 @@ nfs_name_snoop_readdir_add_child_fh_name(int xid, tvbuff_t *tvb, int fh_offset,
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
return;
- readdir_nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_readdir, GINT_TO_POINTER(xid));
+ readdir_nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_readdir, &id);
if (!readdir_nns)
return;
diff --git a/epan/dissectors/packet-nfs.h b/epan/dissectors/packet-nfs.h
index c51465f6f868..ce5ba03fffc7 100644
--- a/epan/dissectors/packet-nfs.h
+++ b/epan/dissectors/packet-nfs.h
@@ -204,7 +204,7 @@
#define NL4_NETADDR 3
extern bool nfs_file_name_snooping;
-extern void nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len,
+extern void nfs_name_snoop_add_name(uint64_t xid, tvbuff_t *tvb, int name_offset, int name_len,
int parent_offset, int parent_len, const char *name);
extern bool nfs_fhandle_reqrep_matching;
extern int dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
--
2.20.1
- References:
- [Wireshark-dev] [PATCH 00/16] NFS: Improve dissector
- From: Pali Rohár
- [Wireshark-dev] [PATCH 00/16] NFS: Improve dissector
- Prev by Date: [Wireshark-dev] [PATCH 13/16] NFS: Fix dissecting NFS4 mode
- Next by Date: [Wireshark-dev] [PATCH 14/16] NFS: Fix dissecting NFS4 CREATE_SESSION cb_sec_params
- Previous by thread: [Wireshark-dev] [PATCH 13/16] NFS: Fix dissecting NFS4 mode
- Next by thread: [Wireshark-dev] [PATCH 14/16] NFS: Fix dissecting NFS4 CREATE_SESSION cb_sec_params
- Index(es):