424 lines
12 KiB
C
424 lines
12 KiB
C
#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->addr_family, sizeof(tuple->addr_family), 0);
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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->addr_family, sizeof(tuple->addr_family), 0);
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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->addr_family, sizeof(tuple->addr_family), 0);
|
|
hash = crc32_hash(&tuple->ip_proto, sizeof(tuple->ip_proto), hash);
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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->addr_family, sizeof(tuple->addr_family), 0);
|
|
hash = crc32_hash(&tuple->ip_proto, sizeof(tuple->ip_proto), hash);
|
|
hash = crc32_hash(&tuple->domain, sizeof(tuple->domain), hash);
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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->addr_family != tuple_b->addr_family)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (tuple_a->addr_family == AF_INET)
|
|
{
|
|
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->addr_family != tuple_b->addr_family)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (tuple_a->addr_family == AF_INET)
|
|
{
|
|
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->addr_family != tuple_b->addr_family)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (tuple_a->addr_family == AF_INET)
|
|
{
|
|
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->domain != tuple_b->domain)
|
|
{
|
|
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->addr_family != tuple_b->addr_family)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (tuple_a->addr_family == AF_INET)
|
|
{
|
|
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)
|
|
{
|
|
memset(out, 0, sizeof(struct tuple2));
|
|
out->addr_family = in->addr_family;
|
|
|
|
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
|
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
|
}
|
|
|
|
void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out)
|
|
{
|
|
memset(out, 0, sizeof(struct tuple4));
|
|
out->addr_family = in->addr_family;
|
|
out->src_port = in->dst_port;
|
|
out->dst_port = in->src_port;
|
|
|
|
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
|
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
|
}
|
|
|
|
void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out)
|
|
{
|
|
memset(out, 0, sizeof(struct tuple5));
|
|
out->addr_family = in->addr_family;
|
|
out->ip_proto = in->ip_proto;
|
|
out->src_port = in->dst_port;
|
|
out->dst_port = in->src_port;
|
|
|
|
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
|
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
|
}
|
|
|
|
void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out)
|
|
{
|
|
memset(out, 0, sizeof(struct tuple6));
|
|
out->addr_family = in->addr_family;
|
|
out->ip_proto = in->ip_proto;
|
|
out->domain = in->domain;
|
|
out->src_port = in->dst_port;
|
|
out->dst_port = in->src_port;
|
|
|
|
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
|
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
|
}
|
|
|
|
void tuple2_to_str(const struct tuple2 *tuple, char *buf, uint32_t size)
|
|
{
|
|
char src_addr[INET6_ADDRSTRLEN] = {0};
|
|
char dst_addr[INET6_ADDRSTRLEN] = {0};
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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_to_str(const struct tuple4 *tuple, char *buf, uint32_t size)
|
|
{
|
|
char src_addr[INET6_ADDRSTRLEN] = {0};
|
|
char dst_addr[INET6_ADDRSTRLEN] = {0};
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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_to_str(const struct tuple5 *tuple, char *buf, uint32_t size)
|
|
{
|
|
char src_addr[INET6_ADDRSTRLEN] = {0};
|
|
char dst_addr[INET6_ADDRSTRLEN] = {0};
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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-%u",
|
|
src_addr, ntohs(tuple->src_port),
|
|
dst_addr, ntohs(tuple->dst_port),
|
|
tuple->ip_proto);
|
|
}
|
|
|
|
void tuple6_to_str(const struct tuple6 *tuple, char *buf, uint32_t size)
|
|
{
|
|
char src_addr[INET6_ADDRSTRLEN] = {0};
|
|
char dst_addr[INET6_ADDRSTRLEN] = {0};
|
|
|
|
if (tuple->addr_family == AF_INET)
|
|
{
|
|
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-%u-%lu",
|
|
src_addr, ntohs(tuple->src_port),
|
|
dst_addr, ntohs(tuple->dst_port),
|
|
tuple->ip_proto, tuple->domain);
|
|
} |