refactor: move packet_layer / packet_tunnel to packet.cpp

This commit is contained in:
luwenpeng
2024-08-16 16:58:06 +08:00
parent a2d68bb853
commit 60a4666427
28 changed files with 257 additions and 289 deletions

View File

@@ -122,6 +122,16 @@ enum packet_action packet_get_action(const struct packet *pkt)
return pkt->meta.action;
}
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;
}
/******************************************************************************
* tuple uitls
******************************************************************************/
@@ -444,6 +454,244 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
}
}
/******************************************************************************
* layer layer
******************************************************************************/
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);
if (raw == NULL)
{
return -1;
}
else
{
layer_convert(raw, 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;
}
/******************************************************************************
* tunnel uitls
******************************************************************************/
struct tunnel_detector
{
enum tunnel_type type;
int contain_layers;
int (*identify_func)(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2);
};
static int is_ipv4_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2 __attribute__((unused)))
{
if (curr && curr->proto == LAYER_PROTO_IPV4 &&
next1 && (next1->proto == LAYER_PROTO_IPV4 || next1->proto == LAYER_PROTO_IPV6))
{
return 1;
}
return 0;
}
static int is_ipv6_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2 __attribute__((unused)))
{
if (curr && curr->proto == LAYER_PROTO_IPV6 &&
next1 && (next1->proto == LAYER_PROTO_IPV4 || next1->proto == LAYER_PROTO_IPV6))
{
return 1;
}
return 0;
}
static int is_gre_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2 __attribute__((unused)))
{
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
next1 && next1->proto == LAYER_PROTO_GRE)
{
return 1;
}
return 0;
}
static int is_gtp_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2)
{
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;
}
static int is_vxlan_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2)
{
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;
}
static int is_l2tp_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2)
{
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;
}
static int is_teredo_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2)
{
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
static int detect_tunnel(const struct raw_layer *curr, const struct raw_layer *next1, const struct raw_layer *next2)
{
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);
const struct raw_layer *curr = NULL;
const struct raw_layer *next1 = NULL;
const struct raw_layer *next2 = NULL;
for (int i = 0; i < used; i++)
{
curr = packet_get_raw_layer(pkt, i);
next1 = packet_get_raw_layer(pkt, i + 1);
next2 = packet_get_raw_layer(pkt, i + 2);
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);
const struct raw_layer *curr = NULL;
const struct raw_layer *next1 = NULL;
const struct raw_layer *next2 = NULL;
memset(out, 0, sizeof(struct tunnel));
for (int i = 0; i < used; i++)
{
curr = packet_get_raw_layer(pkt, i);
next1 = packet_get_raw_layer(pkt, i + 1);
next2 = packet_get_raw_layer(pkt, i + 2);
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)
layer_convert(curr, &out->layers[0]);
if (out->layer_count >= 2)
layer_convert(next1, &out->layers[1]);
if (out->layer_count >= 3)
layer_convert(next2, &out->layers[2]);
return 0;
}
}
return -1;
}
/******************************************************************************
* other uitls
******************************************************************************/
@@ -561,13 +809,3 @@ void layer_convert(const struct raw_layer *in, struct layer *out)
out->hdr_len = in->hdr_len;
out->hdr.raw = (char *)in->hdr_ptr;
}
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;
}