Add session address

This commit is contained in:
luwenpeng
2023-12-11 16:22:46 +08:00
parent 252c74719b
commit 37aeb10e59
5 changed files with 372 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
#include <gtest/gtest.h>
#include "session_address.h"
#define SESSION_ADDRESS_IPV4_TCP(name) \
struct session_address name = {0}; \
(name).layers[0].type = LAYER_IPV4; \
(name).layers[0].tuple.ipv4.src.s_addr = inet_addr("192.168.1.2"); \
(name).layers[0].tuple.ipv4.dst.s_addr = inet_addr("192.168.1.3"); \
(name).layers[1].type = LAYER_TCP; \
(name).layers[1].tuple.tcp.src = htons(1234); \
(name).layers[1].tuple.tcp.dst = htons(5678); \
(name).used = 2;
#define SESSION_ADDRESS_IPV6_UDP(name) \
struct session_address name = {0}; \
(name).layers[0].type = LAYER_IPV6; \
inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).layers[0].tuple.ipv6.src); \
inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).layers[0].tuple.ipv6.dst); \
(name).layers[1].type = LAYER_UDP; \
(name).layers[1].tuple.udp.src = htons(2345); \
(name).layers[1].tuple.udp.dst = htons(443); \
(name).used = 2;
#define SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(name) \
struct session_address name = {0}; \
(name).layers[0].type = LAYER_IPV4; \
(name).layers[0].tuple.ipv4.src.s_addr = inet_addr("192.168.1.2"); \
(name).layers[0].tuple.ipv4.dst.s_addr = inet_addr("192.168.1.3"); \
(name).layers[1].type = LAYER_UDP; \
(name).layers[1].tuple.udp.src = htons(1234); \
(name).layers[1].tuple.udp.dst = htons(5678); \
(name).layers[2].type = LAYER_IPV6; \
inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).layers[2].tuple.ipv6.src); \
inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).layers[2].tuple.ipv6.dst); \
(name).layers[3].type = LAYER_TCP; \
(name).layers[3].tuple.tcp.src = htons(2345); \
(name).layers[3].tuple.tcp.dst = htons(443); \
(name).used = 4;
TEST(SESSION_ADDRESS, TOSTRING)
{
char buff[256] = {0};
SESSION_ADDRESS_IPV4_TCP(sess1_addr);
SESSION_ADDRESS_IPV6_UDP(sess2_addr);
SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr);
session_address_tostring(&sess1_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "192.168.1.2-192.168.1.3/1234-5678/");
session_address_tostring(&sess2_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "2001:db8::ff00:42:8329-2001:db8::ff00:42:832a/2345-443/");
session_address_tostring(&sess3_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "192.168.1.2-192.168.1.3/1234-5678/2001:db8::ff00:42:8329-2001:db8::ff00:42:832a/2345-443/");
}
TEST(SESSION_ADDRESS, REVERSE)
{
char buff[256] = {0};
SESSION_ADDRESS_IPV4_TCP(sess1_addr);
SESSION_ADDRESS_IPV6_UDP(sess2_addr);
SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr);
session_address_reverse(&sess1_addr);
session_address_reverse(&sess2_addr);
session_address_reverse(&sess3_addr);
session_address_tostring(&sess1_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "192.168.1.3-192.168.1.2/5678-1234/");
session_address_tostring(&sess2_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "2001:db8::ff00:42:832a-2001:db8::ff00:42:8329/443-2345/");
session_address_tostring(&sess3_addr, buff, sizeof(buff));
EXPECT_STREQ(buff, "192.168.1.3-192.168.1.2/5678-1234/2001:db8::ff00:42:832a-2001:db8::ff00:42:8329/443-2345/");
}
TEST(SESSION_ADDRESS, SELFCMP)
{
SESSION_ADDRESS_IPV4_TCP(sess1_addr);
SESSION_ADDRESS_IPV6_UDP(sess2_addr);
SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr);
EXPECT_TRUE(session_address_selfcmp(&sess1_addr) < 0);
EXPECT_TRUE(session_address_selfcmp(&sess2_addr) < 0);
EXPECT_TRUE(session_address_selfcmp(&sess3_addr) < 0);
session_address_reverse(&sess1_addr);
session_address_reverse(&sess2_addr);
session_address_reverse(&sess3_addr);
EXPECT_TRUE(session_address_selfcmp(&sess1_addr) > 0);
EXPECT_TRUE(session_address_selfcmp(&sess2_addr) > 0);
EXPECT_TRUE(session_address_selfcmp(&sess3_addr) > 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,184 @@
#include <string.h>
#include <stdio.h>
#include "session_address.h"
void session_address_init(struct session_address *addr, const struct packet *packet)
{
// TODO
}
void session_address_tostring(const struct session_address *addr, char *buf, size_t len)
{
char *ptr = buf;
size_t used = 0;
size_t tlen = 0;
for (int i = 0; i < addr->used; i++)
{
const struct layer_tuple *tuple = &addr->layers[i];
switch (tuple->type)
{
case LAYER_IPV4:
if (len - used < 32)
{
return;
}
inet_ntop(AF_INET, &tuple->tuple.ipv4.src, ptr, len - used);
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '-';
used += 1;
inet_ntop(AF_INET, &tuple->tuple.ipv4.dst, ptr, len - used);
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '/';
used += 1;
break;
case LAYER_IPV6:
if (len - used < 64)
{
return;
}
inet_ntop(AF_INET6, &tuple->tuple.ipv6.src, ptr, len - used);
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '-';
used += 1;
inet_ntop(AF_INET6, &tuple->tuple.ipv6.dst, ptr, len - used);
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '/';
used += 1;
break;
case LAYER_TCP:
if (len - used < 16)
{
return;
}
snprintf(ptr, len - used, "%u-%u", ntohs(tuple->tuple.tcp.src), ntohs(tuple->tuple.tcp.dst));
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '/';
used += 1;
break;
case LAYER_UDP:
if (len - used < 16)
{
return;
}
snprintf(ptr, len - used, "%u-%u", ntohs(tuple->tuple.udp.src), ntohs(tuple->tuple.udp.dst));
tlen = strlen(ptr);
used += tlen;
ptr += tlen;
*ptr++ = '/';
used += 1;
break;
default:
return;
}
}
}
void session_address_reverse(struct session_address *addr)
{
for (int i = 0; i < addr->used; i++)
{
struct layer_tuple *tuple = &addr->layers[i];
switch (tuple->type)
{
case LAYER_IPV4:
{
struct in_addr tmp = tuple->tuple.ipv4.src;
tuple->tuple.ipv4.src = tuple->tuple.ipv4.dst;
tuple->tuple.ipv4.dst = tmp;
break;
}
case LAYER_IPV6:
{
struct in6_addr tmp = tuple->tuple.ipv6.src;
tuple->tuple.ipv6.src = tuple->tuple.ipv6.dst;
tuple->tuple.ipv6.dst = tmp;
break;
}
case LAYER_TCP:
{
uint16_t tmp = tuple->tuple.tcp.src;
tuple->tuple.tcp.src = tuple->tuple.tcp.dst;
tuple->tuple.tcp.dst = tmp;
break;
}
case LAYER_UDP:
{
uint16_t tmp = tuple->tuple.udp.src;
tuple->tuple.udp.src = tuple->tuple.udp.dst;
tuple->tuple.udp.dst = tmp;
break;
}
default:
return;
}
}
}
// cmp src and dst
// return: src - dst
int session_address_selfcmp(struct session_address *addr)
{
int ret = 0;
for (int i = 0; i < addr->used; i++)
{
struct layer_tuple *tuple = &addr->layers[i];
switch (tuple->type)
{
case LAYER_IPV4:
{
ret = tuple->tuple.ipv4.src.s_addr - tuple->tuple.ipv4.dst.s_addr;
if (ret != 0)
{
return ret;
}
break;
}
case LAYER_IPV6:
{
for (int j = 0; j < 16; j++)
{
ret = tuple->tuple.ipv6.src.s6_addr[j] - tuple->tuple.ipv6.dst.s6_addr[j];
if (ret != 0)
{
return ret;
}
}
break;
}
case LAYER_TCP:
{
ret = tuple->tuple.tcp.src - tuple->tuple.tcp.dst;
if (ret != 0)
{
return ret;
}
break;
}
case LAYER_UDP:
{
ret = tuple->tuple.udp.src - tuple->tuple.udp.dst;
if (ret != 0)
{
return ret;
}
break;
}
default:
break;
}
}
return 0;
}

View File

@@ -0,0 +1,72 @@
#ifndef _SESSION_ADDRESS_H
#define _SESSION_ADDRESS_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include <arpa/inet.h>
#define SESSION_ADDR_MAX_LAYER 8
enum layer_type
{
LAYER_IPV4 = 0,
LAYER_IPV6 = 1,
LAYER_TCP = 2,
LAYER_UDP = 3,
};
struct ipv4_address
{
struct in_addr src; /* network order */
struct in_addr dst; /* network order */
};
struct ipv6_address
{
struct in6_addr src; /* network order */
struct in6_addr dst; /* network order */
};
struct tcp_port
{
uint16_t src; /* network order */
uint16_t dst; /* network order */
};
struct udp_port
{
uint16_t src; /* network order */
uint16_t dst; /* network order */
};
struct layer_tuple
{
enum layer_type type;
union
{
struct ipv4_address ipv4;
struct ipv6_address ipv6;
struct tcp_port tcp;
struct udp_port udp;
} tuple;
};
struct session_address
{
uint8_t used;
struct layer_tuple layers[SESSION_ADDR_MAX_LAYER];
};
void session_address_init(struct session_address *addr, const struct packet *packet);
void session_address_tostring(const struct session_address *addr, char *buf, size_t len);
void session_address_reverse(struct session_address *addr);
int session_address_selfcmp(struct session_address *addr);
#ifdef __cpluscplus
}
#endif
#endif