refactor: packet module (split to parse/build/layer/tunnel/utils)

This commit is contained in:
luwenpeng
2024-06-24 17:07:05 +08:00
parent d8963af5f8
commit 71422ebb36
36 changed files with 796 additions and 724 deletions

View File

@@ -4,6 +4,8 @@
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "packet_def.h"
#include "packet_layer.h"
#include "duplicated_packet_filter.h"
struct duplicated_packet_key

View File

@@ -7,11 +7,6 @@ extern "C"
// Duplicated Packet Filter for IPv4 Packet
#include "log.h"
#include "packet_priv.h"
#define DUPLICATED_PACKET_FILTER_LOG_ERROR(format, ...) LOG_ERROR("duplicated packet filter", format, ##__VA_ARGS__)
struct duplicated_packet_filter;
struct duplicated_packet_filter *duplicated_packet_filter_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now);
void duplicated_packet_filter_free(struct duplicated_packet_filter *filter);

View File

@@ -1,7 +1,9 @@
#include <gtest/gtest.h>
#include "tuple.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "duplicated_packet_filter.h"
#include "packet_priv.h"
/******************************************************************************
* [Protocols in frame: eth:ethertype:ip:ipv6:tcp]

View File

@@ -1,5 +1,6 @@
#include <string.h>
#include "tuple.h"
#include "dablooms.h"
#include "udp_utils.h"
#include "ipv4_utils.h"

View File

@@ -5,11 +5,6 @@ extern "C"
{
#endif
#include "log.h"
#include "tuple.h"
#define EVICTED_SESSION_FILTER_LOG_ERROR(format, ...) LOG_ERROR("evicted session filter", format, ##__VA_ARGS__)
struct evicted_session_filter *evicted_session_filter_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now);
void evicted_session_filter_free(struct evicted_session_filter *filter);

View File

@@ -1,5 +1,6 @@
#include <gtest/gtest.h>
#include "tuple.h"
#include "evicted_session_filter.h"
TEST(EVICTED_SESSION_FILTER, TEST)

View File

@@ -3,14 +3,19 @@
#include <sys/queue.h>
#include <assert.h>
#include "packet_priv.h"
#include "log.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_parse.h"
#include "crc32_hash.h"
#include "checksum.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip_reassembly.h"
#define IP_REASSEMBLE_DEBUG(format, ...) LOG_DEBUG("ip_reassembly", format, ##__VA_ARGS__)
#define IP_REASSEMBLE_ERROR(format, ...) LOG_ERROR("ip_reassembly", format, ##__VA_ARGS__)
#define IPV4_KEYLEN 1
#define IPV6_KEYLEN 4
#define PRIME_VALUE 0xeaad8405

View File

@@ -5,12 +5,6 @@ extern "C"
{
#endif
#include "packet_priv.h"
#include "log.h"
#define IP_REASSEMBLE_DEBUG(format, ...) LOG_DEBUG("ip_reassembly", format, ##__VA_ARGS__)
#define IP_REASSEMBLE_ERROR(format, ...) LOG_ERROR("ip_reassembly", format, ##__VA_ARGS__)
struct ip_reassembly_options
{
uint8_t enable;

View File

@@ -12,8 +12,10 @@ extern "C"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip_reassembly.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_parse.h"
#include "packet_layer.h"
static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr)
{

View File

@@ -1,4 +1,4 @@
add_library(packet packet.cpp packet_build.cpp packet_utils.cpp packet_layer.cpp packet_tunnel.cpp checksum.cpp)
add_library(packet packet_parse.cpp packet_build.cpp packet_utils.cpp packet_ldbc.cpp packet_layer.cpp packet_tunnel.cpp checksum.cpp)
target_include_directories(packet PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/include)

View File

@@ -1,13 +1,16 @@
#include <time.h>
#include "packet_build.h"
#include "log.h"
#include "checksum.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_layer.h"
#include "packet_parse.h"
#include "packet_build.h"
#define PACKET_BUILD_LOG_DEBUG(format, ...) LOG_DEBUG("packet build", format, ##__VA_ARGS__)
#define PACKET_BUILD_LOG_ERROR(format, ...) LOG_ERROR("packet build", format, ##__VA_ARGS__)

62
src/packet/packet_def.h Normal file
View File

@@ -0,0 +1,62 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include "stellar/layer.h"
#include "stellar/packet.h"
#define PACKET_MAX_LAYERS 32
#define MAX_ROUTE_CTX 64
struct route_ctx
{
char data[MAX_ROUTE_CTX];
int used;
};
struct metadata
{
struct route_ctx route_ctx;
struct sids sids;
uint64_t session_id;
uint64_t domain_id;
uint16_t link_id;
int is_ctrl;
enum packet_direction direction;
enum packet_action action;
const void *origin_ctx;
};
struct raw_layer
{
enum layer_proto proto;
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
};
struct packet
{
struct raw_layer layers[PACKET_MAX_LAYERS];
struct raw_layer *frag_layer; // fragment layer
int8_t layers_used;
int8_t layers_size;
int8_t need_free;
const char *data_ptr;
uint16_t data_len;
uint16_t trim_len; // trim eth padding
struct metadata meta;
};
#ifdef __cplusplus
}
#endif

View File

@@ -1,6 +1,12 @@
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_layer.h"
#include "packet_utils.h"
int packet_get_layer_count(const struct packet *pkt)
{
return pkt->layers_used;
}
int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out)
{
const struct raw_layer *raw = packet_get_raw_layer(pkt, idx);
@@ -14,3 +20,44 @@ int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out
return 0;
}
}
const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx)
{
if (idx < 0 || idx >= pkt->layers_used)
{
return NULL;
}
return &pkt->layers[idx];
}
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
if (layer->proto == proto)
{
return layer;
}
}
return NULL;
}
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
if (layer->proto == proto)
{
return layer;
}
}
return NULL;
}

18
src/packet/packet_layer.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include "stellar/layer.h"
int packet_get_layer_count(const struct packet *pkt);
int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out);
const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx);
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto);
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto);
#ifdef __cplusplus
}
#endif

122
src/packet/packet_ldbc.cpp Normal file
View File

@@ -0,0 +1,122 @@
#include "tuple.h"
#include "uthash.h"
#include "packet_ldbc.h"
#include "packet_utils.h"
uint64_t packet_ldbc_hash(const struct packet *pkt, enum load_balance ldbc, enum packet_direction direction)
{
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 tuple2 inner_addr;
struct tuple2 outer_addr;
if (pkt == NULL)
{
return hash_value;
}
if (packet_get_innermost_tuple2(pkt, &inner_addr) == -1)
{
return hash_value;
}
if (packet_get_outermost_tuple2(pkt, &outer_addr) == -1)
{
return hash_value;
}
if (inner_addr.ip_type == IP_TYPE_V4)
{
inner_src_addr = (const char *)&inner_addr.src_addr.v4;
inner_dst_addr = (const char *)&inner_addr.dst_addr.v4;
inner_addr_len = sizeof(struct in_addr);
}
else
{
inner_src_addr = (const char *)&inner_addr.src_addr.v6;
inner_dst_addr = (const char *)&inner_addr.dst_addr.v6;
inner_addr_len = sizeof(struct in6_addr);
}
if (outer_addr.ip_type == IP_TYPE_V4)
{
outer_src_addr = (const char *)&outer_addr.src_addr.v4;
outer_dst_addr = (const char *)&outer_addr.dst_addr.v4;
outer_addr_len = sizeof(struct in_addr);
}
else
{
outer_src_addr = (const char *)&outer_addr.src_addr.v6;
outer_dst_addr = (const char *)&outer_addr.dst_addr.v6;
outer_addr_len = sizeof(struct in6_addr);
}
switch (ldbc)
{
case LDBC_HASH_OUTERMOST_INT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
}
break;
case LDBC_HASH_OUTERMOST_EXT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
}
break;
case LDBC_HASH_OUTERMOST_INT_EXT_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_HASH_INNERMOST_INT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
}
break;
case LDBC_HASH_INNERMOST_EXT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
}
break;
default:
return hash_value;
}
return hash_value;
}

25
src/packet/packet_ldbc.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include "stellar/packet.h"
enum load_balance
{
LDBC_HASH_OUTERMOST_INT_IP = 1,
LDBC_HASH_OUTERMOST_EXT_IP = 2,
LDBC_HASH_OUTERMOST_INT_EXT_IP = 3,
LDBC_HASH_INNERMOST_INT_IP = 4,
LDBC_HASH_INNERMOST_EXT_IP = 5,
};
uint64_t packet_ldbc_hash(const struct packet *pkt, enum load_balance ldbc, enum packet_direction direction);
#ifdef __cplusplus
}
#endif

View File

@@ -4,9 +4,7 @@
#include <netinet/ip_icmp.h>
#include <linux/ppp_defs.h>
#include "uthash.h"
#include "packet_priv.h"
#include "packet_utils.h"
#include "log.h"
#include "eth_utils.h"
#include "gre_utils.h"
#include "udp_utils.h"
@@ -17,31 +15,37 @@
#include "l2tp_utils.h"
#include "vlan_utils.h"
#include "vxlan_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
#define PACKET_PARSE_LOG_DEBUG(format, ...) void(0) // LOG_DEBUG("packet parse", format, ##__VA_ARGS__)
#define PACKET_PARSE_LOG_WARN(format, ...) LOG_WARN("packet parse", format, ##__VA_ARGS__)
#define PACKET_PARSE_LOG_ERROR(format, ...) LOG_ERROR("packet parse", format, ##__VA_ARGS__)
#define PACKET_LOG_DATA_INSUFFICIENCY(pkt, layer) \
{ \
PACKET_LOG_WARN("pkt: %p, layer: %s, data insufficiency", \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, data insufficiency", \
(pkt), layer_proto_to_str(layer)); \
}
#define PACKET_LOG_UNSUPPORT_PROTO(pkt, layer, next_proto) \
{ \
PACKET_LOG_WARN("pkt: %p, layer: %s, unsupport next proto %d", \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, unsupport next proto %d", \
(pkt), layer_proto_to_str(layer), (next_proto)); \
}
#define PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto) \
{ \
PACKET_LOG_WARN("pkt: %p, layer: l3, unsupport next eth proto %s", \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: l3, unsupport next eth proto %s", \
(pkt), eth_proto_to_str(next_proto)); \
}
#define PACKET_LOG_UNSUPPORT_IPPROTO(pkt, next_proto) \
{ \
PACKET_LOG_WARN("pkt: %p, layer: l4, unsupport next ip proto %s", \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: l4, unsupport next ip proto %s", \
(pkt), ip_proto_to_str(next_proto)); \
}
@@ -49,15 +53,8 @@
* Static API
******************************************************************************/
static inline const char *ldbc_method_to_str(enum ldbc_method method);
static inline const char *layer_proto_to_str(enum layer_proto proto);
static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple);
static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple);
static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain);
static inline struct raw_layer *get_free_layer(struct packet *pkt);
static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len);
// 数据链路层
@@ -94,25 +91,6 @@ static inline const char *parse_l4(struct packet *pkt, uint8_t next_proto, const
* Private API -- Utils
******************************************************************************/
static inline const char *ldbc_method_to_str(enum ldbc_method method)
{
switch (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 inline const char *layer_proto_to_str(enum layer_proto proto)
{
switch (proto)
@@ -156,106 +134,6 @@ static inline const char *layer_proto_to_str(enum layer_proto proto)
}
}
static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
switch (proto)
{
case LAYER_PROTO_IPV4:
ipv4 = (const struct ip *)data;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr;
tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr;
break;
case LAYER_PROTO_IPV6:
ipv6 = (const struct ip6_hdr *)data;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6->ip6_src;
tuple->dst_addr.v6 = ipv6->ip6_dst;
break;
default:
break;
}
}
static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
const struct tcphdr *tcp = NULL;
const struct udphdr *udp = NULL;
switch (proto)
{
case LAYER_PROTO_TCP:
tcp = (const struct tcphdr *)data;
tuple->src_port = tcp->th_sport;
tuple->dst_port = tcp->th_dport;
break;
case LAYER_PROTO_UDP:
udp = (const struct udphdr *)data;
tuple->src_port = udp->uh_sport;
tuple->dst_port = udp->uh_dport;
break;
case LAYER_PROTO_IPV4:
ipv4 = (const struct ip *)data;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr;
tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr;
break;
case LAYER_PROTO_IPV6:
ipv6 = (const struct ip6_hdr *)data;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6->ip6_src;
tuple->dst_addr.v6 = ipv6->ip6_dst;
break;
default:
break;
}
}
static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
const struct tcphdr *tcp = NULL;
const struct udphdr *udp = NULL;
tuple->domain = domain;
switch (proto)
{
case LAYER_PROTO_TCP:
tcp = (const struct tcphdr *)data;
tuple->ip_proto = IPPROTO_TCP;
tuple->src_port = tcp->th_sport;
tuple->dst_port = tcp->th_dport;
break;
case LAYER_PROTO_UDP:
udp = (const struct udphdr *)data;
tuple->ip_proto = IPPROTO_UDP;
tuple->src_port = udp->uh_sport;
tuple->dst_port = udp->uh_dport;
break;
case LAYER_PROTO_IPV4:
ipv4 = (const struct ip *)data;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr;
tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr;
break;
case LAYER_PROTO_IPV6:
ipv6 = (const struct ip6_hdr *)data;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6->ip6_src;
tuple->dst_addr.v6 = ipv6->ip6_dst;
break;
default:
break;
}
}
static inline struct raw_layer *get_free_layer(struct packet *pkt)
{
if (pkt->layers_used >= pkt->layers_size)
@@ -276,7 +154,7 @@ static inline struct raw_layer *get_free_layer(struct packet *pkt)
(_layer)->pld_len = (_len) - (_hdr_len) - (_trim); \
(_pkt)->trim_len += (_trim); \
(_pkt)->layers_used++; \
PACKET_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \
PACKET_PARSE_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \
(_pkt)->layers_used - 1, (_pkt)->layers_size, layer_proto_to_str((_proto)), \
(_layer)->hdr_offset, (_layer)->hdr_ptr, (_layer)->hdr_len, (_layer)->pld_ptr, (_layer)->pld_len); \
}
@@ -701,7 +579,7 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1
}
if (unlikely(total_len < hdr_len))
{
PACKET_LOG_ERROR("packet %p ip total_len %d < hdr_len %d", pkt, total_len, hdr_len);
PACKET_PARSE_LOG_ERROR("packet %p ip total_len %d < hdr_len %d", pkt, total_len, hdr_len);
return data;
}
uint16_t trim_len = len - total_len;
@@ -710,7 +588,7 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1
// ip fragmented
if (ipv4_hdr_get_mf_flag(hdr) || ipv4_hdr_get_frag_offset(hdr))
{
PACKET_LOG_WARN("packet %p ip layer %p is fragmented", pkt, layer);
PACKET_PARSE_LOG_WARN("packet %p ip layer %p is fragmented", pkt, layer);
pkt->frag_layer = layer;
return layer->pld_ptr;
}
@@ -800,7 +678,7 @@ static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint1
// ipv6 fragment
if (next_proto == IPPROTO_FRAGMENT)
{
PACKET_LOG_WARN("packet %p ipv6 layer %p is fragmented", pkt, layer);
PACKET_PARSE_LOG_WARN("packet %p ipv6 layer %p is fragmented", pkt, layer);
pkt->frag_layer = layer;
return layer->pld_ptr;
}
@@ -1208,399 +1086,3 @@ void packet_print(const struct packet *pkt)
}
}
}
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
memset(tuple, 0, sizeof(struct tuple2));
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple);
return 0;
}
}
return -1;
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
memset(tuple, 0, sizeof(struct tuple2));
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple);
return 0;
}
}
return -1;
}
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
memset(tuple, 0, sizeof(struct tuple4));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
// first get L4 layer
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
break;
}
}
if (layer_l3 && layer_l4)
{
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple);
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
memset(tuple, 0, sizeof(struct tuple4));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
// first get L3 layer
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
break;
}
}
if (layer_l3 && layer_l4)
{
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple);
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
memset(tuple, 0, sizeof(struct tuple6));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
// first get L4 layer
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain);
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
memset(tuple, 0, sizeof(struct tuple6));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
// first get L3 layer
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain);
return 0;
}
else
{
return -1;
}
}
const char *packet_get_raw_data(const struct packet *pkt)
{
return pkt->data_ptr;
}
uint16_t packet_get_raw_len(const struct packet *pkt)
{
return pkt->data_len;
}
const char *packet_get_payload(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return NULL;
}
return pkt->layers[pkt->layers_used - 1].pld_ptr;
}
uint16_t packet_get_payload_len(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return 0;
}
return pkt->layers[pkt->layers_used - 1].pld_len;
}
int packet_get_layer_count(const struct packet *pkt)
{
return pkt->layers_used;
}
const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx)
{
if (idx < 0 || idx >= pkt->layers_used)
{
return NULL;
}
return &pkt->layers[idx];
}
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
if (layer->proto == proto)
{
return layer;
}
}
return NULL;
}
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
if (layer->proto == proto)
{
return layer;
}
}
return NULL;
}
uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, enum packet_direction direction)
{
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 tuple2 inner_addr;
struct tuple2 outer_addr;
if (pkt == NULL)
{
return hash_value;
}
if (packet_get_innermost_tuple2(pkt, &inner_addr) == -1)
{
return hash_value;
}
if (packet_get_outermost_tuple2(pkt, &outer_addr) == -1)
{
return hash_value;
}
if (inner_addr.ip_type == IP_TYPE_V4)
{
inner_src_addr = (const char *)&inner_addr.src_addr.v4;
inner_dst_addr = (const char *)&inner_addr.dst_addr.v4;
inner_addr_len = sizeof(struct in_addr);
}
else
{
inner_src_addr = (const char *)&inner_addr.src_addr.v6;
inner_dst_addr = (const char *)&inner_addr.dst_addr.v6;
inner_addr_len = sizeof(struct in6_addr);
}
if (outer_addr.ip_type == IP_TYPE_V4)
{
outer_src_addr = (const char *)&outer_addr.src_addr.v4;
outer_dst_addr = (const char *)&outer_addr.dst_addr.v4;
outer_addr_len = sizeof(struct in_addr);
}
else
{
outer_src_addr = (const char *)&outer_addr.src_addr.v6;
outer_dst_addr = (const char *)&outer_addr.dst_addr.v6;
outer_addr_len = sizeof(struct in6_addr);
}
switch (method)
{
case LDBC_METHOD_HASH_INT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
}
break;
case LDBC_METHOD_HASH_EXT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(outer_src_addr, outer_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value);
}
break;
case LDBC_METHOD_HASH_INT_IP_AND_EXT_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 (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
}
break;
case LDBC_METHOD_HASH_INNERMOST_EXT_IP:
if (direction == PACKET_DIRECTION_INCOMING)
{
// direction 1: E2I
HASH_VALUE(inner_src_addr, inner_addr_len, hash_value);
}
else
{
// direction 0: I2E
HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value);
}
break;
default:
return hash_value;
}
return hash_value;
}

