Add Packet/IPv4/TCP/UDP helpers API

This commit is contained in:
luwenpeng
2024-01-03 09:57:06 +08:00
parent 529234029f
commit 6b3fc4b560
16 changed files with 502 additions and 956 deletions

View File

@@ -6,74 +6,186 @@ extern "C"
{
#endif
#include <stdlib.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include "packet.h"
#include "ipv4_helpers.h"
struct metadata
{
// TODO
};
// metadata
struct metadata *metadata_dup(const struct metadata *metadata);
void metadata_free(struct metadata *metadata);
void packet_set0_metadata(struct packet *pkt, const struct metadata *metadata);
const struct metadata *packet_get0_metadata(const struct packet *pkt);
/******************************************************************************
* metadata
******************************************************************************/
// packet
struct packet *packet_dup(const struct packet *pkt);
void packet_free(struct packet *pkt);
static inline struct metadata *metadata_dup(const struct metadata *metadata)
{
if (metadata == NULL)
{
return NULL;
}
uint64_t packet_get_zone_id(const struct packet *pkt);
uint16_t packet_get_raw_len(const struct packet *pkt);
const char *packet_get0_raw_data(const struct packet *pkt);
struct metadata *metadata_dup = (struct metadata *)calloc(1, sizeof(struct metadata));
if (metadata_dup == NULL)
{
return NULL;
}
memcpy(metadata_dup, metadata, sizeof(struct metadata));
bool paket_is_fragment(const struct packet *pkt);
bool packet_has_tcp(const struct packet *pkt);
bool packet_has_udp(const struct packet *pkt);
return metadata_dup;
}
// foreach layer
uint8_t packet_get_layer_count(const struct packet *pkt);
enum layer_type packet_get_layer_type(const struct packet *pkt, uint8_t index);
const char *packet_get_layer_hdr_ptr(const struct packet *pkt, uint8_t index);
const char *packet_get_layer_pld_ptr(const struct packet *pkt, uint8_t index);
uint16_t packet_get_layer_hdr_len(const struct packet *pkt, uint8_t index);
uint16_t packet_get_layer_pld_len(const struct packet *pkt, uint8_t index);
static inline void metadata_free(struct metadata *metadata)
{
if (metadata)
{
free(metadata);
metadata = NULL;
}
}
// get tcp layer
const struct layer_record *packet_get0_tcp_layer(const struct packet *pkt);
const char *packet_get_tcp_hdr_ptr(const struct packet *pkt);
const char *packet_get_tcp_pld_ptr(const struct packet *pkt);
uint16_t packet_get_tcp_hdr_len(const struct packet *pkt);
uint16_t packet_get_tcp_pld_len(const struct packet *pkt);
uint16_t packet_get_tcp_sport(const struct packet *pkt);
uint16_t packet_get_tcp_dport(const struct packet *pkt);
uint32_t packet_get_tcp_seq(const struct packet *pkt);
uint32_t packet_get_tcp_ack(const struct packet *pkt);
uint8_t packet_get_tcp_flags(const struct packet *pkt);
bool packet_has_tcp_flag_urg(const struct packet *pkt);
bool packet_has_tcp_flag_ack(const struct packet *pkt);
bool packet_has_tcp_flag_psh(const struct packet *pkt);
bool packet_has_tcp_flag_rst(const struct packet *pkt);
bool packet_has_tcp_flag_syn(const struct packet *pkt);
bool packet_has_tcp_flag_fin(const struct packet *pkt);
static inline void packet_set0_metadata(struct packet *pkt, const struct metadata *metadata)
{
pkt->user_data = (const void *)metadata;
}
// get inner udp layer
const struct layer_record *packet_get0_inner_udp_layer(const struct packet *pkt);
const char *packet_get_inner_udp_hdr_ptr(const struct packet *pkt);
const char *packet_get_inner_udp_pld_ptr(const struct packet *pkt);
uint16_t packet_get_inner_udp_hdr_len(const struct packet *pkt);
uint16_t packet_get_inner_udp_pld_len(const struct packet *pkt);
uint16_t packet_get_inner_udp_sport(const struct packet *pkt);
uint16_t packet_get_inner_udp_dport(const struct packet *pkt);
static inline const struct metadata *packet_get0_metadata(const struct packet *pkt)
{
return (const struct metadata *)pkt->user_data;
}
// get outer udp layer
const struct layer_record *packet_get0_outer_udp_layer(const struct packet *pkt);
const char *packet_get_outer_udp_hdr_ptr(const struct packet *pkt);
const char *packet_get_outer_udp_pld_ptr(const struct packet *pkt);
uint16_t packet_get_outer_udp_hdr_len(const struct packet *pkt);
uint16_t packet_get_outer_udp_pld_len(const struct packet *pkt);
uint16_t packet_get_outer_udp_sport(const struct packet *pkt);
uint16_t packet_get_outer_udp_dport(const struct packet *pkt);
/******************************************************************************
* packet
******************************************************************************/
static inline bool paket_is_fragment(const struct packet *pkt)
{
for (int8_t i = 0; i < pkt->layers_used; i++)
{
if (pkt->layers[i].type == LAYER_TYPE_IPV4)
{
struct ip *ip_hdr = (struct ip *)pkt->layers[i].hdr_ptr;
if (ipv4_hdr_has_flag_mf(ip_hdr) || ipv4_hdr_get_frag_offset(ip_hdr))
{
return true;
}
}
if (pkt->layers[i].type == LAYER_TYPE_IPV6)
{
struct ip6_hdr *ip6_hdr = (struct ip6_hdr *)pkt->layers[i].hdr_ptr;
if (ip6_hdr->ip6_nxt == IPPROTO_FRAGMENT)
{
return true;
}
}
}
return false;
}
static inline struct packet *packet_dup(const struct packet *pkt)
{
if (pkt == NULL)
{
return NULL;
}
struct packet *pkt_dup = (struct packet *)calloc(1, sizeof(struct packet));
if (pkt_dup == NULL)
{
return NULL;
}
memcpy(pkt_dup, pkt, sizeof(struct packet));
if (pkt->data_len)
{
pkt_dup->data_ptr = (const char *)calloc(1, pkt->data_len);
if (pkt_dup->data_ptr == NULL)
{
free(pkt_dup);
return NULL;
}
memcpy((char *)pkt_dup->data_ptr, pkt->data_ptr, pkt->data_len);
for (int8_t i = 0; i < pkt->layers_used; i++)
{
pkt_dup->layers[i].hdr_ptr = pkt_dup->data_ptr + pkt->layers[i].hdr_offset;
pkt_dup->layers[i].pld_ptr = pkt_dup->data_ptr + pkt->layers[i].hdr_offset + pkt->layers[i].hdr_len;
}
}
return pkt_dup;
}
static inline void packet_free(struct packet *pkt)
{
if (pkt)
{
if (pkt->data_ptr)
{
free((char *)pkt->data_ptr);
pkt->data_ptr = NULL;
}
free(pkt);
pkt = NULL;
}
}
static inline uint64_t packet_get_zone_id(const struct packet *pkt)
{
return pkt->zone_id;
}
static inline uint16_t packet_get_raw_len(const struct packet *pkt)
{
return pkt->data_len;
}
static inline const char *packet_get0_raw_data(const struct packet *pkt)
{
return pkt->data_ptr;
}
static inline uint8_t packet_get_layer_count(const struct packet *pkt)
{
return pkt->layers_used;
}
static inline const struct layer_record *packet_get_layer(const struct packet *pkt, uint8_t index)
{
return &pkt->layers[index];
}
static inline enum layer_type layer_get_type(const struct layer_record *layer)
{
return layer->type;
}
static inline const char *layer_get_hdr_ptr(const struct layer_record *layer)
{
return layer->hdr_ptr;
}
static inline const char *layer_get_pld_ptr(const struct layer_record *layer)
{
return layer->pld_ptr;
}
static inline uint16_t layer_get_hdr_len(const struct layer_record *layer)
{
return layer->hdr_len;
}
static inline uint16_t layer_get_pld_len(const struct layer_record *layer)
{
return layer->pld_len;
}
#ifdef __cpluscplus
}