165 lines
5.6 KiB
C
165 lines
5.6 KiB
C
#ifndef _PACKET_PUB_H
|
|
#define _PACKET_PUB_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include "stellar/tuple.h"
|
|
|
|
enum layer_type
|
|
{
|
|
// L2 -- data link layer
|
|
LAYER_TYPE_ETHER = 1 << 0,
|
|
LAYER_TYPE_PPP = 1 << 1,
|
|
LAYER_TYPE_HDLC = 1 << 2,
|
|
LAYER_TYPE_L2 = (LAYER_TYPE_ETHER | LAYER_TYPE_PPP | LAYER_TYPE_HDLC),
|
|
|
|
// L2 -- tunnel
|
|
LAYER_TYPE_VLAN = 1 << 3,
|
|
LAYER_TYPE_PPPOE = 1 << 4,
|
|
LAYER_TYPE_MPLS = 1 << 5,
|
|
LAYER_TYPE_L2_TUN = (LAYER_TYPE_VLAN | LAYER_TYPE_PPPOE | LAYER_TYPE_MPLS),
|
|
|
|
// L3 -- network layer
|
|
LAYER_TYPE_IPV4 = 1 << 6,
|
|
LAYER_TYPE_IPV6 = 1 << 7,
|
|
LAYER_TYPE_L3 = (LAYER_TYPE_IPV4 | LAYER_TYPE_IPV6),
|
|
|
|
// L3 -- tunnel
|
|
LAYER_TYPE_GRE = 1 << 8,
|
|
LAYER_TYPE_L3_TUN = (LAYER_TYPE_GRE),
|
|
|
|
// L4 -- transport layer
|
|
LAYER_TYPE_UDP = 1 << 9,
|
|
LAYER_TYPE_TCP = 1 << 10,
|
|
LAYER_TYPE_ICMP = 1 << 11,
|
|
LAYER_TYPE_ICMP6 = 1 << 12,
|
|
LAYER_TYPE_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP | LAYER_TYPE_ICMP | LAYER_TYPE_ICMP6),
|
|
|
|
// L4 -- tunnel
|
|
LAYER_TYPE_VXLAN = 1 << 13,
|
|
LAYER_TYPE_GTPV1_U = 1 << 14,
|
|
|
|
// ALL
|
|
LAYER_TYPE_ALL = (LAYER_TYPE_L2 | LAYER_TYPE_L2_TUN | LAYER_TYPE_L3 | LAYER_TYPE_L3_TUN | LAYER_TYPE_L4 | LAYER_TYPE_VXLAN | LAYER_TYPE_GTPV1_U),
|
|
};
|
|
|
|
struct packet_layer
|
|
{
|
|
enum layer_type type;
|
|
const char *hdr_ptr; // header pointer
|
|
const char *pld_ptr; // payload pointer
|
|
uint16_t hdr_offset; // header offset from data_ptr
|
|
uint16_t hdr_len; // header length
|
|
uint16_t pld_len; // payload length
|
|
};
|
|
|
|
// return 0: found
|
|
// return -1: not found
|
|
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
|
|
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
|
|
|
|
// return 0: found
|
|
// return -1: not found
|
|
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
|
|
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
|
|
|
|
// return 0: found
|
|
// return -1: not found
|
|
int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
|
|
int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
|
|
|
|
const struct packet_layer *packet_get_innermost_layer(const struct packet *pkt, enum layer_type type);
|
|
const struct packet_layer *packet_get_outermost_layer(const struct packet *pkt, enum layer_type type);
|
|
|
|
/******************************************************************************
|
|
* Utils
|
|
******************************************************************************/
|
|
|
|
#define MAX_SID_NUM 8
|
|
struct sid_list
|
|
{
|
|
uint16_t sid[MAX_SID_NUM];
|
|
int used;
|
|
};
|
|
|
|
enum packet_direction
|
|
{
|
|
PACKET_DIRECTION_OUTGOING = 0, // Internal -> External: 0
|
|
PACKET_DIRECTION_INCOMING = 1, // External -> Internal: 1
|
|
};
|
|
|
|
enum packet_action
|
|
{
|
|
PACKET_ACTION_FORWARD = 0,
|
|
PACKET_ACTION_DROP = 1,
|
|
};
|
|
|
|
enum packet_direction packet_get_direction(const struct packet *pkt);
|
|
uint64_t packet_get_session_id(const struct packet *pkt);
|
|
void packet_prepend_sid_list(struct packet *pkt, const struct sid_list *list);
|
|
|
|
int8_t packet_get_layers_number(const struct packet *pkt);
|
|
const struct packet_layer *packet_get_layer(const struct packet *pkt, int8_t idx);
|
|
|
|
const char *packet_get_data(const struct packet *pkt);
|
|
uint16_t packet_get_len(const struct packet *pkt);
|
|
|
|
const char *packet_get_payload(const struct packet *pkt);
|
|
uint16_t packet_get_payload_len(const struct packet *pkt);
|
|
|
|
void packet_set_action(struct packet *pkt, enum packet_action action);
|
|
enum packet_action packet_get_action(const struct packet *pkt);
|
|
|
|
/*
|
|
******************************************************************************
|
|
* Example: getting the innermost TCP layer
|
|
******************************************************************************
|
|
*
|
|
* |<--------------------------- pkt->data_len -------------------------->|
|
|
* +----------+------+-----+-------+------+---------------+---------------+
|
|
* | Ethernet | IPv4 | UDP | GTP-U | IPv4 | TCP | Payload |
|
|
* +----------+------+-----+-------+------+---------------+---------------+
|
|
* ^ ^ ^
|
|
* | | |
|
|
* |<------------ hdr_offset ------------>|<-- hdr_len -->|<-- pld_len -->|
|
|
* | | |
|
|
* | | +-- pld_ptr
|
|
* | +-- hdr_ptr
|
|
* +-- data_ptr
|
|
*
|
|
* const struct packet_layer *tcp_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_TCP);
|
|
* const struct tcphdr *hdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
|
|
* uint16_t src_port = ntohs(hdr->th_sport);
|
|
* uint16_t dst_port = ntohs(hdr->th_dport);
|
|
* uint32_t seq = ntohl(hdr->th_seq);
|
|
* uint32_t ack = ntohl(hdr->th_ack);
|
|
*
|
|
******************************************************************************
|
|
* Example: foreach layer in packet
|
|
******************************************************************************
|
|
*
|
|
* // inorder
|
|
* int8_t layers = packet_get_layers_number(pkt);
|
|
* for (int8_t i = 0; i < layers; i++)
|
|
* {
|
|
* const struct packet_layer *layer = packet_get_layer(pkt, i);
|
|
* printf("layer[%d]: type=%d, hdr_offset=%d, hdr_len=%d, pld_len=%d\n", i, layer->type, layer->hdr_offset, layer->hdr_len, layer->pld_len);
|
|
* }
|
|
*
|
|
* // reverse
|
|
* for (int8_t i = layers - 1; i >= 0; i--)
|
|
* {
|
|
* const struct packet_layer *layer = packet_get_layer(pkt, i);
|
|
* printf("layer[%d]: type=%d, hdr_offset=%d, hdr_len=%d, pld_len=%d\n", i, layer->type, layer->hdr_offset, layer->hdr_len, layer->pld_len);
|
|
* }
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|