15
src/packet/packet_parse.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
const char *packet_parse(struct packet *pkt, const char *data, uint16_t len);
void packet_print(const struct packet *pkt);
#ifdef __cplusplus
}
#endif

View File

@@ -1,104 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include "log.h"
#include "tuple.h"
#include "stellar/layer.h"
#include "stellar/packet.h"
#define PACKET_MAX_LAYERS 32
#define PACKET_LOG_ERROR(format, ...) LOG_ERROR("packet", format, ##__VA_ARGS__)
#define PACKET_LOG_WARN(format, ...) LOG_WARN("packet", format, ##__VA_ARGS__)
#define PACKET_LOG_DEBUG(format, ...) void(0)
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,
};
#define MAX_ROUTE_CTX 64
struct route_ctx
{
char data[MAX_ROUTE_CTX];
int used;
};
struct metadata
{
struct route_ctx route_ctx;
struct sids sids;
uint64_t session_id;
uint64_t domain_id;
uint16_t link_id;
int is_ctrl;
enum packet_direction direction;
enum packet_action action;
const void *origin_ctx;
};
struct raw_layer
{
enum layer_proto proto;
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
};
struct packet
{
struct raw_layer layers[PACKET_MAX_LAYERS];
struct raw_layer *frag_layer; // fragment layer
int8_t layers_used;
int8_t layers_size;
int8_t need_free;
const char *data_ptr;
uint16_t data_len;
uint16_t trim_len; // trim eth padding
struct metadata meta;
};
// return innermost payload
const char *packet_parse(struct packet *pkt, const char *data, uint16_t len);
void packet_print(const struct packet *pkt);
// return 0: found
// return -1: not found
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
// return 0: found
// return -1: not found
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
// return 0: found
// return -1: not found
int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
int packet_get_layer_count(const struct packet *pkt);
const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx);
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto type);
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto type);
// direction: PACKET_DIRECTION_OUTGOING = 0 (Internal -> External)
// direction: PACKET_DIRECTION_INCOMING = 1 (External -> Internal)
uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, enum packet_direction direction);
#ifdef __cplusplus
}
#endif

