summaryrefslogtreecommitdiff
path: root/common/src/tuple.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/tuple.cpp')
-rw-r--r--common/src/tuple.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/common/src/tuple.cpp b/common/src/tuple.cpp
new file mode 100644
index 0000000..9b4fed2
--- /dev/null
+++ b/common/src/tuple.cpp
@@ -0,0 +1,452 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "tuple.h"
+#include "crc32_hash.h"
+
+uint32_t tuple2_hash(const struct tuple2 *tuple)
+{
+ uint32_t src_addr_hash = 0;
+ uint32_t dst_addr_hash = 0;
+ uint32_t hash = crc32_hash(&tuple->ip_type, sizeof(tuple->ip_type), 0);
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v4, sizeof(tuple->src_addr.v4), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v4, sizeof(tuple->dst_addr.v4), hash);
+ }
+ else
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v6, sizeof(tuple->src_addr.v6), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v6, sizeof(tuple->dst_addr.v6), hash);
+ }
+ hash = src_addr_hash + dst_addr_hash;
+
+ return hash;
+}
+
+uint32_t tuple4_hash(const struct tuple4 *tuple)
+{
+ uint32_t src_addr_hash = 0;
+ uint32_t dst_addr_hash = 0;
+ uint32_t src_port_hash = 0;
+ uint32_t dst_port_hash = 0;
+ uint32_t hash = crc32_hash(&tuple->ip_type, sizeof(tuple->ip_type), 0);
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v4, sizeof(tuple->src_addr.v4), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v4, sizeof(tuple->dst_addr.v4), hash);
+ }
+ else
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v6, sizeof(tuple->src_addr.v6), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v6, sizeof(tuple->dst_addr.v6), hash);
+ }
+ hash = src_addr_hash + dst_addr_hash;
+
+ src_port_hash = crc32_hash(&tuple->src_port, sizeof(tuple->src_port), hash);
+ dst_port_hash = crc32_hash(&tuple->dst_port, sizeof(tuple->dst_port), hash);
+ hash = src_port_hash + dst_port_hash;
+
+ return hash;
+}
+
+uint32_t tuple5_hash(const struct tuple5 *tuple)
+{
+ uint32_t src_addr_hash = 0;
+ uint32_t dst_addr_hash = 0;
+ uint32_t src_port_hash = 0;
+ uint32_t dst_port_hash = 0;
+ uint32_t hash = crc32_hash(&tuple->ip_type, sizeof(tuple->ip_type), 0);
+ hash = crc32_hash(&tuple->ip_proto, sizeof(tuple->ip_proto), hash);
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v4, sizeof(tuple->src_addr.v4), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v4, sizeof(tuple->dst_addr.v4), hash);
+ }
+ else
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v6, sizeof(tuple->src_addr.v6), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v6, sizeof(tuple->dst_addr.v6), hash);
+ }
+ hash = src_addr_hash + dst_addr_hash;
+
+ src_port_hash = crc32_hash(&tuple->src_port, sizeof(tuple->src_port), hash);
+ dst_port_hash = crc32_hash(&tuple->dst_port, sizeof(tuple->dst_port), hash);
+ hash = src_port_hash + dst_port_hash;
+
+ return hash;
+}
+
+uint32_t tuple6_hash(const struct tuple6 *tuple)
+{
+ uint32_t src_addr_hash = 0;
+ uint32_t dst_addr_hash = 0;
+ uint32_t src_port_hash = 0;
+ uint32_t dst_port_hash = 0;
+ uint32_t hash = crc32_hash(&tuple->ip_type, sizeof(tuple->ip_type), 0);
+ hash = crc32_hash(&tuple->ip_proto, sizeof(tuple->ip_proto), hash);
+ hash = crc32_hash(&tuple->security_zone, sizeof(tuple->security_zone), hash);
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v4, sizeof(tuple->src_addr.v4), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v4, sizeof(tuple->dst_addr.v4), hash);
+ }
+ else
+ {
+ src_addr_hash = crc32_hash(&tuple->src_addr.v6, sizeof(tuple->src_addr.v6), hash);
+ dst_addr_hash = crc32_hash(&tuple->dst_addr.v6, sizeof(tuple->dst_addr.v6), hash);
+ }
+ hash = src_addr_hash + dst_addr_hash;
+
+ src_port_hash = crc32_hash(&tuple->src_port, sizeof(tuple->src_port), hash);
+ dst_port_hash = crc32_hash(&tuple->dst_port, sizeof(tuple->dst_port), hash);
+ hash = src_port_hash + dst_port_hash;
+
+ return hash;
+}
+
+int tuple2_cmp(const struct tuple2 *tuple_a, const struct tuple2 *tuple_b)
+{
+ if (tuple_a->ip_type != tuple_b->ip_type)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type == IP_TYPE_V4)
+ {
+ if (tuple_a->src_addr.v4.s_addr != tuple_b->src_addr.v4.s_addr)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_addr.v4.s_addr != tuple_b->dst_addr.v4.s_addr)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ if (memcmp(&tuple_a->src_addr.v6, &tuple_b->src_addr.v6, sizeof(tuple_a->src_addr.v6)) != 0)
+ {
+ return -1;
+ }
+
+ if (memcmp(&tuple_a->dst_addr.v6, &tuple_b->dst_addr.v6, sizeof(tuple_a->dst_addr.v6)) != 0)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int tuple4_cmp(const struct tuple4 *tuple_a, const struct tuple4 *tuple_b)
+{
+ if (tuple_a->src_port != tuple_b->src_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_port != tuple_b->dst_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type != tuple_b->ip_type)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type == IP_TYPE_V4)
+ {
+ if (tuple_a->src_addr.v4.s_addr != tuple_b->src_addr.v4.s_addr)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_addr.v4.s_addr != tuple_b->dst_addr.v4.s_addr)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ if (memcmp(&tuple_a->src_addr.v6, &tuple_b->src_addr.v6, sizeof(tuple_a->src_addr.v6)) != 0)
+ {
+ return -1;
+ }
+
+ if (memcmp(&tuple_a->dst_addr.v6, &tuple_b->dst_addr.v6, sizeof(tuple_a->dst_addr.v6)) != 0)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int tuple5_cmp(const struct tuple5 *tuple_a, const struct tuple5 *tuple_b)
+{
+ if (tuple_a->ip_proto != tuple_b->ip_proto)
+ {
+ return -1;
+ }
+
+ if (tuple_a->src_port != tuple_b->src_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_port != tuple_b->dst_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type != tuple_b->ip_type)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type == IP_TYPE_V4)
+ {
+ if (tuple_a->src_addr.v4.s_addr != tuple_b->src_addr.v4.s_addr)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_addr.v4.s_addr != tuple_b->dst_addr.v4.s_addr)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ if (memcmp(&tuple_a->src_addr.v6, &tuple_b->src_addr.v6, sizeof(tuple_a->src_addr.v6)) != 0)
+ {
+ return -1;
+ }
+
+ if (memcmp(&tuple_a->dst_addr.v6, &tuple_b->dst_addr.v6, sizeof(tuple_a->dst_addr.v6)) != 0)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int tuple6_cmp(const struct tuple6 *tuple_a, const struct tuple6 *tuple_b)
+{
+ if (tuple_a->security_zone != tuple_b->security_zone)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_proto != tuple_b->ip_proto)
+ {
+ return -1;
+ }
+
+ if (tuple_a->src_port != tuple_b->src_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_port != tuple_b->dst_port)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type != tuple_b->ip_type)
+ {
+ return -1;
+ }
+
+ if (tuple_a->ip_type == IP_TYPE_V4)
+ {
+ if (tuple_a->src_addr.v4.s_addr != tuple_b->src_addr.v4.s_addr)
+ {
+ return -1;
+ }
+
+ if (tuple_a->dst_addr.v4.s_addr != tuple_b->dst_addr.v4.s_addr)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ if (memcmp(&tuple_a->src_addr.v6, &tuple_b->src_addr.v6, sizeof(tuple_a->src_addr.v6)) != 0)
+ {
+ return -1;
+ }
+
+ if (memcmp(&tuple_a->dst_addr.v6, &tuple_b->dst_addr.v6, sizeof(tuple_a->dst_addr.v6)) != 0)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void tuple2_reverse(const struct tuple2 *in, struct tuple2 *out)
+{
+ out->ip_type = in->ip_type;
+
+ if (in->ip_type == IP_TYPE_V4)
+ {
+ out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
+ out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
+ }
+ else
+ {
+ memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
+ memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
+ }
+}
+
+void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out)
+{
+ out->ip_type = in->ip_type;
+ out->src_port = in->dst_port;
+ out->dst_port = in->src_port;
+
+ if (in->ip_type == IP_TYPE_V4)
+ {
+ out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
+ out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
+ }
+ else
+ {
+ memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
+ memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
+ }
+}
+
+void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out)
+{
+ out->ip_type = in->ip_type;
+ out->ip_proto = in->ip_proto;
+ out->src_port = in->dst_port;
+ out->dst_port = in->src_port;
+
+ if (in->ip_type == IP_TYPE_V4)
+ {
+ out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
+ out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
+ }
+ else
+ {
+ memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
+ memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
+ }
+}
+
+void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out)
+{
+ out->ip_type = in->ip_type;
+ out->ip_proto = in->ip_proto;
+ out->security_zone = in->security_zone;
+ out->src_port = in->dst_port;
+ out->dst_port = in->src_port;
+
+ if (in->ip_type == IP_TYPE_V4)
+ {
+ out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
+ out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
+ }
+ else
+ {
+ memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
+ memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
+ }
+}
+
+void tuple2_tostring(const struct tuple2 *tuple, char *buf, uint32_t size)
+{
+ char src_addr[INET6_ADDRSTRLEN] = {0};
+ char dst_addr[INET6_ADDRSTRLEN] = {0};
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ inet_ntop(AF_INET, &tuple->src_addr.v4, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET, &tuple->dst_addr.v4, dst_addr, INET6_ADDRSTRLEN);
+ }
+ else
+ {
+ inet_ntop(AF_INET6, &tuple->src_addr.v6, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET6, &tuple->dst_addr.v6, dst_addr, INET6_ADDRSTRLEN);
+ }
+
+ snprintf(buf, size, "%s -> %s", src_addr, dst_addr);
+}
+
+void tuple4_tostring(const struct tuple4 *tuple, char *buf, uint32_t size)
+{
+ char src_addr[INET6_ADDRSTRLEN] = {0};
+ char dst_addr[INET6_ADDRSTRLEN] = {0};
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ inet_ntop(AF_INET, &tuple->src_addr.v4, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET, &tuple->dst_addr.v4, dst_addr, INET6_ADDRSTRLEN);
+ }
+ else
+ {
+ inet_ntop(AF_INET6, &tuple->src_addr.v6, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET6, &tuple->dst_addr.v6, dst_addr, INET6_ADDRSTRLEN);
+ }
+
+ snprintf(buf, size, "%s:%u -> %s:%u",
+ src_addr, ntohs(tuple->src_port),
+ dst_addr, ntohs(tuple->dst_port));
+}
+
+void tuple5_tostring(const struct tuple5 *tuple, char *buf, uint32_t size)
+{
+ char src_addr[INET6_ADDRSTRLEN] = {0};
+ char dst_addr[INET6_ADDRSTRLEN] = {0};
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ inet_ntop(AF_INET, &tuple->src_addr.v4, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET, &tuple->dst_addr.v4, dst_addr, INET6_ADDRSTRLEN);
+ }
+ else
+ {
+ inet_ntop(AF_INET6, &tuple->src_addr.v6, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET6, &tuple->dst_addr.v6, dst_addr, INET6_ADDRSTRLEN);
+ }
+
+ snprintf(buf, size, "%s:%u -> %s:%u, proto: %u",
+ src_addr, ntohs(tuple->src_port),
+ dst_addr, ntohs(tuple->dst_port),
+ tuple->ip_proto);
+}
+
+void tuple6_tostring(const struct tuple6 *tuple, char *buf, uint32_t size)
+{
+ char src_addr[INET6_ADDRSTRLEN] = {0};
+ char dst_addr[INET6_ADDRSTRLEN] = {0};
+
+ if (tuple->ip_type == IP_TYPE_V4)
+ {
+ inet_ntop(AF_INET, &tuple->src_addr.v4, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET, &tuple->dst_addr.v4, dst_addr, INET6_ADDRSTRLEN);
+ }
+ else
+ {
+ inet_ntop(AF_INET6, &tuple->src_addr.v6, src_addr, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET6, &tuple->dst_addr.v6, dst_addr, INET6_ADDRSTRLEN);
+ }
+
+ snprintf(buf, size, "%s:%u -> %s:%u, proto: %u, zone: %lu",
+ src_addr, ntohs(tuple->src_port),
+ dst_addr, ntohs(tuple->dst_port),
+ tuple->ip_proto, tuple->security_zone);
+} \ No newline at end of file