2024-09-14 18:38:37 +08:00
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
2024-06-24 17:07:05 +08:00
|
|
|
|
#include "tuple.h"
|
2024-08-16 17:07:52 +08:00
|
|
|
|
#include "uthash.h"
|
2024-08-23 18:44:17 +08:00
|
|
|
|
#include "log_private.h"
|
2024-08-16 16:12:12 +08:00
|
|
|
|
#include "packet_helper.h"
|
2024-09-19 16:10:59 +08:00
|
|
|
|
#include "packet_internal.h"
|
2024-04-11 19:44:02 +08:00
|
|
|
|
|
2024-08-23 18:44:17 +08:00
|
|
|
|
#define PACKET_LOG_ERROR(format, ...) STELLAR_LOG_ERROR(__thread_local_logger, "packet", format, ##__VA_ARGS__)
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
2024-04-11 19:44:02 +08:00
|
|
|
|
/******************************************************************************
|
2024-06-14 19:24:27 +08:00
|
|
|
|
* metadata utils
|
2024-04-11 19:44:02 +08:00
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
2024-08-16 16:31:25 +08:00
|
|
|
|
void packet_set_route_ctx(struct packet *pkt, const struct route_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.route_ctx = *ctx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const struct route_ctx *packet_get_route_ctx(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return &pkt->meta.route_ctx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void packet_set_origin_ctx(struct packet *pkt, void *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.origin_ctx = ctx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const void *packet_get_origin_ctx(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->meta.origin_ctx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
void packet_set_sids(struct packet *pkt, const struct sids *sids)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
pkt->meta.sids = *sids;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
const struct sids *packet_get_sids(const struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
return &pkt->meta.sids;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
void packet_prepend_sids(struct packet *pkt, const struct sids *sids)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
if (pkt->meta.sids.used + sids->used > MAX_SIDS)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-08-16 16:31:25 +08:00
|
|
|
|
PACKET_LOG_ERROR("sids overflow");
|
2024-06-14 19:24:27 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = pkt->meta.sids.used - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.sids.sid[i + sids->used] = pkt->meta.sids.sid[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < sids->used; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.sids.sid[i] = sids->sid[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
pkt->meta.sids.used += sids->used;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
void packet_set_session_id(struct packet *pkt, uint64_t id)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
pkt->meta.session_id = id;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
uint64_t packet_get_session_id(const struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
return pkt->meta.session_id;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-25 10:32:51 +08:00
|
|
|
|
void packet_set_domain(struct packet *pkt, uint64_t domain)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-25 10:32:51 +08:00
|
|
|
|
pkt->meta.domain = domain;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-25 10:32:51 +08:00
|
|
|
|
uint64_t packet_get_domain(const struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-25 10:32:51 +08:00
|
|
|
|
return pkt->meta.domain;
|
2024-06-14 19:24:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void packet_set_link_id(struct packet *pkt, uint16_t id)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.link_id = id;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t packet_get_link_id(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->meta.link_id;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-13 18:03:05 +08:00
|
|
|
|
void packet_set_ctrl(struct packet *pkt, bool ctrl)
|
2024-06-14 19:24:27 +08:00
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.is_ctrl = ctrl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-13 18:03:05 +08:00
|
|
|
|
bool packet_is_ctrl(const struct packet *pkt)
|
2024-06-14 19:24:27 +08:00
|
|
|
|
{
|
|
|
|
|
|
return pkt->meta.is_ctrl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-14 18:38:37 +08:00
|
|
|
|
void packet_set_claim(struct packet *pkt, bool claim)
|
2024-09-13 18:03:05 +08:00
|
|
|
|
{
|
2024-09-14 18:38:37 +08:00
|
|
|
|
pkt->meta.is_claim = claim;
|
2024-09-13 18:03:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-14 18:38:37 +08:00
|
|
|
|
bool packet_is_claim(const struct packet *pkt)
|
2024-09-13 18:03:05 +08:00
|
|
|
|
{
|
2024-09-14 18:38:37 +08:00
|
|
|
|
return pkt->meta.is_claim;
|
2024-09-13 18:03:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
void packet_set_direction(struct packet *pkt, enum packet_direction dir)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.direction = dir;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enum packet_direction packet_get_direction(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->meta.direction;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-09 14:57:12 +08:00
|
|
|
|
void packet_set_action(struct packet *pkt, enum packet_action action)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
pkt->meta.action = action;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-09 14:57:12 +08:00
|
|
|
|
enum packet_action packet_get_action(const struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
return pkt->meta.action;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-23 16:04:07 +08:00
|
|
|
|
void packet_set_timeval(struct packet *pkt, const struct timeval *tv)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->meta.tv = *tv;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const struct timeval *packet_get_timeval(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return &pkt->meta.tv;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-16 16:58:06 +08:00
|
|
|
|
void packet_set_user_data(struct packet *pkt, void *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
pkt->user_data = data;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void *packet_get_user_data(struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->user_data;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-24 17:07:05 +08:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
|
* 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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer_l3 = NULL;
|
|
|
|
|
|
const struct layer_private *layer_l4 = NULL;
|
|
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
layer_l3 = layer;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer_l3 = NULL;
|
|
|
|
|
|
const struct layer_private *layer_l4 = NULL;
|
|
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
layer_l3 = layer;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer_l3 = NULL;
|
|
|
|
|
|
const struct layer_private *layer_l4 = NULL;
|
|
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
layer_l3 = layer;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
layer_l3 = layer;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
|
|
|
|
|
|
{
|
2024-06-25 10:32:51 +08:00
|
|
|
|
tuple->domain = packet_get_domain(pkt);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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));
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer_l3 = NULL;
|
|
|
|
|
|
const struct layer_private *layer_l4 = NULL;
|
|
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-06-24 17:07:05 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
|
|
|
|
|
|
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
layer_l3 = layer;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (layer->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
2024-07-25 18:29:57 +08:00
|
|
|
|
tuple->addr_family = AF_INET6;
|
2024-07-09 11:17:03 +08:00
|
|
|
|
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
|
|
|
|
|
|
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2024-06-25 10:32:51 +08:00
|
|
|
|
tuple->domain = packet_get_domain(pkt);
|
2024-06-24 17:07:05 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-16 16:58:06 +08:00
|
|
|
|
/******************************************************************************
|
2024-08-16 17:07:52 +08:00
|
|
|
|
* layer uitls
|
2024-08-16 16:58:06 +08:00
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
int packet_get_layer_count(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->layers_used;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:55:06 +08:00
|
|
|
|
const struct layer *packet_get_layer_by_idx(const struct packet *pkt, int idx)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
2024-08-21 11:55:06 +08:00
|
|
|
|
const struct layer_private *layer = packet_get_layer(pkt, idx);
|
|
|
|
|
|
if (layer == NULL)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
2024-08-21 11:55:06 +08:00
|
|
|
|
return NULL;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-08-21 11:55:06 +08:00
|
|
|
|
return (const struct layer *)layer;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *packet_get_layer(const struct packet *pkt, int idx)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (idx < 0 || idx >= pkt->layers_used)
|
|
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
return &pkt->layers[idx];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *packet_get_innermost_layer(const struct packet *pkt, enum layer_proto proto)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
|
|
|
|
|
|
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
layer = &pkt->layers[i];
|
|
|
|
|
|
if (layer->proto == proto)
|
|
|
|
|
|
{
|
|
|
|
|
|
return layer;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *packet_get_outermost_layer(const struct packet *pkt, enum layer_proto proto)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *layer = NULL;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
|
|
|
|
|
|
for (int8_t i = 0; i < pkt->layers_used; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
layer = &pkt->layers[i];
|
|
|
|
|
|
if (layer->proto == proto)
|
|
|
|
|
|
{
|
|
|
|
|
|
return layer;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
|
* tunnel uitls
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
struct tunnel_detector
|
|
|
|
|
|
{
|
|
|
|
|
|
enum tunnel_type type;
|
|
|
|
|
|
int contain_layers;
|
2024-08-21 11:17:25 +08:00
|
|
|
|
int (*identify_func)(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2);
|
2024-08-16 16:58:06 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_ipv4_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2 __attribute__((unused)))
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && curr->proto == LAYER_PROTO_IPV4 &&
|
|
|
|
|
|
next1 && (next1->proto == LAYER_PROTO_IPV4 || next1->proto == LAYER_PROTO_IPV6))
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_ipv6_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2 __attribute__((unused)))
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && curr->proto == LAYER_PROTO_IPV6 &&
|
|
|
|
|
|
next1 && (next1->proto == LAYER_PROTO_IPV4 || next1->proto == LAYER_PROTO_IPV6))
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_gre_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2 __attribute__((unused)))
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
|
|
|
|
|
|
next1 && next1->proto == LAYER_PROTO_GRE)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_gtp_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
|
|
|
|
|
|
next1 && next1->proto == LAYER_PROTO_UDP &&
|
|
|
|
|
|
next2 && next2->proto == LAYER_PROTO_GTP_U)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_vxlan_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
|
|
|
|
|
|
next1 && next1->proto == LAYER_PROTO_UDP &&
|
|
|
|
|
|
next2 && next2->proto == LAYER_PROTO_VXLAN)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_l2tp_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
|
|
|
|
|
|
next1 && next1->proto == LAYER_PROTO_UDP &&
|
|
|
|
|
|
next2 && next2->proto == LAYER_PROTO_L2TP)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int is_teredo_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (curr && curr->proto == LAYER_PROTO_IPV4 &&
|
|
|
|
|
|
next1 && next1->proto == LAYER_PROTO_UDP &&
|
|
|
|
|
|
next2 && next2->proto == LAYER_PROTO_IPV6)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct tunnel_detector detectors[] = {
|
|
|
|
|
|
{TUNNEL_IPV4, 1, is_ipv4_tunnel},
|
|
|
|
|
|
{TUNNEL_IPV6, 1, is_ipv6_tunnel},
|
|
|
|
|
|
{TUNNEL_GRE, 2, is_gre_tunnel},
|
|
|
|
|
|
{TUNNEL_GTP, 3, is_gtp_tunnel},
|
|
|
|
|
|
{TUNNEL_VXLAN, 3, is_vxlan_tunnel},
|
|
|
|
|
|
{TUNNEL_L2TP, 3, is_l2tp_tunnel},
|
|
|
|
|
|
{TUNNEL_TEREDO, 2, is_teredo_tunnel},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// return index of detectors
|
2024-08-21 11:17:25 +08:00
|
|
|
|
static int detect_tunnel(const struct layer_private *curr, const struct layer_private *next1, const struct layer_private *next2)
|
2024-08-16 16:58:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < (int)(sizeof(detectors) / sizeof(detectors[0])); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (detectors[i].identify_func(curr, next1, next2))
|
|
|
|
|
|
{
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int packet_get_tunnel_count(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
int used = packet_get_layer_count(pkt);
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *curr = NULL;
|
|
|
|
|
|
const struct layer_private *next1 = NULL;
|
|
|
|
|
|
const struct layer_private *next2 = NULL;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < used; i++)
|
|
|
|
|
|
{
|
2024-08-21 11:17:25 +08:00
|
|
|
|
curr = packet_get_layer(pkt, i);
|
|
|
|
|
|
next1 = packet_get_layer(pkt, i + 1);
|
|
|
|
|
|
next2 = packet_get_layer(pkt, i + 2);
|
2024-08-16 16:58:06 +08:00
|
|
|
|
if (detect_tunnel(curr, next1, next2) >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// return 0: success
|
|
|
|
|
|
// return -1: failed
|
|
|
|
|
|
int packet_get_tunnel_by_idx(const struct packet *pkt, int idx, struct tunnel *out)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ret = -1;
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
int used = packet_get_layer_count(pkt);
|
2024-08-21 11:17:25 +08:00
|
|
|
|
const struct layer_private *curr = NULL;
|
|
|
|
|
|
const struct layer_private *next1 = NULL;
|
|
|
|
|
|
const struct layer_private *next2 = NULL;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
memset(out, 0, sizeof(struct tunnel));
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < used; i++)
|
|
|
|
|
|
{
|
2024-08-21 11:17:25 +08:00
|
|
|
|
curr = packet_get_layer(pkt, i);
|
|
|
|
|
|
next1 = packet_get_layer(pkt, i + 1);
|
|
|
|
|
|
next2 = packet_get_layer(pkt, i + 2);
|
2024-08-16 16:58:06 +08:00
|
|
|
|
ret = detect_tunnel(curr, next1, next2);
|
|
|
|
|
|
if (ret >= 0 && count++ == idx)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct tunnel_detector *hit = &detectors[ret];
|
|
|
|
|
|
out->type = hit->type;
|
|
|
|
|
|
out->layer_count = hit->contain_layers;
|
|
|
|
|
|
if (out->layer_count >= 1)
|
2024-08-21 11:55:06 +08:00
|
|
|
|
out->layers[0] = (const struct layer *)curr;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
if (out->layer_count >= 2)
|
2024-08-21 11:55:06 +08:00
|
|
|
|
out->layers[1] = (const struct layer *)next1;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
if (out->layer_count >= 3)
|
2024-08-21 11:55:06 +08:00
|
|
|
|
out->layers[2] = (const struct layer *)next2;
|
2024-08-16 16:58:06 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-16 17:07:52 +08:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
|
* load balance uitls
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t packet_ldbc_hash(const struct packet *pkt, enum packet_load_balance_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.addr_family == AF_INET)
|
|
|
|
|
|
{
|
|
|
|
|
|
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.addr_family == AF_INET)
|
|
|
|
|
|
{
|
|
|
|
|
|
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 PKT_LDBC_METH_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 PKT_LDBC_METH_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 PKT_LDBC_METH_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 PKT_LDBC_METH_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 PKT_LDBC_METH_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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
|
* other uitls
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
2024-06-24 17:07:05 +08:00
|
|
|
|
const char *packet_get_raw_data(const struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-06-24 17:07:05 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2024-08-08 16:17:40 +08:00
|
|
|
|
if (pkt == NULL || pkt->layers_used == 0)
|
2024-06-24 17:07:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
2024-07-11 14:13:34 +08:00
|
|
|
|
|
|
|
|
|
|
if (pkt->layers[pkt->layers_used - 1].pld_len)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pkt->layers[pkt->layers_used - 1].pld_ptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
2024-06-24 17:07:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t packet_get_payload_len(const struct packet *pkt)
|
|
|
|
|
|
{
|
2024-08-14 10:50:33 +08:00
|
|
|
|
if (pkt == NULL || pkt->layers_used == 0)
|
2024-06-24 17:07:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return pkt->layers[pkt->layers_used - 1].pld_len;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct packet *packet_new(uint16_t pkt_len)
|
|
|
|
|
|
{
|
2024-08-14 10:50:33 +08:00
|
|
|
|
struct packet *pkt = (struct packet *)calloc(1, sizeof(struct packet) + pkt_len);
|
2024-04-11 19:44:02 +08:00
|
|
|
|
if (pkt == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
pkt->data_len = pkt_len;
|
|
|
|
|
|
pkt->data_ptr = (const char *)pkt + sizeof(struct packet);
|
2024-06-14 19:24:27 +08:00
|
|
|
|
pkt->need_free = 1;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
|
|
|
|
|
|
return pkt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct packet *packet_dup(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pkt == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct packet *dup_pkt = packet_new(pkt->data_len);
|
|
|
|
|
|
if (dup_pkt == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
2024-05-15 11:40:00 +08:00
|
|
|
|
|
|
|
|
|
|
dup_pkt->layers_used = pkt->layers_used;
|
|
|
|
|
|
dup_pkt->layers_size = pkt->layers_size;
|
|
|
|
|
|
|
2024-04-11 19:44:02 +08:00
|
|
|
|
memcpy((char *)dup_pkt->data_ptr, pkt->data_ptr, pkt->data_len);
|
2024-05-15 11:40:00 +08:00
|
|
|
|
dup_pkt->data_len = pkt->data_len;
|
2024-06-14 19:24:27 +08:00
|
|
|
|
packet_set_action(dup_pkt, PACKET_ACTION_DROP);
|
2024-04-11 19:44:02 +08:00
|
|
|
|
|
|
|
|
|
|
for (int8_t i = 0; i < pkt->layers_used; i++)
|
|
|
|
|
|
{
|
2024-06-14 19:24:27 +08:00
|
|
|
|
dup_pkt->layers[i].proto = pkt->layers[i].proto;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
dup_pkt->layers[i].hdr_ptr = dup_pkt->data_ptr + pkt->layers[i].hdr_offset;
|
|
|
|
|
|
dup_pkt->layers[i].pld_ptr = dup_pkt->data_ptr + pkt->layers[i].hdr_offset + pkt->layers[i].hdr_len;
|
2024-05-15 11:40:00 +08:00
|
|
|
|
dup_pkt->layers[i].hdr_offset = pkt->layers[i].hdr_offset;
|
|
|
|
|
|
dup_pkt->layers[i].hdr_len = pkt->layers[i].hdr_len;
|
|
|
|
|
|
dup_pkt->layers[i].pld_len = pkt->layers[i].pld_len;
|
2024-04-11 19:44:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// update frag_layer
|
|
|
|
|
|
if (pkt->frag_layer)
|
|
|
|
|
|
{
|
|
|
|
|
|
dup_pkt->frag_layer = &dup_pkt->layers[pkt->frag_layer - pkt->layers];
|
|
|
|
|
|
}
|
2024-08-21 11:06:58 +08:00
|
|
|
|
memcpy(&dup_pkt->meta, &pkt->meta, sizeof(struct metadata));
|
|
|
|
|
|
packet_set_origin_ctx(dup_pkt, (void *)NULL);
|
2024-04-11 19:44:02 +08:00
|
|
|
|
|
|
|
|
|
|
return dup_pkt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 19:24:27 +08:00
|
|
|
|
void packet_free(struct packet *pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-09-14 18:38:37 +08:00
|
|
|
|
if (pkt)
|
2024-04-11 19:44:02 +08:00
|
|
|
|
{
|
2024-09-14 18:38:37 +08:00
|
|
|
|
if (packet_is_claim(pkt))
|
|
|
|
|
|
{
|
|
|
|
|
|
PACKET_LOG_ERROR("packet has been claimed and cannot be released, please check the module arrangement order");
|
|
|
|
|
|
assert(0);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pkt->need_free)
|
|
|
|
|
|
{
|
|
|
|
|
|
free((void *)pkt);
|
|
|
|
|
|
}
|
2024-05-08 18:24:26 +08:00
|
|
|
|
}
|
2024-06-17 11:41:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-24 17:07:05 +08:00
|
|
|
|
int packet_is_fragment(const struct packet *pkt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (pkt->frag_layer) ? 1 : 0;
|
|
|
|
|
|
}
|