refactor: packet module (split to parse/build/layer/tunnel/utils)
This commit is contained in:
@@ -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)
|
||||
@@ -198,4 +558,4 @@ void layer_convert(const struct raw_layer *in, struct layer *out)
|
||||
out->proto = in->proto;
|
||||
out->hdr_len = in->hdr_len;
|
||||
out->hdr.raw = (char *)in->hdr_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user