#ifndef _PACKET_HELPERS_H #define _PACKET_HELPERS_H #ifdef __cpluscplus extern "C" { #endif #include #include #include #include #include "packet.h" #include "ipv4_helpers.h" struct metadata { // TODO }; /****************************************************************************** * metadata ******************************************************************************/ static inline struct metadata *metadata_dup(const struct metadata *metadata) { if (metadata == NULL) { return NULL; } struct metadata *metadata_dup = (struct metadata *)calloc(1, sizeof(struct metadata)); if (metadata_dup == NULL) { return NULL; } memcpy(metadata_dup, metadata, sizeof(struct metadata)); return metadata_dup; } static inline void metadata_free(struct metadata *metadata) { if (metadata) { free(metadata); metadata = NULL; } } static inline void packet_set0_metadata(struct packet *pkt, const struct metadata *metadata) { pkt->user_data = (const void *)metadata; } static inline const struct metadata *packet_get0_metadata(const struct packet *pkt) { return (const struct metadata *)pkt->user_data; } /****************************************************************************** * 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)); pkt_dup->user_data = NULL; 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 } #endif #endif