重构Packet Parser

This commit is contained in:
luwenpeng
2023-11-13 16:56:31 +08:00
parent 07f41fc298
commit b4c688c87c
17 changed files with 1823 additions and 2680 deletions

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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
View 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