#include #include #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); }