#ifndef _PACKET_H #define _PACKET_H #ifdef __cplusplus extern "C" { #endif #include "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_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP), // L4 -- tunnel LAYER_TYPE_VXLAN = 1 << 11, LAYER_TYPE_GTPV1_U = 1 << 12, // 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 ******************************************************************************/ int8_t packet_get_layers(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); int packet_need_drop(const struct packet *pkt); void packet_set_drop(struct packet *pkt); void packet_set_ctrl(struct packet *pkt); int packet_is_ctrl(const struct packet *pkt); void packet_set_direction(struct packet *pkt, int dir); int packet_get_direction(const struct packet *pkt); // 1: E2I, 0: I2E void packet_set_session_id(struct packet *pkt, uint64_t sess_id); uint64_t packet_get_session_id(const struct packet *pkt); void packet_set_sid_list(struct packet *pkt, uint16_t *sid, int num); int packet_get_sid_list(const struct packet *pkt, uint16_t *sid, int num); // return number of sid void packet_prepend_sid_list(struct packet *pkt, uint16_t *sid, int num); void packet_append_sid_list(struct packet *pkt, uint16_t *sid, int num); /* ****************************************************************************** * 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(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