重构Packet Parser
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
add_library(common src/four_tuple.cpp src/session_table.cpp src/data_packet.cpp src/control_packet.cpp src/bfd.cpp src/utils.cpp src/g_vxlan.cpp src/log.cpp src/timestamp.cpp src/mpack.cpp)
|
||||
add_library(common src/session_table.cpp src/packet.cpp src/control_packet.cpp src/bfd.cpp src/utils.cpp src/g_vxlan.cpp src/log.cpp src/timestamp.cpp src/mpack.cpp)
|
||||
target_link_libraries(common PUBLIC cjson)
|
||||
target_link_libraries(common PUBLIC MESA_handle_logger)
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#ifndef _DATA_PACKET_H
|
||||
#define _DATA_PACKET_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum layer_type
|
||||
{
|
||||
// 数据链路层
|
||||
LAYER_TYPE_ETHER = 1 << 0,
|
||||
LAYER_TYPE_PPP = 1 << 1,
|
||||
LAYER_TYPE_HDLC = 1 << 2,
|
||||
LAYER_TYPE_L2 = (LAYER_TYPE_ETHER | LAYER_TYPE_PPP | LAYER_TYPE_HDLC),
|
||||
|
||||
// 数据链路层 -- 隧道
|
||||
LAYER_TYPE_VLAN = 1 << 3,
|
||||
LAYER_TYPE_PPPOE = 1 << 4,
|
||||
LAYER_TYPE_MPLS = 1 << 5,
|
||||
LAYER_TYPE_L2_TUN = (LAYER_TYPE_VLAN | LAYER_TYPE_PPPOE | LAYER_TYPE_MPLS),
|
||||
|
||||
// 网络层
|
||||
LAYER_TYPE_IPV4 = 1 << 6,
|
||||
LAYER_TYPE_IPV6 = 1 << 7,
|
||||
LAYER_TYPE_L3 = (LAYER_TYPE_IPV4 | LAYER_TYPE_IPV6),
|
||||
|
||||
// 网络层 -- 隧道
|
||||
|
||||
// 传输层
|
||||
LAYER_TYPE_UDP = 1 << 8,
|
||||
LAYER_TYPE_TCP = 1 << 9,
|
||||
LAYER_TYPE_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP),
|
||||
|
||||
// 传输层 -- 隧道
|
||||
LAYER_TYPE_G_VXLAN = 1 << 10,
|
||||
LAYER_TYPE_GTPV1_U = 1 << 11,
|
||||
|
||||
// ALL
|
||||
LAYER_TYPE_ALL = (LAYER_TYPE_L2 | LAYER_TYPE_L2_TUN | LAYER_TYPE_L3 | LAYER_TYPE_L4 | LAYER_TYPE_G_VXLAN | LAYER_TYPE_GTPV1_U),
|
||||
|
||||
// UNKNOWN
|
||||
LAYER_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
enum ldbc_method
|
||||
{
|
||||
LDBC_METHOD_HASH_INT_IP = 1,
|
||||
LDBC_METHOD_HASH_EXT_IP = 2,
|
||||
LDBC_METHOD_HASH_INT_IP_AND_EXT_IP = 3,
|
||||
LDBC_METHOD_HASH_INNERMOST_INT_IP = 4,
|
||||
LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5,
|
||||
};
|
||||
|
||||
struct layer_result
|
||||
{
|
||||
uint16_t offset;
|
||||
enum layer_type type;
|
||||
};
|
||||
|
||||
struct data_packet
|
||||
{
|
||||
struct layer_result layers[16];
|
||||
uint16_t layers_used;
|
||||
uint16_t layers_size;
|
||||
|
||||
const void *data_ptr;
|
||||
uint64_t trace_id;
|
||||
};
|
||||
|
||||
// return innermost payload
|
||||
const void *data_packet_parse(struct data_packet *handler, const void *data, size_t length, uint64_t trace_id);
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_innermost_four_tuple(struct data_packet *handler, struct four_tuple *addr);
|
||||
int data_packet_get_outermost_four_tuple(struct data_packet *handler, struct four_tuple *addr);
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_innermost_address(struct data_packet *handler, struct four_tuple *addr);
|
||||
int data_packet_get_outermost_address(struct data_packet *handler, struct four_tuple *addr);
|
||||
|
||||
uint64_t data_packet_get_hash(struct data_packet *handler, enum ldbc_method method, int dir_is_i2e);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
#ifndef _FOUR_TUPLE_H
|
||||
#define _FOUR_TUPLE_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
enum addr_type
|
||||
{
|
||||
ADDR_TYPE_V4,
|
||||
ADDR_TYPE_V6,
|
||||
};
|
||||
|
||||
struct addr_v4
|
||||
{
|
||||
struct in_addr src_addr; /* network order */
|
||||
struct in_addr dst_addr; /* network order */
|
||||
};
|
||||
|
||||
struct addr_v6
|
||||
{
|
||||
struct in6_addr src_addr; /* network order */
|
||||
struct in6_addr dst_addr; /* network order */
|
||||
};
|
||||
|
||||
struct four_tuple
|
||||
{
|
||||
enum addr_type addr_type;
|
||||
in_port_t src_port; /* network order */
|
||||
in_port_t dst_port; /* network order */
|
||||
union
|
||||
{
|
||||
struct addr_v4 addr_v4;
|
||||
struct addr_v6 addr_v6;
|
||||
};
|
||||
};
|
||||
|
||||
#define INIT_ADDR_V4(name, src_addr_str, src_port_num, dst_addr_str, dst_port_num) \
|
||||
struct four_tuple name; \
|
||||
memset(&name, 0, sizeof(name)); \
|
||||
(name).addr_type = ADDR_TYPE_V4; \
|
||||
(name).src_port = htons((src_port_num)); \
|
||||
(name).dst_port = htons((dst_port_num)); \
|
||||
inet_pton(AF_INET, (src_addr_str), &(name).addr_v4.src_addr); \
|
||||
inet_pton(AF_INET, (dst_addr_str), &(name).addr_v4.dst_addr);
|
||||
|
||||
#define INIT_ADDR_V6(name, src_addr_str, src_port_num, dst_addr_str, dst_port_num) \
|
||||
struct four_tuple name; \
|
||||
memset(&name, 0, sizeof(name)); \
|
||||
(name).addr_type = ADDR_TYPE_V6; \
|
||||
(name).src_port = htons((src_port_num)); \
|
||||
(name).dst_port = htons((dst_port_num)); \
|
||||
inet_pton(AF_INET6, (src_addr_str), &(name).addr_v6.src_addr); \
|
||||
inet_pton(AF_INET6, (dst_addr_str), &(name).addr_v6.dst_addr);
|
||||
|
||||
void four_tuple_copy(struct four_tuple *dst, struct four_tuple *src);
|
||||
char *four_tuple_to_string(const struct four_tuple *addr);
|
||||
void four_tuple_reverse(const struct four_tuple *orin, struct four_tuple *out);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
108
common/include/packet.h
Normal file
108
common/include/packet.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef _PACKET_H
|
||||
#define _PACKET_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "tuple.h"
|
||||
|
||||
enum layer_type
|
||||
{
|
||||
// 数据链路层
|
||||
LAYER_TYPE_ETHER = 1 << 0,
|
||||
LAYER_TYPE_PPP = 1 << 1,
|
||||
LAYER_TYPE_HDLC = 1 << 2,
|
||||
LAYER_TYPE_L2 = (LAYER_TYPE_ETHER | LAYER_TYPE_PPP | LAYER_TYPE_HDLC),
|
||||
|
||||
// 数据链路层 -- 隧道
|
||||
LAYER_TYPE_VLAN = 1 << 3,
|
||||
LAYER_TYPE_PPPOE = 1 << 4,
|
||||
LAYER_TYPE_MPLS = 1 << 5,
|
||||
LAYER_TYPE_L2_TUN = (LAYER_TYPE_VLAN | LAYER_TYPE_PPPOE | LAYER_TYPE_MPLS),
|
||||
|
||||
// 网络层
|
||||
LAYER_TYPE_IPV4 = 1 << 6,
|
||||
LAYER_TYPE_IPV6 = 1 << 7,
|
||||
LAYER_TYPE_L3 = (LAYER_TYPE_IPV4 | LAYER_TYPE_IPV6),
|
||||
|
||||
// 网络层 -- 隧道
|
||||
LAYER_TYPE_GRE = 1 << 8,
|
||||
LAYER_TYPE_L3_TUN = (LAYER_TYPE_GRE),
|
||||
|
||||
// 传输层
|
||||
LAYER_TYPE_UDP = 1 << 9,
|
||||
LAYER_TYPE_TCP = 1 << 10,
|
||||
LAYER_TYPE_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP),
|
||||
|
||||
// 传输层 -- 隧道
|
||||
LAYER_TYPE_VXLAN = 1 << 11,
|
||||
LAYER_TYPE_GTPV1_U = 1 << 12,
|
||||
|
||||
// ALL
|
||||
LAYER_TYPE_ALL = (LAYER_TYPE_L2 | LAYER_TYPE_L2_TUN | LAYER_TYPE_L3 | LAYER_TYPE_L3_TUN | LAYER_TYPE_L4 | LAYER_TYPE_VXLAN | LAYER_TYPE_GTPV1_U),
|
||||
};
|
||||
|
||||
enum ldbc_method
|
||||
{
|
||||
LDBC_METHOD_HASH_INT_IP = 1,
|
||||
LDBC_METHOD_HASH_EXT_IP = 2,
|
||||
LDBC_METHOD_HASH_INT_IP_AND_EXT_IP = 3,
|
||||
LDBC_METHOD_HASH_INNERMOST_INT_IP = 4,
|
||||
LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5,
|
||||
};
|
||||
|
||||
struct layer_record
|
||||
{
|
||||
enum layer_type type;
|
||||
const char *hdr_ptr; // header pointer
|
||||
const char *pld_ptr; // payload pointer
|
||||
uint16_t hdr_offset; // header offset from data_ptr
|
||||
uint16_t hdr_len; // header length
|
||||
uint16_t pld_len; // payload length
|
||||
};
|
||||
|
||||
#define PACKET_MAX_LAYERS 16
|
||||
struct packet
|
||||
{
|
||||
struct layer_record layers[PACKET_MAX_LAYERS];
|
||||
int8_t layers_used;
|
||||
int8_t layers_size;
|
||||
|
||||
const char *data_ptr;
|
||||
uint16_t data_len;
|
||||
};
|
||||
|
||||
#define PACKET_LOG_ERROR(format, ...) void(0)
|
||||
#ifndef PACKET_LOG_ERROR
|
||||
#define PACKET_LOG_ERROR(format, ...) \
|
||||
fprintf(stderr, "ERROR " format "\n", ##__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
// return innermost payload
|
||||
const char *packet_parse(struct packet *handler, const char *data, uint16_t len);
|
||||
void packet_print(const struct packet *handler);
|
||||
|
||||
// return 0 : found
|
||||
// return -1 : not found
|
||||
int packet_get_innermost_four_tuple(const struct packet *handler, struct four_tuple *tuple);
|
||||
int packet_get_outermost_four_tuple(const struct packet *handler, struct four_tuple *tuple);
|
||||
|
||||
// return 0 : found
|
||||
// return -1 : not found
|
||||
int packet_get_innermost_two_tuple(const struct packet *handler, struct two_tuple *tuple);
|
||||
int packet_get_outermost_two_tuple(const struct packet *handler, struct two_tuple *tuple);
|
||||
|
||||
const struct layer_record *packet_get_innermost_layer(const struct packet *handler, enum layer_type type);
|
||||
const struct layer_record *packet_get_outermost_layer(const struct packet *handler, enum layer_type type);
|
||||
|
||||
uint64_t packet_get_hash(const struct packet *handler, enum ldbc_method method, int dir_is_i2e);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -10,7 +10,7 @@ extern "C"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "uthash.h"
|
||||
#include "four_tuple.h"
|
||||
#include "tuple.h"
|
||||
|
||||
// Note: session_addr must be initialized by memset(0) before use !!!
|
||||
|
||||
|
||||
356
common/include/tuple.h
Normal file
356
common/include/tuple.h
Normal file
@@ -0,0 +1,356 @@
|
||||
#ifndef _TUPLE_H
|
||||
#define _TUPLE_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
enum address_type
|
||||
{
|
||||
ADDR_TYPE_IPV4,
|
||||
ADDR_TYPE_IPV6,
|
||||
};
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
union ip_address
|
||||
{
|
||||
struct ipv4_address ipv4; /* network order */
|
||||
struct ipv6_address ipv6; /* network order */
|
||||
};
|
||||
|
||||
struct two_tuple
|
||||
{
|
||||
enum address_type type;
|
||||
union ip_address addr; /* network order */
|
||||
};
|
||||
|
||||
struct four_tuple
|
||||
{
|
||||
struct two_tuple two_tuple;
|
||||
|
||||
in_port_t src_port; /* network order */
|
||||
in_port_t dst_port; /* network order */
|
||||
};
|
||||
|
||||
#define SET_HUMAN_READABLE_IPV4_TUPLE(tuple, src_addr_str, src_port, dst_addr_str, dst_port) \
|
||||
do \
|
||||
{ \
|
||||
memset(tuple, 0, sizeof(struct four_tuple)); \
|
||||
two_tuple_set_ipv4_string(&(tuple)->two_tuple, src_addr_str, dst_addr_str); \
|
||||
four_tuple_set_port(tuple, htons(src_port), htons(dst_port)); \
|
||||
} while (0)
|
||||
|
||||
#define SET_HUMAN_READABLE_IPV6_TUPLE(tuple, src_addr_str, src_port, dst_addr_str, dst_port) \
|
||||
do \
|
||||
{ \
|
||||
memset(tuple, 0, sizeof(struct four_tuple)); \
|
||||
two_tuple_set_ipv6_string(&(tuple)->two_tuple, src_addr_str, dst_addr_str); \
|
||||
four_tuple_set_port(tuple, htons(src_port), htons(dst_port)); \
|
||||
} while (0)
|
||||
|
||||
/******************************************************************************
|
||||
* two tuple
|
||||
******************************************************************************/
|
||||
|
||||
inline void two_tuple_set_ipv4_string(struct two_tuple *tuple, const char *src, const char *dst)
|
||||
{
|
||||
memset(tuple, 0, sizeof(struct two_tuple));
|
||||
struct ipv4_address *ipv4 = &(tuple->addr.ipv4);
|
||||
tuple->type = ADDR_TYPE_IPV4;
|
||||
inet_pton(AF_INET, src, &ipv4->src);
|
||||
inet_pton(AF_INET, dst, &ipv4->dst);
|
||||
}
|
||||
|
||||
inline void two_tuple_set_ipv6_string(struct two_tuple *tuple, const char *src, const char *dst)
|
||||
{
|
||||
memset(tuple, 0, sizeof(struct two_tuple));
|
||||
struct ipv6_address *ipv6 = &(tuple->addr.ipv6);
|
||||
tuple->type = ADDR_TYPE_IPV6;
|
||||
inet_pton(AF_INET6, src, &ipv6->src);
|
||||
inet_pton(AF_INET6, dst, &ipv6->dst);
|
||||
}
|
||||
|
||||
inline void two_tuple_set_ipv4_address(struct two_tuple *tuple, const struct in_addr *src, const struct in_addr *dst)
|
||||
{
|
||||
memset(tuple, 0, sizeof(struct two_tuple));
|
||||
struct ipv4_address *ipv4 = &(tuple->addr.ipv4);
|
||||
tuple->type = ADDR_TYPE_IPV4;
|
||||
ipv4->src = *src;
|
||||
ipv4->dst = *dst;
|
||||
}
|
||||
|
||||
inline void two_tuple_set_ipv6_address(struct two_tuple *tuple, const struct in6_addr *src, const struct in6_addr *dst)
|
||||
{
|
||||
memset(tuple, 0, sizeof(struct two_tuple));
|
||||
struct ipv6_address *ipv6 = &(tuple->addr.ipv6);
|
||||
tuple->type = ADDR_TYPE_IPV6;
|
||||
ipv6->src = *src;
|
||||
ipv6->dst = *dst;
|
||||
}
|
||||
|
||||
inline int two_tuple_get_address_length(const struct two_tuple *tuple)
|
||||
{
|
||||
if (tuple->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
return sizeof(struct in_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sizeof(struct in6_addr);
|
||||
}
|
||||
}
|
||||
|
||||
inline const char *two_tuple_get_src_address(const struct two_tuple *tuple)
|
||||
{
|
||||
if (tuple->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
return (const char *)&(tuple->addr.ipv4.src);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (const char *)&(tuple->addr.ipv6.src);
|
||||
}
|
||||
}
|
||||
|
||||
inline const char *two_tuple_get_dst_address(const struct two_tuple *tuple)
|
||||
{
|
||||
if (tuple->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
return (const char *)&(tuple->addr.ipv4.dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (const char *)&(tuple->addr.ipv6.dst);
|
||||
}
|
||||
}
|
||||
|
||||
inline void two_tuple_copy(struct two_tuple *dst, const struct two_tuple *src)
|
||||
{
|
||||
memset(dst, 0, sizeof(struct two_tuple));
|
||||
dst->type = src->type;
|
||||
|
||||
if (src->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
dst->addr.ipv4 = src->addr.ipv4;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->addr.ipv6 = src->addr.ipv6;
|
||||
}
|
||||
}
|
||||
|
||||
inline int two_tuple_cmp(const struct two_tuple *tuple1, const struct two_tuple *tuple2)
|
||||
{
|
||||
if (tuple1->type != tuple2->type)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tuple1->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
if (memcmp(&(tuple1->addr.ipv4.src), &(tuple2->addr.ipv4.src), sizeof(struct in_addr)) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(&(tuple1->addr.ipv4.dst), &(tuple2->addr.ipv4.dst), sizeof(struct in_addr)) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memcmp(&(tuple1->addr.ipv6.src), &(tuple2->addr.ipv6.src), sizeof(struct in6_addr)) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(&(tuple1->addr.ipv6.dst), &(tuple2->addr.ipv6.dst), sizeof(struct in6_addr)) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void two_tuple_reverse(const struct two_tuple *orin, struct two_tuple *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct two_tuple));
|
||||
|
||||
if (orin->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
out->type = ADDR_TYPE_IPV4;
|
||||
struct ipv4_address *ipv4_out = &(out->addr.ipv4);
|
||||
const struct ipv4_address *ipv4_orin = &(orin->addr.ipv4);
|
||||
ipv4_out->src = ipv4_orin->dst;
|
||||
ipv4_out->dst = ipv4_orin->src;
|
||||
}
|
||||
|
||||
if (orin->type == ADDR_TYPE_IPV6)
|
||||
{
|
||||
out->type = ADDR_TYPE_IPV6;
|
||||
struct ipv6_address *ipv6_out = &(out->addr.ipv6);
|
||||
const struct ipv6_address *ipv6_orin = &(orin->addr.ipv6);
|
||||
ipv6_out->src = ipv6_orin->dst;
|
||||
ipv6_out->dst = ipv6_orin->src;
|
||||
}
|
||||
}
|
||||
|
||||
inline char *two_tuple_tostring(const struct two_tuple *tuple)
|
||||
{
|
||||
char *str_ret = NULL;
|
||||
|
||||
if (tuple->type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
char src[INET_ADDRSTRLEN] = {0};
|
||||
char dst[INET_ADDRSTRLEN] = {0};
|
||||
inet_ntop(AF_INET, &tuple->addr.ipv4.src, src, sizeof(src));
|
||||
inet_ntop(AF_INET, &tuple->addr.ipv4.dst, dst, sizeof(dst));
|
||||
asprintf(&str_ret, "%s %s", src, dst);
|
||||
}
|
||||
|
||||
if (tuple->type == ADDR_TYPE_IPV6)
|
||||
{
|
||||
char src[INET6_ADDRSTRLEN] = {0};
|
||||
char dst[INET6_ADDRSTRLEN] = {0};
|
||||
inet_ntop(AF_INET6, &tuple->addr.ipv6.src, src, sizeof(src));
|
||||
inet_ntop(AF_INET6, &tuple->addr.ipv6.dst, dst, sizeof(dst));
|
||||
asprintf(&str_ret, "%s %s", src, dst);
|
||||
}
|
||||
|
||||
return str_ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* four tuple
|
||||
******************************************************************************/
|
||||
|
||||
inline void four_tuple_set_ipv4_string(struct four_tuple *tuple, const char *src, const char *dst)
|
||||
{
|
||||
two_tuple_set_ipv4_string(&(tuple->two_tuple), src, dst);
|
||||
}
|
||||
|
||||
inline void four_tuple_set_ipv6_string(struct four_tuple *tuple, const char *src, const char *dst)
|
||||
{
|
||||
two_tuple_set_ipv6_string(&(tuple->two_tuple), src, dst);
|
||||
}
|
||||
|
||||
inline void four_tuple_set_ipv4_address(struct four_tuple *tuple, const struct in_addr *src, const struct in_addr *dst)
|
||||
{
|
||||
two_tuple_set_ipv4_address(&(tuple->two_tuple), src, dst);
|
||||
}
|
||||
|
||||
inline void four_tuple_set_ipv6_address(struct four_tuple *tuple, const struct in6_addr *src, const struct in6_addr *dst)
|
||||
{
|
||||
two_tuple_set_ipv6_address(&(tuple->two_tuple), src, dst);
|
||||
}
|
||||
|
||||
inline void four_tuple_set_port(struct four_tuple *tuple, const in_port_t src, const in_port_t dst)
|
||||
{
|
||||
tuple->src_port = 0;
|
||||
tuple->dst_port = 0;
|
||||
tuple->src_port = src;
|
||||
tuple->dst_port = dst;
|
||||
}
|
||||
|
||||
inline int four_tuple_get_address_length(const struct four_tuple *tuple)
|
||||
{
|
||||
return two_tuple_get_address_length(&(tuple->two_tuple));
|
||||
}
|
||||
|
||||
inline const char *four_tuple_get_src_address(const struct four_tuple *tuple)
|
||||
{
|
||||
return two_tuple_get_src_address(&(tuple->two_tuple));
|
||||
}
|
||||
|
||||
inline const char *four_tuple_get_dst_address(const struct four_tuple *tuple)
|
||||
{
|
||||
return two_tuple_get_dst_address(&(tuple->two_tuple));
|
||||
}
|
||||
|
||||
inline void four_tuple_copy(struct four_tuple *dst, const struct four_tuple *src)
|
||||
{
|
||||
memset(dst, 0, sizeof(struct four_tuple));
|
||||
two_tuple_copy(&(dst->two_tuple), &(src->two_tuple));
|
||||
dst->src_port = src->src_port;
|
||||
dst->dst_port = src->dst_port;
|
||||
}
|
||||
|
||||
inline int four_tuple_cmp(const struct four_tuple *tuple1, const struct four_tuple *tuple2)
|
||||
{
|
||||
if (tuple1->src_port != tuple2->src_port)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tuple1->dst_port != tuple2->dst_port)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return two_tuple_cmp(&(tuple1->two_tuple), &(tuple2->two_tuple));
|
||||
}
|
||||
|
||||
inline void four_tuple_reverse(const struct four_tuple *orin, struct four_tuple *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct four_tuple));
|
||||
|
||||
out->src_port = orin->dst_port;
|
||||
out->dst_port = orin->src_port;
|
||||
|
||||
two_tuple_reverse(&(orin->two_tuple), &(out->two_tuple));
|
||||
}
|
||||
|
||||
inline char *four_tuple_tostring(const struct four_tuple *tuple)
|
||||
{
|
||||
char *str_ret = NULL;
|
||||
|
||||
if (tuple->two_tuple.type == ADDR_TYPE_IPV4)
|
||||
{
|
||||
char src[INET_ADDRSTRLEN] = {0};
|
||||
char dst[INET_ADDRSTRLEN] = {0};
|
||||
uint16_t src_port = ntohs((uint16_t)tuple->src_port);
|
||||
uint16_t dst_port = ntohs((uint16_t)tuple->dst_port);
|
||||
inet_ntop(AF_INET, &tuple->two_tuple.addr.ipv4.src, src, sizeof(src));
|
||||
inet_ntop(AF_INET, &tuple->two_tuple.addr.ipv4.dst, dst, sizeof(dst));
|
||||
asprintf(&str_ret, "%s %u %s %u", src, src_port, dst, dst_port);
|
||||
}
|
||||
|
||||
if (tuple->two_tuple.type == ADDR_TYPE_IPV6)
|
||||
{
|
||||
char src[INET6_ADDRSTRLEN] = {0};
|
||||
char dst[INET6_ADDRSTRLEN] = {0};
|
||||
uint16_t src_port = ntohs((uint16_t)tuple->src_port);
|
||||
uint16_t dst_port = ntohs((uint16_t)tuple->dst_port);
|
||||
inet_ntop(AF_INET6, &tuple->two_tuple.addr.ipv6.src, src, sizeof(src));
|
||||
inet_ntop(AF_INET6, &tuple->two_tuple.addr.ipv6.dst, dst, sizeof(dst));
|
||||
asprintf(&str_ret, "%s %u %s %u", src, src_port, dst, dst_port);
|
||||
}
|
||||
|
||||
return str_ret;
|
||||
}
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,955 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#define __FAVOR_BSD 1
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <linux/ppp_defs.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
#include "uthash.h"
|
||||
#include "four_tuple.h"
|
||||
#include "data_packet.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Struct
|
||||
******************************************************************************/
|
||||
|
||||
struct vlan_hdr
|
||||
{
|
||||
uint16_t vlan_cfi;
|
||||
uint16_t protocol;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct vxlan_hdr
|
||||
{
|
||||
uint8_t flags[2];
|
||||
uint16_t gdp; // group policy id
|
||||
uint8_t vni[3];
|
||||
uint8_t reserved;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct gtp_hdr
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned char flags;
|
||||
unsigned char msg_type;
|
||||
unsigned short len;
|
||||
unsigned int teid;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int teid;
|
||||
unsigned short len;
|
||||
unsigned char msg_type;
|
||||
unsigned char flags;
|
||||
#else
|
||||
#error "Please check <endian.h>"
|
||||
#endif
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define GTP_HDR_VER_MASK (0xE0)
|
||||
#define GTP_HDR_FLAG_N_PDU (0x01)
|
||||
#define GTP_HDR_FLAG_SEQ_NUM (0x02)
|
||||
#define GTP_HDR_FLAG_NEXT_EXT_HDR (0x04)
|
||||
|
||||
/******************************************************************************
|
||||
* Static API
|
||||
******************************************************************************/
|
||||
|
||||
static const char *ldbc_method_to_string(enum ldbc_method ldbc_method);
|
||||
static const char *layer_type_to_string(enum layer_type this_type);
|
||||
static int data_packet_push_layer(struct data_packet *handler, enum layer_type type, uint16_t offset);
|
||||
static void populate_four_tuple_from_layer(const void *data, enum layer_type layer_type, struct four_tuple *addr);
|
||||
|
||||
// parser protocol
|
||||
static uint16_t parse_gtphdr_len(const struct gtp_hdr *gtph);
|
||||
static const void *parse_ether(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_ipv4(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_ipv6(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_tcp(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_udp(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_pppoe_ses(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_vxlan(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_vlan8021q(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_gtpv1_u(struct data_packet *handler, const void *data, size_t length);
|
||||
static const void *parse_mpls(struct data_packet *handler, const void *data, size_t length);
|
||||
|
||||
/******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
// return innermost payload
|
||||
const void *data_packet_parse(struct data_packet *handler, const void *data, size_t length, uint64_t trace_id)
|
||||
{
|
||||
memset(handler, 0, sizeof(struct data_packet));
|
||||
|
||||
handler->layers_used = 0;
|
||||
handler->layers_size = sizeof(handler->layers) / sizeof(handler->layers[0]);
|
||||
handler->data_ptr = data;
|
||||
handler->trace_id = trace_id;
|
||||
|
||||
// TESTED
|
||||
return parse_ether(handler, data, length);
|
||||
}
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_innermost_four_tuple(struct data_packet *handler, struct four_tuple *addr)
|
||||
{
|
||||
const char *l3_layer_data = NULL;
|
||||
const char *l4_layer_data = NULL;
|
||||
const struct layer_result *l3_layer_result = NULL;
|
||||
const struct layer_result *l4_layer_result = NULL;
|
||||
|
||||
// search L4 layer and L3 layer in reverse order
|
||||
for (int8_t i = handler->layers_used - 1; i >= 0; i--)
|
||||
{
|
||||
const struct layer_result *layer = &handler->layers[i];
|
||||
enum layer_type type = layer->type;
|
||||
|
||||
LOG_DEBUG("%s: find innermost tuple4, trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->trace_id, i, handler->layers_size, layer_type_to_string(type));
|
||||
|
||||
// first get L4 layer
|
||||
if (type & LAYER_TYPE_L4)
|
||||
{
|
||||
l4_layer_result = layer;
|
||||
continue;
|
||||
}
|
||||
|
||||
// second get L3 layer
|
||||
if (type & LAYER_TYPE_L3)
|
||||
{
|
||||
l3_layer_result = layer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (l3_layer_result)
|
||||
{
|
||||
l3_layer_data = (const char *)handler->data_ptr + l3_layer_result->offset;
|
||||
populate_four_tuple_from_layer(l3_layer_data, l3_layer_result->type, addr);
|
||||
}
|
||||
|
||||
if (l4_layer_result)
|
||||
{
|
||||
l4_layer_data = (const char *)handler->data_ptr + l4_layer_result->offset;
|
||||
populate_four_tuple_from_layer(l4_layer_data, l4_layer_result->type, addr);
|
||||
}
|
||||
|
||||
if (l3_layer_result && l4_layer_result)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_outermost_four_tuple(struct data_packet *handler, struct four_tuple *addr)
|
||||
{
|
||||
const char *l3_layer_data = NULL;
|
||||
const char *l4_layer_data = NULL;
|
||||
const struct layer_result *l3_layer_result = NULL;
|
||||
const struct layer_result *l4_layer_result = NULL;
|
||||
|
||||
// search L3 layer and L4 layer in order
|
||||
for (int8_t i = 0; i <= handler->layers_used - 1; i++)
|
||||
{
|
||||
const struct layer_result *layer = &handler->layers[i];
|
||||
enum layer_type type = layer->type;
|
||||
|
||||
LOG_DEBUG("%s: find outermost tuple4, trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->trace_id, i, handler->layers_size, layer_type_to_string(type));
|
||||
|
||||
// first get L3 layer
|
||||
if (type & LAYER_TYPE_L3)
|
||||
{
|
||||
l3_layer_result = layer;
|
||||
continue;
|
||||
}
|
||||
|
||||
// second get L4 layer
|
||||
if (type & LAYER_TYPE_L4)
|
||||
{
|
||||
l4_layer_result = layer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (l3_layer_result)
|
||||
{
|
||||
l3_layer_data = (const char *)handler->data_ptr + l3_layer_result->offset;
|
||||
populate_four_tuple_from_layer(l3_layer_data, l3_layer_result->type, addr);
|
||||
}
|
||||
|
||||
if (l4_layer_result)
|
||||
{
|
||||
l4_layer_data = (const char *)handler->data_ptr + l4_layer_result->offset;
|
||||
populate_four_tuple_from_layer(l4_layer_data, l4_layer_result->type, addr);
|
||||
}
|
||||
|
||||
if (l3_layer_result && l4_layer_result)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_innermost_address(struct data_packet *handler, struct four_tuple *addr)
|
||||
{
|
||||
const char *l3_layer_data = NULL;
|
||||
|
||||
// search L3 layer in reverse order
|
||||
for (int8_t i = handler->layers_used - 1; i >= 0; i--)
|
||||
{
|
||||
const struct layer_result *layer = &handler->layers[i];
|
||||
enum layer_type type = layer->type;
|
||||
|
||||
LOG_DEBUG("%s: find innermost address, trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->trace_id, i, handler->layers_size, layer_type_to_string(type));
|
||||
if (type & LAYER_TYPE_L3)
|
||||
{
|
||||
l3_layer_data = (const char *)handler->data_ptr + layer->offset;
|
||||
populate_four_tuple_from_layer(l3_layer_data, type, addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int data_packet_get_outermost_address(struct data_packet *handler, struct four_tuple *addr)
|
||||
{
|
||||
const char *l3_layer_data = NULL;
|
||||
|
||||
// search L3 layer in order
|
||||
for (int8_t i = 0; i <= handler->layers_used - 1; i++)
|
||||
{
|
||||
const struct layer_result *layer = &handler->layers[i];
|
||||
enum layer_type type = layer->type;
|
||||
|
||||
LOG_DEBUG("%s: find outermost address, trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->trace_id, i, handler->layers_size, layer_type_to_string(type));
|
||||
if (type & LAYER_TYPE_L3)
|
||||
{
|
||||
l3_layer_data = (const char *)handler->data_ptr + layer->offset;
|
||||
populate_four_tuple_from_layer(l3_layer_data, type, addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t data_packet_get_hash(struct data_packet *handler, enum ldbc_method method, int dir_is_i2e)
|
||||
{
|
||||
uint64_t temp = 0;
|
||||
uint64_t hash_value = 1;
|
||||
|
||||
int inner_addr_len = 0;
|
||||
int outer_addr_len = 0;
|
||||
const char *inner_src_addr = NULL;
|
||||
const char *inner_dst_addr = NULL;
|
||||
const char *outer_src_addr = NULL;
|
||||
const char *outer_dst_addr = NULL;
|
||||
|
||||
struct four_tuple inner_addr;
|
||||
struct four_tuple outer_addr;
|
||||
memset(&inner_addr, 0, sizeof(inner_addr));
|
||||
memset(&outer_addr, 0, sizeof(outer_addr));
|
||||
|
||||
if (handler == NULL)
|
||||
{
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
if (data_packet_get_innermost_address(handler, &inner_addr) == -1)
|
||||
{
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
if (data_packet_get_outermost_address(handler, &outer_addr) == -1)
|
||||
{
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
if (inner_addr.addr_type == ADDR_TYPE_V4)
|
||||
{
|
||||
inner_src_addr = (const char *)&(inner_addr.addr_v4.src_addr);
|
||||
inner_dst_addr = (const char *)&(inner_addr.addr_v4.dst_addr);
|
||||
inner_addr_len = sizeof(inner_addr.addr_v4.dst_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
inner_src_addr = (const char *)&(inner_addr.addr_v6.src_addr);
|
||||
inner_dst_addr = (const char *)&(inner_addr.addr_v6.dst_addr);
|
||||
inner_addr_len = sizeof(inner_addr.addr_v6.dst_addr);
|
||||
}
|
||||
|
||||
if (outer_addr.addr_type == ADDR_TYPE_V4)
|
||||
{
|
||||
outer_src_addr = (const char *)&(outer_addr.addr_v4.src_addr);
|
||||
outer_dst_addr = (const char *)&(outer_addr.addr_v4.dst_addr);
|
||||
outer_addr_len = sizeof(outer_addr.addr_v4.dst_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
outer_src_addr = (const char *)&(outer_addr.addr_v6.src_addr);
|
||||
outer_dst_addr = (const char *)&(outer_addr.addr_v6.dst_addr);
|
||||
outer_addr_len = sizeof(outer_addr.addr_v6.dst_addr);
|
||||
}
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case LDBC_METHOD_HASH_INT_IP:
|
||||
if (dir_is_i2e)
|
||||
{
|
||||
// outer src ip
|
||||
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// outer dst ip
|
||||
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
|
||||
}
|
||||
break;
|
||||
case LDBC_METHOD_HASH_EXT_IP:
|
||||
if (dir_is_i2e)
|
||||
{
|
||||
// outer dst ip
|
||||
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// outer src ip
|
||||
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
|
||||
}
|
||||
break;
|
||||
case LDBC_METHOD_HASH_INT_IP_AND_EXT_IP:
|
||||
// outer dst ip ^ outer src ip
|
||||
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
|
||||
HASH_VALUE(outer_dst_addr, outer_addr_len, temp);
|
||||
hash_value = hash_value ^ temp;
|
||||
break;
|
||||
case LDBC_METHOD_HASH_INNERMOST_INT_IP:
|
||||
if (dir_is_i2e)
|
||||
{
|
||||
// innner src ip
|
||||
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// innner dst ip
|
||||
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
|
||||
}
|
||||
break;
|
||||
case LDBC_METHOD_HASH_INNERMOST_EXT_IP:
|
||||
if (dir_is_i2e)
|
||||
{
|
||||
// innner dst ip
|
||||
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// innner src ip
|
||||
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
char *inner_addr_str = four_tuple_to_string(&inner_addr);
|
||||
char *outer_addr_str = four_tuple_to_string(&outer_addr);
|
||||
LOG_DEBUG("%s: trace_id: %lu, outer_addr: %s, inner_addr: %s, is_internal: %d, hash_method: %s, hash_value: %lu",
|
||||
LOG_TAG_RAWPKT, handler->trace_id, outer_addr_str, inner_addr_str, dir_is_i2e, ldbc_method_to_string(method), hash_value);
|
||||
free(inner_addr_str);
|
||||
free(outer_addr_str);
|
||||
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private API
|
||||
******************************************************************************/
|
||||
|
||||
static const char *ldbc_method_to_string(enum ldbc_method ldbc_method)
|
||||
{
|
||||
switch (ldbc_method)
|
||||
{
|
||||
case LDBC_METHOD_HASH_INT_IP:
|
||||
return "outter_internal_ip";
|
||||
case LDBC_METHOD_HASH_EXT_IP:
|
||||
return "outter_external_ip";
|
||||
case LDBC_METHOD_HASH_INT_IP_AND_EXT_IP:
|
||||
return "outter_internal_ip_and_external_ip";
|
||||
case LDBC_METHOD_HASH_INNERMOST_INT_IP:
|
||||
return "inner_internal_ip";
|
||||
case LDBC_METHOD_HASH_INNERMOST_EXT_IP:
|
||||
return "inner_external_ip";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *layer_type_to_string(enum layer_type this_type)
|
||||
{
|
||||
switch (this_type)
|
||||
{
|
||||
case LAYER_TYPE_ETHER:
|
||||
return "ETHER";
|
||||
case LAYER_TYPE_PPP:
|
||||
return "PPP";
|
||||
case LAYER_TYPE_HDLC:
|
||||
return "HDLC";
|
||||
case LAYER_TYPE_VLAN:
|
||||
return "VLAN";
|
||||
case LAYER_TYPE_PPPOE:
|
||||
return "PPPOE";
|
||||
case LAYER_TYPE_MPLS:
|
||||
return "MPLS";
|
||||
case LAYER_TYPE_IPV4:
|
||||
return "IPV4";
|
||||
case LAYER_TYPE_IPV6:
|
||||
return "IPV6";
|
||||
case LAYER_TYPE_UDP:
|
||||
return "UDP";
|
||||
case LAYER_TYPE_TCP:
|
||||
return "TCP";
|
||||
case LAYER_TYPE_G_VXLAN:
|
||||
return "G_VXLAN";
|
||||
case LAYER_TYPE_GTPV1_U:
|
||||
return "GTPV1_U";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static int data_packet_push_layer(struct data_packet *handler, enum layer_type type, uint16_t offset)
|
||||
{
|
||||
if (handler->layers_used >= handler->layers_size)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
handler->layers[handler->layers_used].offset = offset;
|
||||
handler->layers[handler->layers_used].type = type;
|
||||
handler->layers_used++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void populate_four_tuple_from_layer(const void *data, enum layer_type layer_type, struct four_tuple *addr)
|
||||
{
|
||||
const struct tcphdr *tcp_hdr = NULL;
|
||||
const struct udp_hdr *udp_hdr = NULL;
|
||||
const struct ip *ipv4_hdr = NULL;
|
||||
const struct ip6_hdr *ipv6_hdr = NULL;
|
||||
|
||||
switch (layer_type)
|
||||
{
|
||||
case LAYER_TYPE_TCP:
|
||||
tcp_hdr = (const struct tcphdr *)data;
|
||||
addr->src_port = tcp_hdr->th_sport;
|
||||
addr->dst_port = tcp_hdr->th_dport;
|
||||
break;
|
||||
case LAYER_TYPE_UDP:
|
||||
udp_hdr = (const struct udp_hdr *)data;
|
||||
addr->src_port = udp_hdr->uh_sport;
|
||||
addr->dst_port = udp_hdr->uh_dport;
|
||||
break;
|
||||
case LAYER_TYPE_IPV4:
|
||||
ipv4_hdr = (const struct ip *)data;
|
||||
addr->addr_type = ADDR_TYPE_V4;
|
||||
addr->addr_v4.src_addr = ipv4_hdr->ip_src;
|
||||
addr->addr_v4.dst_addr = ipv4_hdr->ip_dst;
|
||||
break;
|
||||
case LAYER_TYPE_IPV6:
|
||||
ipv6_hdr = (const struct ip6_hdr *)data;
|
||||
addr->addr_type = ADDR_TYPE_V6;
|
||||
memcpy(&addr->addr_v6.src_addr, &ipv6_hdr->ip6_src, sizeof(addr->addr_v6.src_addr));
|
||||
memcpy(&addr->addr_v6.dst_addr, &ipv6_hdr->ip6_dst, sizeof(addr->addr_v6.dst_addr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FROM SAPP
|
||||
static uint16_t parse_gtphdr_len(const struct gtp_hdr *gtph)
|
||||
{
|
||||
const unsigned char *p_ext_hdr = (unsigned char *)gtph + sizeof(struct gtp_hdr);
|
||||
unsigned char next_hdr_type;
|
||||
unsigned char this_ext_field_cont_len;
|
||||
|
||||
// v0 太古老已废弃,目前仅支持 GTPv1 版本
|
||||
if (((gtph->flags & GTP_HDR_VER_MASK) >> 5) != 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gtph->flags & (GTP_HDR_FLAG_SEQ_NUM | GTP_HDR_FLAG_N_PDU | GTP_HDR_FLAG_NEXT_EXT_HDR))
|
||||
{
|
||||
// skip seq field (2 bytes)
|
||||
p_ext_hdr += 2;
|
||||
|
||||
// skip N-PDU field (1 byte)
|
||||
p_ext_hdr++;
|
||||
|
||||
// 解析 GTP 扩展头部字段,参考 wireshark 源码 packet-gtp.c->dissect_gtp_common()
|
||||
next_hdr_type = *p_ext_hdr;
|
||||
if (gtph->flags & GTP_HDR_FLAG_NEXT_EXT_HDR)
|
||||
{
|
||||
while (next_hdr_type != 0)
|
||||
{
|
||||
// 指向长度字段, 以4个字节为单位
|
||||
p_ext_hdr++;
|
||||
this_ext_field_cont_len = *p_ext_hdr * 4 - 2;
|
||||
|
||||
// 指向数据部分第一个字节
|
||||
p_ext_hdr++;
|
||||
p_ext_hdr += this_ext_field_cont_len;
|
||||
|
||||
// 指向下一个头部字段
|
||||
next_hdr_type = *p_ext_hdr;
|
||||
p_ext_hdr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_ext_hdr++;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *)p_ext_hdr - (char *)gtph;
|
||||
}
|
||||
|
||||
static const void *parse_ether(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct ethhdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_ETHER));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_ETHER, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct ethhdr *hdr = (struct ethhdr *)data;
|
||||
uint16_t next_proto = ntohs(hdr->h_proto);
|
||||
uint16_t hdr_len = sizeof(struct ethhdr);
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_ETHER), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
case ETH_P_8021Q:
|
||||
case ETH_P_8021AD:
|
||||
// TESTED
|
||||
return parse_vlan8021q(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_IP:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_IPV6:
|
||||
// TESTED
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_PPP_SES:
|
||||
// TODO
|
||||
return parse_pppoe_ses(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_MPLS_UC:
|
||||
// TESTED
|
||||
return parse_mpls(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_ETHER), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_ipv4(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct ip))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV4));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_IPV4, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct ip *hdr = (struct ip *)data;
|
||||
uint16_t next_proto = hdr->ip_p;
|
||||
uint16_t hdr_len = (hdr->ip_hl & 0xf) * 4u;
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV4), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
// TESTED
|
||||
return parse_tcp(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_UDP:
|
||||
// TESTED
|
||||
return parse_udp(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_IPIP:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_IPV6:
|
||||
// TESTED
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV4), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_ipv6(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct ip6_hdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV6));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_IPV6, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct ip6_hdr *hdr = (struct ip6_hdr *)data;
|
||||
uint16_t next_proto = hdr->ip6_nxt;
|
||||
uint16_t hdr_len = sizeof(struct ip6_hdr);
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV6), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
// TESTED
|
||||
return parse_tcp(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_UDP:
|
||||
// TESTED
|
||||
return parse_udp(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_IPIP:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
case IPPROTO_IPV6:
|
||||
// TESTED
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_IPV6), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_tcp(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct tcphdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_TCP));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_TCP, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct tcphdr *hdr = (struct tcphdr *)data;
|
||||
uint16_t hdr_len = hdr->th_off << 2;
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_TCP), data_next_length, length);
|
||||
|
||||
return data_next_layer;
|
||||
}
|
||||
|
||||
static const void *parse_udp(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct udp_hdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_UDP));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_UDP, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct udp_hdr *hdr = (struct udp_hdr *)data;
|
||||
uint16_t hdr_len = sizeof(struct udp_hdr);
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_UDP), data_next_length, length);
|
||||
switch (ntohs(hdr->uh_dport))
|
||||
{
|
||||
// VXLAN_DPORT
|
||||
case 4789:
|
||||
// TESTED
|
||||
return parse_vxlan(handler, data_next_layer, data_next_length);
|
||||
// GTP1U_PORT
|
||||
case 2152:
|
||||
// TESTED
|
||||
return parse_gtpv1_u(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_pppoe_ses(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < 8)
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_PPPOE));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_PPPOE, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t next_proto = *((uint16_t *)data + 3);
|
||||
uint16_t hdr_len = 8;
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_PPPOE), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
// PPPOE_TYPE_IPV4
|
||||
case 0x2100:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
// PPPOE_TYPE_IPV6
|
||||
case 0x5700:
|
||||
// TODO
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_PPPOE), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_vxlan(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct vxlan_hdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_G_VXLAN));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_G_VXLAN, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
// struct vxlan_hdr *vxlan_hdr = (struct vxlan_hdr *)data;
|
||||
uint16_t hdr_len = sizeof(struct vxlan_hdr);
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_G_VXLAN), data_next_length, length);
|
||||
// TESTED
|
||||
return parse_ether(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
|
||||
static const void *parse_vlan8021q(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct vlan_hdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_VLAN));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_VLAN, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
struct vlan_hdr *hdr = (struct vlan_hdr *)data;
|
||||
uint16_t next_proto = ntohs(hdr->protocol);
|
||||
uint16_t hdr_len = sizeof(struct vlan_hdr);
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_VLAN), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
case ETH_P_8021Q:
|
||||
// TESTED
|
||||
return parse_vlan8021q(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_IP:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_IPV6:
|
||||
// TODO
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_PPP_SES:
|
||||
// TESTED
|
||||
return parse_pppoe_ses(handler, data_next_layer, data_next_length);
|
||||
case ETH_P_MPLS_UC:
|
||||
// TODO
|
||||
return parse_mpls(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_VLAN), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_gtpv1_u(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < sizeof(struct gtp_hdr))
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_GTPV1_U));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t hdr_len = parse_gtphdr_len((const struct gtp_hdr *)data);
|
||||
if (hdr_len < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_GTPV1_U, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t next_proto = (((const uint8_t *)((const char *)data + hdr_len))[0]) >> 4;
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_GTPV1_U), data_next_length, length);
|
||||
switch (next_proto)
|
||||
{
|
||||
case 4:
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
case 6:
|
||||
// TESTED
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
default:
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_GTPV1_U), next_proto);
|
||||
return data_next_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static const void *parse_mpls(struct data_packet *handler, const void *data, size_t length)
|
||||
{
|
||||
if (length < 4)
|
||||
{
|
||||
LOG_ERROR("%s: trace_id: %lu, %s, err: data not enough", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS));
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->data_ptr);
|
||||
if (data_packet_push_layer(handler, LAYER_TYPE_MPLS, offset) < 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
#define MPLS_LABEL_MASK (0xFFFFF000)
|
||||
#define MPLS_EXP_MASK (0x00000E00)
|
||||
#define MPLS_BLS_MASK (0x00000100)
|
||||
#define MPLS_TTL_MASK (0x000000FF)
|
||||
|
||||
/*
|
||||
* MPLS Format
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Label | Exp |S| TTL |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* Label : Label Value 20 bits
|
||||
* Exp : Experimental Use 3 bits
|
||||
* S : Bottom of Stack 1 bit
|
||||
* TTL : Time to Live 8 bits
|
||||
*/
|
||||
|
||||
uint32_t *hdr = (uint32_t *)data;
|
||||
// unsigned int mpls_label = (ntohl(*hdr) & MPLS_LABEL_MASK) >> 12;
|
||||
// unsigned int mpls_exp = (ntohl(*hdr) & MPLS_EXP_MASK) >> 9;
|
||||
unsigned int mpls_bls = (ntohl(*hdr) & MPLS_BLS_MASK) >> 8;
|
||||
// unsigned int mpls_ttl = (ntohl(*hdr) & MPLS_TTL_MASK);
|
||||
|
||||
uint16_t hdr_len = 4;
|
||||
const void *data_next_layer = (const char *)data + hdr_len;
|
||||
size_t data_next_length = length - hdr_len;
|
||||
|
||||
if (mpls_bls == 1)
|
||||
{
|
||||
uint8_t ip_version = (((uint8_t *)data_next_layer)[0]) >> 4;
|
||||
if (ip_version == 0)
|
||||
{
|
||||
/*
|
||||
* PW Ethernet Control Word
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |0 0 0 0| Reserved | Sequence Number |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* Reference: https://tools.ietf.org/html/rfc4448
|
||||
*/
|
||||
data_next_layer = (const char *)data_next_layer + 4;
|
||||
data_next_length = data_next_length - 4;
|
||||
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS), data_next_length, length);
|
||||
// TESTED
|
||||
return parse_ether(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
else if (ip_version == 4)
|
||||
{
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS), data_next_length, length);
|
||||
// TESTED
|
||||
return parse_ipv4(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
else if (ip_version == 6)
|
||||
{
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS), data_next_length, length);
|
||||
// TODO
|
||||
return parse_ipv6(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS), data_next_length, length);
|
||||
// TODO
|
||||
return parse_ether(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("%s: trace_id: %lu, %s->payload: [%lu/%lu]", LOG_TAG_RAWPKT, handler->trace_id, layer_type_to_string(LAYER_TYPE_MPLS), data_next_length, length);
|
||||
// TESTED
|
||||
return parse_mpls(handler, data_next_layer, data_next_length);
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "four_tuple.h"
|
||||
|
||||
void four_tuple_copy(struct four_tuple *dst, struct four_tuple *src)
|
||||
{
|
||||
dst->addr_type = src->addr_type;
|
||||
dst->src_port = src->src_port;
|
||||
dst->dst_port = src->dst_port;
|
||||
|
||||
if (src->addr_type == ADDR_TYPE_V4)
|
||||
{
|
||||
memcpy(&(dst->addr_v4.src_addr), &(src->addr_v4.src_addr), sizeof(struct in_addr));
|
||||
memcpy(&(dst->addr_v4.dst_addr), &(src->addr_v4.dst_addr), sizeof(struct in_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&(dst->addr_v6.src_addr), &(src->addr_v6.src_addr), sizeof(struct addr_v6));
|
||||
memcpy(&(dst->addr_v6.dst_addr), &(src->addr_v6.dst_addr), sizeof(struct addr_v6));
|
||||
}
|
||||
}
|
||||
|
||||
char *four_tuple_to_string(const struct four_tuple *addr)
|
||||
{
|
||||
char *str_ret = NULL;
|
||||
|
||||
if (addr->addr_type == ADDR_TYPE_V4)
|
||||
{
|
||||
char src_addr[INET_ADDRSTRLEN] = {0};
|
||||
char dst_addr[INET_ADDRSTRLEN] = {0};
|
||||
uint16_t src_port = ntohs((uint16_t)addr->src_port);
|
||||
uint16_t dst_port = ntohs((uint16_t)addr->dst_port);
|
||||
inet_ntop(AF_INET, &addr->addr_v4.src_addr, src_addr, sizeof(src_addr));
|
||||
inet_ntop(AF_INET, &addr->addr_v4.dst_addr, dst_addr, sizeof(dst_addr));
|
||||
asprintf(&str_ret, "%s %u %s %u", src_addr, src_port, dst_addr, dst_port);
|
||||
}
|
||||
|
||||
if (addr->addr_type == ADDR_TYPE_V6)
|
||||
{
|
||||
char src_addr[INET6_ADDRSTRLEN] = {0};
|
||||
char dst_addr[INET6_ADDRSTRLEN] = {0};
|
||||
uint16_t src_port = ntohs((uint16_t)addr->src_port);
|
||||
uint16_t dst_port = ntohs((uint16_t)addr->dst_port);
|
||||
inet_ntop(AF_INET6, &addr->addr_v6.src_addr, src_addr, sizeof(src_addr));
|
||||
inet_ntop(AF_INET6, &addr->addr_v6.dst_addr, dst_addr, sizeof(dst_addr));
|
||||
asprintf(&str_ret, "%s %u %s %u", src_addr, src_port, dst_addr, dst_port);
|
||||
}
|
||||
|
||||
return str_ret;
|
||||
}
|
||||
|
||||
void four_tuple_reverse(const struct four_tuple *orin, struct four_tuple *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct four_tuple));
|
||||
|
||||
if (orin->addr_type == ADDR_TYPE_V4)
|
||||
{
|
||||
out->addr_type = ADDR_TYPE_V4;
|
||||
out->addr_v4.src_addr = orin->addr_v4.dst_addr;
|
||||
out->addr_v4.dst_addr = orin->addr_v4.src_addr;
|
||||
out->src_port = orin->dst_port;
|
||||
out->dst_port = orin->src_port;
|
||||
}
|
||||
|
||||
if (orin->addr_type == ADDR_TYPE_V6)
|
||||
{
|
||||
out->addr_type = ADDR_TYPE_V6;
|
||||
out->addr_v6.src_addr = orin->addr_v6.dst_addr;
|
||||
out->addr_v6.dst_addr = orin->addr_v6.src_addr;
|
||||
out->src_port = orin->dst_port;
|
||||
out->dst_port = orin->src_port;
|
||||
}
|
||||
}
|
||||
1274
common/src/packet.cpp
Normal file
1274
common/src/packet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest_four_tuple
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_four_tuple gtest_four_tuple.cpp)
|
||||
target_include_directories(gtest_four_tuple PUBLIC ${CMAKE_SOURCE_DIR}/common/include)
|
||||
target_link_libraries(gtest_four_tuple common gtest)
|
||||
|
||||
###############################################################################
|
||||
# gtest_session_table
|
||||
###############################################################################
|
||||
@@ -14,14 +6,6 @@ add_executable(gtest_session_table gtest_session_table.cpp)
|
||||
target_include_directories(gtest_session_table PUBLIC ${CMAKE_SOURCE_DIR}/common/include)
|
||||
target_link_libraries(gtest_session_table common gtest)
|
||||
|
||||
###############################################################################
|
||||
# gtest_data_packet
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_data_packet gtest_data_packet.cpp)
|
||||
target_include_directories(gtest_data_packet PUBLIC ${CMAKE_SOURCE_DIR}/common/include)
|
||||
target_link_libraries(gtest_data_packet common gtest)
|
||||
|
||||
###############################################################################
|
||||
# gtest_control_packet
|
||||
###############################################################################
|
||||
@@ -51,9 +35,7 @@ target_link_libraries(gtest_health_check_table common gtest platform)
|
||||
###############################################################################
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(gtest_four_tuple)
|
||||
gtest_discover_tests(gtest_session_table)
|
||||
gtest_discover_tests(gtest_data_packet)
|
||||
gtest_discover_tests(gtest_control_packet)
|
||||
gtest_discover_tests(gtest_utils)
|
||||
gtest_discover_tests(gtest_health_check_table)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "four_tuple.h"
|
||||
|
||||
TEST(ADDR_TUPLE4, IPV4)
|
||||
{
|
||||
char *ret_str = NULL;
|
||||
struct four_tuple reve_addr;
|
||||
|
||||
INIT_ADDR_V4(orin_addr, "1.2.3.4", 12345, "4.3.2.1", 23456)
|
||||
four_tuple_reverse(&orin_addr, &reve_addr);
|
||||
|
||||
ret_str = four_tuple_to_string(&orin_addr);
|
||||
EXPECT_TRUE(ret_str != nullptr);
|
||||
EXPECT_STREQ(ret_str, "1.2.3.4 12345 4.3.2.1 23456");
|
||||
free(ret_str);
|
||||
|
||||
ret_str = four_tuple_to_string(&reve_addr);
|
||||
EXPECT_TRUE(ret_str != nullptr);
|
||||
EXPECT_STREQ(ret_str, "4.3.2.1 23456 1.2.3.4 12345");
|
||||
free(ret_str);
|
||||
}
|
||||
|
||||
TEST(ADDR_TUPLE4, IPV6)
|
||||
{
|
||||
char *ret_str = NULL;
|
||||
struct four_tuple reve_addr;
|
||||
|
||||
INIT_ADDR_V6(orin_addr, "1:2::3", 12345, "a:b::c", 23456);
|
||||
four_tuple_reverse(&orin_addr, &reve_addr);
|
||||
|
||||
ret_str = four_tuple_to_string(&orin_addr);
|
||||
EXPECT_TRUE(ret_str != nullptr);
|
||||
EXPECT_STREQ(ret_str, "1:2::3 12345 a:b::c 23456");
|
||||
free(ret_str);
|
||||
|
||||
ret_str = four_tuple_to_string(&reve_addr);
|
||||
EXPECT_TRUE(ret_str != nullptr);
|
||||
EXPECT_STREQ(ret_str, "a:b::c 23456 1:2::3 12345");
|
||||
free(ret_str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -11,8 +11,10 @@ TEST(STREAM_TABLE, INSERT)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
|
||||
// TEST Insert
|
||||
EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0);
|
||||
@@ -35,9 +37,12 @@ TEST(STREAM_TABLE, SEARCH_BY_ID)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
INIT_ADDR_V4(addr3, "1.1.1.1", 1111, "2.2.2.2", 2222);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr3;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr3, "1.1.1.1", 1111, "2.2.2.2", 2222);
|
||||
|
||||
// TEST Insert
|
||||
EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0);
|
||||
@@ -67,9 +72,12 @@ TEST(STREAM_TABLE, SEARCH_BY_ADDR)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
INIT_ADDR_V4(addr3, "1.1.1.1", 1111, "2.2.2.2", 2222);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr3;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr3, "1.1.1.1", 1111, "2.2.2.2", 2222);
|
||||
|
||||
// TEST Insert
|
||||
EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0);
|
||||
@@ -99,8 +107,10 @@ TEST(STREAM_TABLE, SEARCH_BY_REVERSE_ADDR)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1_reverse;
|
||||
struct four_tuple addr2_reverse;
|
||||
four_tuple_reverse(&addr1, &addr1_reverse);
|
||||
@@ -132,8 +142,10 @@ TEST(STREAM_TABLE, DELETE_BY_ID)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1_reverse;
|
||||
struct four_tuple addr2_reverse;
|
||||
four_tuple_reverse(&addr1, &addr1_reverse);
|
||||
@@ -169,8 +181,10 @@ TEST(STREAM_TABLE, DELETE_BY_ADDR)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1_reverse;
|
||||
struct four_tuple addr2_reverse;
|
||||
four_tuple_reverse(&addr1, &addr1_reverse);
|
||||
@@ -206,8 +220,10 @@ TEST(STREAM_TABLE, DELETE_BY_REVERSE_ADDR)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1_reverse;
|
||||
struct four_tuple addr2_reverse;
|
||||
four_tuple_reverse(&addr1, &addr1_reverse);
|
||||
@@ -243,8 +259,10 @@ TEST(STREAM_TABLE, RESET)
|
||||
|
||||
char *val_hello = strdup("HELLO");
|
||||
char *val_world = strdup("WORLD");
|
||||
INIT_ADDR_V4(addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
INIT_ADDR_V6(addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
struct four_tuple addr1;
|
||||
SET_HUMAN_READABLE_IPV4_TUPLE(&addr1, "1.2.3.4", 1234, "4.3.2.1", 4321);
|
||||
struct four_tuple addr2;
|
||||
SET_HUMAN_READABLE_IPV6_TUPLE(&addr2, "2:3:4::5", 2345, "5:4:3::2", 5342);
|
||||
|
||||
// TEST Insert
|
||||
EXPECT_TRUE(session_table_insert(table, 1, &addr1, val_hello, free) == 0);
|
||||
|
||||
@@ -7,7 +7,7 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "data_packet.h"
|
||||
#include "packet.h"
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
enum traffic_type
|
||||
@@ -138,7 +138,7 @@ void policy_enforcer_destory(struct policy_enforcer *enforcer);
|
||||
// return -1 : error
|
||||
int policy_enforcer_register(struct policy_enforcer *enforcer);
|
||||
int policy_enforce_chaining_size(struct policy_enforcer *enforcer);
|
||||
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct data_packet *data_pkt, uint64_t rule_id, int dir_is_i2e);
|
||||
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct packet *data_pkt, uint64_t rule_id, int dir_is_i2e);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -66,6 +66,15 @@ struct packet_io
|
||||
* metadata
|
||||
******************************************************************************/
|
||||
|
||||
void sce_packet_get_innermost_tuple(const struct packet *handler, struct four_tuple *tuple)
|
||||
{
|
||||
memset(tuple, 0, sizeof(struct four_tuple));
|
||||
if (packet_get_innermost_four_tuple(handler, tuple) == -1)
|
||||
{
|
||||
packet_get_innermost_two_tuple(handler, &tuple->two_tuple);
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 : success
|
||||
// return -1 : error
|
||||
int mbuff_get_metadata(marsio_buff_t *rx_buff, struct metadata *meta)
|
||||
@@ -349,14 +358,10 @@ static struct session_ctx *data_packet_search_session(struct session_table *tabl
|
||||
{
|
||||
struct four_tuple inner_addr;
|
||||
struct four_tuple reverse_addr;
|
||||
struct data_packet data_pkt;
|
||||
struct packet data_pkt;
|
||||
|
||||
memset(&inner_addr, 0, sizeof(struct four_tuple));
|
||||
memset(&reverse_addr, 0, sizeof(struct four_tuple));
|
||||
|
||||
data_packet_parse(&data_pkt, (const void *)raw_data, raw_len, 0);
|
||||
|
||||
data_packet_get_innermost_four_tuple(&data_pkt, &inner_addr);
|
||||
packet_parse(&data_pkt, raw_data, raw_len);
|
||||
sce_packet_get_innermost_tuple(&data_pkt, &inner_addr);
|
||||
four_tuple_reverse(&inner_addr, &reverse_addr);
|
||||
|
||||
struct session_node *node = session_table_search_by_id(table, session_id);
|
||||
@@ -368,7 +373,7 @@ static struct session_ctx *data_packet_search_session(struct session_table *tabl
|
||||
struct session_ctx *session_ctx = (struct session_ctx *)node->value;
|
||||
if (memcmp(&session_ctx->inner_tuple4, &inner_addr, sizeof(struct four_tuple)) != 0 && memcmp(&session_ctx->inner_tuple4, &reverse_addr, sizeof(struct four_tuple)) != 0)
|
||||
{
|
||||
char *addr_str = four_tuple_to_string(&inner_addr);
|
||||
char *addr_str = four_tuple_tostring(&inner_addr);
|
||||
LOG_ERROR("%s: unexpected raw packet, session %lu expected address tuple4 is %s, but current packet's address tuple4 is %s, bypass !!!", LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr, addr_str);
|
||||
free(addr_str);
|
||||
return NULL;
|
||||
@@ -382,18 +387,15 @@ static struct session_ctx *data_packet_search_session(struct session_table *tabl
|
||||
static struct session_ctx *inject_packet_search_session(struct session_table *table, const char *raw_data, int raw_len)
|
||||
{
|
||||
struct four_tuple inner_addr;
|
||||
struct data_packet data_pkt;
|
||||
struct packet data_pkt;
|
||||
|
||||
memset(&inner_addr, 0, sizeof(struct four_tuple));
|
||||
|
||||
data_packet_parse(&data_pkt, (const void *)raw_data, raw_len, 0);
|
||||
|
||||
data_packet_get_innermost_four_tuple(&data_pkt, &inner_addr);
|
||||
packet_parse(&data_pkt, raw_data, raw_len);
|
||||
sce_packet_get_innermost_tuple(&data_pkt, &inner_addr);
|
||||
|
||||
struct session_node *node = session_table_search_by_addr(table, &inner_addr);
|
||||
if (node == NULL)
|
||||
{
|
||||
char *addr_str = four_tuple_to_string(&inner_addr);
|
||||
char *addr_str = four_tuple_tostring(&inner_addr);
|
||||
LOG_ERROR("%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_str);
|
||||
free(addr_str);
|
||||
return NULL;
|
||||
@@ -878,7 +880,7 @@ static void session_value_free_cb(void *ctx)
|
||||
session_ctx_free(s_ctx);
|
||||
}
|
||||
|
||||
static void handle_policy_mutil_hits(struct policy_enforcer *enforcer, struct session_ctx *session_ctx, struct control_packet *ctrl_pkt, data_packet *data_pkt, int is_e2i_dir)
|
||||
static void handle_policy_mutil_hits(struct policy_enforcer *enforcer, struct session_ctx *session_ctx, struct control_packet *ctrl_pkt, packet *data_pkt, int is_e2i_dir)
|
||||
{
|
||||
for (int i = 0; i < ctrl_pkt->rule_id_num; i++)
|
||||
{
|
||||
@@ -913,21 +915,21 @@ static void handle_session_opening(struct metadata *meta, struct control_packet
|
||||
}
|
||||
#endif
|
||||
|
||||
struct data_packet data_pkt;
|
||||
struct packet data_pkt;
|
||||
struct four_tuple inner_tuple4;
|
||||
const void *payload = data_packet_parse(&data_pkt, (const void *)meta->raw_data, meta->raw_len, meta->session_id);
|
||||
data_packet_get_innermost_four_tuple(&data_pkt, &inner_tuple4);
|
||||
uint16_t real_offset = (char *)payload - meta->raw_data;
|
||||
const char *payload = packet_parse(&data_pkt, meta->raw_data, meta->raw_len);
|
||||
sce_packet_get_innermost_tuple(&data_pkt, &inner_tuple4);
|
||||
uint16_t real_offset = payload - meta->raw_data;
|
||||
if (real_offset != meta->l7offset)
|
||||
{
|
||||
char *addr_str = four_tuple_to_string(&inner_tuple4);
|
||||
char *addr_str = four_tuple_tostring(&inner_tuple4);
|
||||
LOG_ERROR("%s: incorrect dataoffset %d in the control zone of session %lu %s, the expect value is %d", LOG_TAG_PKTIO, meta->l7offset, meta->session_id, addr_str, real_offset);
|
||||
free(addr_str);
|
||||
}
|
||||
|
||||
struct session_ctx *session_ctx = session_ctx_new();
|
||||
session_ctx->session_id = meta->session_id;
|
||||
session_ctx->session_addr = four_tuple_to_string(&inner_tuple4);
|
||||
session_ctx->session_addr = four_tuple_tostring(&inner_tuple4);
|
||||
four_tuple_copy(&session_ctx->inner_tuple4, &inner_tuple4);
|
||||
metadata_deep_copy(session_ctx->ctrl_meta, meta);
|
||||
session_ctx->chainings.chaining_raw = selected_chaining_create(chaining_size, session_ctx->session_id, session_ctx->session_addr);
|
||||
@@ -974,9 +976,9 @@ static void handle_session_active(struct metadata *meta, struct control_packet *
|
||||
{
|
||||
struct session_ctx *session_ctx = (struct session_ctx *)node->value;
|
||||
|
||||
struct data_packet data_pkt;
|
||||
const void *payload = data_packet_parse(&data_pkt, (const void *)meta->raw_data, meta->raw_len, meta->session_id);
|
||||
uint16_t real_offset = (char *)payload - meta->raw_data;
|
||||
struct packet data_pkt;
|
||||
const char *payload = packet_parse(&data_pkt, meta->raw_data, meta->raw_len);
|
||||
uint16_t real_offset = payload - meta->raw_data;
|
||||
if (real_offset != meta->l7offset)
|
||||
{
|
||||
LOG_ERROR("%s: incorrect dataoffset %d in the control zone of session %lu %s, the expect value is %d", LOG_TAG_PKTIO, meta->l7offset, meta->session_id, session_ctx->session_addr, real_offset);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "global_metrics.h"
|
||||
#include "health_check.h"
|
||||
#include "data_packet.h"
|
||||
#include "packet.h"
|
||||
#include "policy.h"
|
||||
#include "utils.h"
|
||||
#include "log.h"
|
||||
@@ -1682,7 +1682,7 @@ int policy_enforce_chaining_size(struct policy_enforcer *enforcer)
|
||||
return enforcer->config.max_chaining_size;
|
||||
}
|
||||
|
||||
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct data_packet *data_pkt, uint64_t rule_id, int dir_is_i2e)
|
||||
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct packet *data_pkt, uint64_t rule_id, int dir_is_i2e)
|
||||
{
|
||||
char buffer[16] = {0};
|
||||
struct selected_chaining *chaining = NULL;
|
||||
@@ -1731,7 +1731,7 @@ void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct se
|
||||
// sf_index
|
||||
selected_sf->sf_index = chaining->chaining_used;
|
||||
|
||||
uint64_t packet_hash = data_packet_get_hash(data_pkt, sff_param->sff_ldbc.method, dir_is_i2e);
|
||||
uint64_t packet_hash = packet_get_hash(data_pkt, sff_param->sff_ldbc.method, dir_is_i2e);
|
||||
select_sf_from_sff(enforcer, sff_param, selected_sf, s_ctx, packet_hash);
|
||||
|
||||
LOG_INFO("%s: session %lu %s enforce chaining [%d/%d]: policy: %lu->%d->%d, action: %s->%s->%s",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "sce.h"
|
||||
#include "policy.h"
|
||||
#include "data_packet.h"
|
||||
#include "packet.h"
|
||||
#include "global_metrics.h"
|
||||
|
||||
unsigned char data1[] = {
|
||||
@@ -171,9 +171,9 @@ TEST(POLICY, POLICY_ENFORCER_RAW_TRAFFIC1)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -224,9 +224,9 @@ TEST(POLICY, POLICY_ENFORCER_RAW_TRAFFIC2)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -318,9 +318,9 @@ TEST(POLICY, POLICY_ENFORCER_RAW_TRAFFIC_MUTIL_HITS)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -417,9 +417,9 @@ TEST(POLICY, POLICY_ENFORCER_DECRYPTED_TRAFFIC1)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -471,9 +471,9 @@ TEST(POLICY, POLICY_ENFORCER_DECRYPTED_TRAFFIC2)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -566,9 +566,9 @@ TEST(POLICY, POLICY_ENFORCER_DECRYPTED_TRAFFIC_MUTIL_HITS)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
@@ -665,9 +665,9 @@ TEST(POLICY, POLICY_ENFORCER_MIX_TRAFFIC_MUTIL_HITS)
|
||||
s_ctx.session_id = 1;
|
||||
s_ctx.session_addr = (char *)"1.1.1.1 11 2.2.2.2 22";
|
||||
|
||||
struct data_packet handler;
|
||||
struct packet handler;
|
||||
|
||||
const void *payload = data_packet_parse(&handler, (const void *)data1, sizeof(data1), 0);
|
||||
const char *payload = packet_parse(&handler, (const char *)data1, sizeof(data1));
|
||||
EXPECT_TRUE(payload != nullptr);
|
||||
EXPECT_TRUE((char *)payload - (char *)&data1 == 70);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user