aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2021-01-20 21:30:19 +0100
committerLuca Deri <deri@ntop.org>2021-01-20 21:30:19 +0100
commit3e5e9569ff6454e11a09d4cbb88efa778508ed05 (patch)
treea5d15631ae14cbe325a8280e0cddf16d345f1a61
parentd964c3e08179fd68da655b5f2975486cf918ff4a (diff)
Added simple hash implementation to the nDPI API
-rw-r--r--example/ndpiReader.c23
-rw-r--r--src/include/ndpi_api.h.in9
-rw-r--r--src/include/ndpi_typedefs.h17
-rw-r--r--src/lib/ndpi_utils.c103
4 files changed, 151 insertions, 1 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 98eef139d..5fbf9ebe2 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -114,7 +114,7 @@ struct info_pair {
int count;
};
-typedef struct node_a{
+typedef struct node_a {
u_int32_t addr;
u_int8_t version; /* IP version */
char proto[16]; /*app level protocol*/
@@ -3690,6 +3690,25 @@ void rulesUnitTest() {
/* *********************************************** */
+void hashUnitTest() {
+ ndpi_str_hash *h = ndpi_hash_alloc(16384);
+ char* dict[] = { "hello", "world", NULL };
+ int i;
+
+ assert(h);
+
+ for(i=0; dict[i] != NULL; i++) {
+ u_int8_t l = strlen(dict[i]), v;
+
+ assert(ndpi_hash_add_entry(h, dict[i], l, i) == 0);
+ assert(ndpi_hash_find_entry(h, dict[i], l, &v) == 0);
+ }
+
+ ndpi_hash_free(h);
+}
+
+/* *********************************************** */
+
/**
@brief MAIN FUNCTION
**/
@@ -3712,6 +3731,7 @@ int orginal_main(int argc, char **argv) {
/* Internal checks */
// binUnitTest();
+ hashUnitTest();
dgaUnitTest();
hllUnitTest();
bitmapUnitTest();
@@ -3811,3 +3831,4 @@ int orginal_main(int argc, char **argv) {
return 0;
}
#endif /* WIN32 */
+
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index f5b5f15db..18936f9ff 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -1433,8 +1433,17 @@ extern "C" {
u_int8_t num_clusters, u_int16_t *cluster_ids,
struct ndpi_bin *centroids);
+ /* ******************************* */
+
u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long);
+ /* ******************************* */
+
+ ndpi_str_hash* ndpi_hash_alloc(u_int32_t max_num_entries);
+ void ndpi_hash_free(ndpi_str_hash *h);
+ int ndpi_hash_find_entry(ndpi_str_hash *h, char *key, u_int key_len, u_int8_t *value);
+ int ndpi_hash_add_entry(ndpi_str_hash *h, char *key, u_int8_t key_len, u_int8_t value);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 6f9cc9885..76f9198da 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1559,4 +1559,21 @@ struct ndpi_bin {
} u;
};
+/* **************************************** */
+
+struct ndpi_str_hash_info {
+ char *key; /* Key */
+ u_int8_t key_len;
+ u_int8_t value; /* Value */
+ struct ndpi_str_hash_info *next;
+};
+
+typedef struct {
+ u_int32_t num_buckets, max_num_entries;
+ struct ndpi_str_hash_info **buckets;
+} ndpi_str_hash;
+
+
+/* **************************************** */
+
#endif /* __NDPI_TYPEDEFS_H__ */
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index cb6cb5e92..4f31369af 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1821,3 +1821,106 @@ u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long) {
}
/* ******************************************************************** */
+
+ndpi_str_hash* ndpi_hash_alloc(u_int32_t max_num_entries) {
+ ndpi_str_hash *h = (ndpi_str_hash*)malloc(sizeof(ndpi_str_hash));
+
+ if(!h) return(NULL);
+ if(max_num_entries < 1024) max_num_entries = 1024;
+ if(max_num_entries > 10000000) max_num_entries = 10000000;
+
+ h->max_num_entries = max_num_entries, h->num_buckets = max_num_entries/2;
+ h->buckets = (struct ndpi_str_hash_info**)calloc(sizeof(struct ndpi_str_hash_info*), h->num_buckets);
+
+ if(h->buckets == NULL) {
+ free(h);
+ return(NULL);
+ } else
+ return(h);
+}
+
+/* ******************************************************************** */
+
+void ndpi_hash_free(ndpi_str_hash *h) {
+ u_int32_t i;
+
+ for(i=0; i<h->num_buckets; i++) {
+ struct ndpi_str_hash_info *head = h->buckets[i];
+
+ while(head != NULL) {
+ struct ndpi_str_hash_info *next = head->next;
+
+ free(head->key);
+ free(head);
+ head = next;
+ }
+ }
+
+ free(h->buckets);
+ free(h);
+}
+
+/* ******************************************************************** */
+
+static u_int32_t _ndpi_hash_function(ndpi_str_hash *h, char *key, u_int8_t key_len) {
+ u_int32_t hv = 0;
+ u_int8_t i;
+
+ for(i=0; i<key_len; i++)
+ hv += key[i]*(i+1);
+
+ return(hv % h->num_buckets);
+}
+
+/* ******************************************************************** */
+
+static int _ndpi_hash_find_entry(ndpi_str_hash *h, u_int32_t hashval, char *key, u_int key_len, u_int8_t *value) {
+ struct ndpi_str_hash_info *head = h->buckets[hashval];
+
+ while(head != NULL) {
+ if((head->key_len == key_len) && (memcmp(head->key, key, key_len) == 0)) {
+ *value = head->value;
+ return(0); /* Found */
+ }
+
+ head = head-> next;
+ }
+
+ return(-1); /* Not found */
+}
+
+/* ******************************************************************** */
+
+int ndpi_hash_find_entry(ndpi_str_hash *h, char *key, u_int key_len, u_int8_t *value) {
+ u_int32_t hv = _ndpi_hash_function(h, key, key_len);
+
+ return(_ndpi_hash_find_entry(h, hv, key, key_len, value));
+}
+
+/* ******************************************************************** */
+
+int ndpi_hash_add_entry(ndpi_str_hash *h, char *key, u_int8_t key_len, u_int8_t value) {
+ u_int32_t hv = _ndpi_hash_function(h, key, key_len);
+ u_int8_t ret_value;
+ int rc = _ndpi_hash_find_entry(h, hv, key, key_len, &ret_value);
+
+ if(rc == -1) {
+ /* Not found */
+ struct ndpi_str_hash_info *e = (struct ndpi_str_hash_info*)malloc(sizeof(struct ndpi_str_hash_info));
+
+ if(e == NULL)
+ return(-2);
+
+ if((e->key = (char*)malloc(key_len)) == NULL)
+ return(-3);
+
+ memcpy(e->key, key, key_len);
+ e->key_len = key_len, e->value = value;
+ e->next = h->buckets[hv];
+ h->buckets[hv] = e;
+
+ return(0);
+ } else
+ return(0);
+}
+