View File

@@ -1,8 +1,9 @@
#include <assert.h>
#include "stellar/tunnel.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_layer.h"
struct tunnel_detector
{

View File

@@ -1,8 +1,16 @@
#include <stdlib.h>
#include "packet_priv.h"
#include "log.h"
#include "tuple.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "packet_def.h"
#include "packet_utils.h"
#define PACKET_UTILS_LOG_ERROR(format, ...) LOG_ERROR("packet utils", format, ##__VA_ARGS__)
/******************************************************************************
* metadata utils
******************************************************************************/
@@ -31,7 +39,7 @@ void packet_prepend_sids(struct packet *pkt, const struct sids *sids)
{
if (pkt->meta.sids.used + sids->used > MAX_SIDS)
{
PACKET_LOG_ERROR("sids overflow");
PACKET_UTILS_LOG_ERROR("sids overflow");
return;
}
else
@@ -118,13 +126,360 @@ const void *packet_get_origin_ctx(const struct packet *pkt)
return pkt->meta.origin_ctx;
}
/******************************************************************************
* tuple uitls
******************************************************************************/
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
memset(tuple, 0, sizeof(struct tuple2));
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
return 0;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
return 0;
}
}
return -1;
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
memset(tuple, 0, sizeof(struct tuple2));
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
return 0;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
return 0;
}
}
return -1;
}
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
memset(tuple, 0, sizeof(struct tuple4));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
// first get L4 layer
if (layer->proto == LAYER_PROTO_UDP)
{
const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr;
tuple->src_port = udp_hdr->uh_sport;
tuple->dst_port = udp_hdr->uh_dport;
layer_l4 = layer;
continue;
}
if (layer->proto == LAYER_PROTO_TCP)
{
const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr;
tuple->src_port = tcp_hdr->th_sport;
tuple->dst_port = tcp_hdr->th_dport;
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
break;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
memset(tuple, 0, sizeof(struct tuple4));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
// first get L3 layer
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
continue;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->proto == LAYER_PROTO_UDP)
{
const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr;
tuple->src_port = udp_hdr->uh_sport;
tuple->dst_port = udp_hdr->uh_dport;
layer_l4 = layer;
break;
}
if (layer->proto == LAYER_PROTO_TCP)
{
const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr;
tuple->src_port = tcp_hdr->th_sport;
tuple->dst_port = tcp_hdr->th_dport;
layer_l4 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
memset(tuple, 0, sizeof(struct tuple6));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
// first get L4 layer
if (layer->proto == LAYER_PROTO_UDP)
{
const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr;
tuple->ip_proto = IPPROTO_UDP;
tuple->src_port = udp_hdr->uh_sport;
tuple->dst_port = udp_hdr->uh_dport;
layer_l4 = layer;
continue;
}
if (layer->proto == LAYER_PROTO_TCP)
{
const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr;
tuple->ip_proto = IPPROTO_TCP;
tuple->src_port = tcp_hdr->th_sport;
tuple->dst_port = tcp_hdr->th_dport;
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
break;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
tuple->domain = packet_get_domain_id(pkt);
return 0;
}
else
{
return -1;
}
}
// return 0 : found
// return -1 : not found
int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
memset(tuple, 0, sizeof(struct tuple6));
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
// first get L3 layer
if (layer->proto == LAYER_PROTO_IPV4)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
continue;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->proto == LAYER_PROTO_UDP)
{
const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr;
tuple->ip_proto = IPPROTO_UDP;
tuple->src_port = udp_hdr->uh_sport;
tuple->dst_port = udp_hdr->uh_dport;
layer_l4 = layer;
break;
}
if (layer->proto == LAYER_PROTO_TCP)
{
const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr;
tuple->ip_proto = IPPROTO_TCP;
tuple->src_port = tcp_hdr->th_sport;
tuple->dst_port = tcp_hdr->th_dport;
layer_l4 = layer;
break;
}
}
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
tuple->domain = packet_get_domain_id(pkt);
return 0;
}
else
{
return -1;
}
}
/******************************************************************************
* other uitls
******************************************************************************/
int packet_is_fragment(const struct packet *pkt)
const char *packet_get_raw_data(const struct packet *pkt)
{
return (pkt->frag_layer) ? 1 : 0;
return pkt->data_ptr;
}
uint16_t packet_get_raw_len(const struct packet *pkt)
{
return pkt->data_len;
}
const char *packet_get_payload(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return NULL;
}
return pkt->layers[pkt->layers_used - 1].pld_ptr;
}
uint16_t packet_get_payload_len(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return 0;
}
return pkt->layers[pkt->layers_used - 1].pld_len;
}
struct packet *packet_new(uint16_t pkt_len)
@@ -188,6 +543,11 @@ void packet_free(struct packet *pkt)
}
}
int packet_is_fragment(const struct packet *pkt)
{
return (pkt->frag_layer) ? 1 : 0;
}
void layer_convert(const struct raw_layer *in, struct layer *out)
{
if (in == NULL || out == NULL)

View File

@@ -6,7 +6,7 @@ extern "C"
#endif
#include <stdint.h>
#include "packet_priv.h"
#include "stellar/packet.h"
/******************************************************************************
* metadata utils
@@ -40,15 +40,40 @@ enum packet_action packet_get_action(const struct packet *pkt);
void packet_set_origin_ctx(struct packet *pkt, void *ctx);
const void *packet_get_origin_ctx(const struct packet *pkt);
/******************************************************************************
* tuple uitls
******************************************************************************/
// return 0: found
// return -1: not found
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
// return 0: found
// return -1: not found
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
// return 0: found
// return -1: not found
int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
/******************************************************************************
* other uitls
******************************************************************************/
int packet_is_fragment(const struct packet *pkt);
const char *packet_get_raw_data(const struct packet *pkt);
uint16_t packet_get_raw_len(const struct packet *pkt);
const char *packet_get_payload(const struct packet *pkt);
uint16_t packet_get_payload_len(const struct packet *pkt);
struct packet *packet_new(uint16_t pkt_len);
struct packet *packet_dup(const struct packet *pkt);
void packet_free(struct packet *pkt);
int packet_is_fragment(const struct packet *pkt);
void layer_convert(const struct raw_layer *in, struct layer *out);
#ifdef __cplusplus

View File

@@ -1,7 +1,13 @@
#include <gtest/gtest.h>
#include <arpa/inet.h>
#include "packet_priv.h"
#include "tuple.h"
#include "packet_def.h"
#include "packet_ldbc.h"
#include "packet_parse.h"
#include "packet_build.h"
#include "packet_utils.h"
#include "packet_layer.h"
/******************************************************************************
* [Protocols in frame: eth:ethertype:vlan:ethertype:vlan:ethertype:ip:ip:udp:data]
@@ -2851,11 +2857,11 @@ TEST(PACKET, HASH_VALUE)
// buffer: "2001:da8:200:900e:200:5efe:d24d:58a3 0 2600:140e:6::1702:1058 0"
// buffer: "210.77.88.163 0 59.66.4.50 0"
EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_EXT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INNERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INNERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_OUTGOING));
EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_INNERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_INNERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING));
}
#endif

View File

@@ -1,7 +1,8 @@
#include <gtest/gtest.h>
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_parse.h"
/******************************************************************************
* [Protocols in frame: eth:ethertype:ip:data]

View File

@@ -1,13 +1,14 @@
#include <gtest/gtest.h>
#include "stellar/layer.h"
#include "stellar/tunnel.h"
#include "packet_priv.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "udp_utils.h"
#include "gre_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "vxlan_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "stellar/layer.h"
#include "stellar/tunnel.h"
/******************************************************************************
* [Protocols in frame: eth:ethertype:vlan:ethertype:vlan:ethertype:ip:ip:udp:data]

View File

@@ -9,12 +9,19 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "log.h"
#include "tuple.h"
#include "macro.h"
#include "dumpfile_io.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_ldbc.h"
#include "packet_utils.h"
#include "packet_parse.h"
#include "lock_free_queue.h"
#define PACKET_IO_LOG_STATE(format, ...) LOG_STATE("dumpfile io", format, ##__VA_ARGS__)
#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("dumpfile io", format, ##__VA_ARGS__)
#define MAX_PACKET_QUEUE_SIZE (4096 * 1000)
struct dumpfile_io
@@ -203,7 +210,7 @@ static void pcap_packet_handler(u_char *user, const struct pcap_pkthdr *h, const
struct packet pkt;
memset(&pkt, 0, sizeof(struct packet));
packet_parse(&pkt, pcap_pkt->data, pcap_pkt->len);
uint64_t hash = packet_get_hash(&pkt, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_OUTGOING);
uint64_t hash = packet_ldbc_hash(&pkt, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_OUTGOING);
// push packet to queue
struct lock_free_queue *queue = handle->queue[hash % handle->nr_threads];

View File

@@ -4,11 +4,14 @@
#include <string.h>
#include <netinet/ether.h>
#include "macro.h"
#include "log.h"
#include "marsio.h"
#include "packet_priv.h"
#include "packet_utils.h"
#include "marsio_io.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_parse.h"
#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("marsio io", format, ##__VA_ARGS__)
struct marsio_io
{

View File

@@ -16,7 +16,6 @@ struct packet_io *packet_io_new(struct packet_io_options *opts)
struct packet_io *packet_io = (struct packet_io *)calloc(1, sizeof(struct packet_io));
if (packet_io == NULL)
{
PACKET_IO_LOG_ERROR("unable to alloc packet io");
return NULL;
}

View File

@@ -5,13 +5,9 @@ extern "C"
{
#endif
#include "log.h"
#include "macro.h"
#include "packet_priv.h"
#include <stdint.h>
#define PACKET_IO_LOG_STATE(format, ...) LOG_STATE("packet_io", format, ##__VA_ARGS__)
#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("packet_io", format, ##__VA_ARGS__)
#define PACKET_IO_LOG_DEBUG(format, ...) LOG_DEBUG("packet_io", format, ##__VA_ARGS__)
#include "macro.h"
struct io_stat
{

View File

@@ -1,6 +1,6 @@
#include <assert.h>
#include "packet_priv.h"
#include "packet_def.h"
#include "session_priv.h"
#include "tcp_utils.h"
#include "tcp_reassembly.h"

View File

@@ -6,6 +6,7 @@
#include "times.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "packet_layer.h"
#include "id_generator.h"
#include "session_pool.h"
#include "session_table.h"

View File

@@ -6,11 +6,11 @@ extern "C"
#endif
#include "list.h"
#include "packet_priv.h"
#include "packet_utils.h"
#include "timeout.h"
#include "uthash.h"
#include "tuple.h"
#include "uthash.h"
#include "timeout.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "stellar/session.h"
#include "tcp_reassembly.h"
#include "session_manager.h"

View File

@@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include "times.h"
#include "packet_parse.h"
#include "session_priv.h"
#include "session_manager.h"

View File

@@ -5,6 +5,9 @@ extern "C"
{
#endif
#include "packet_parse.h"
#include "packet_layer.h"
/******************************************************************************
* test packet: HTTP www.example.com
******************************************************************************/

View File

@@ -2,9 +2,9 @@
#include <assert.h>
#include "times.h"
#include "packet_build.h"
#include "packet_io.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_build.h"
#include "session_priv.h"
#include "stellar_priv.h"

View File

@@ -1,7 +1,8 @@
#include <unistd.h>
#include <pcap/pcap.h>
#include "ipv6_utils.h"
#include "packet_priv.h"
#include "packet_def.h"
#include "packet_layer.h"
#include "packet_parse.h"
#include "eth_utils.h"
#include "vlan_utils.h"
#include "ipv4_utils.h"