diff options
| author | luwenpeng <[email protected]> | 2024-06-14 19:24:27 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2024-06-14 19:24:27 +0800 |
| commit | de4c15f43c1fee821723bd629d46193dacd7735b (patch) | |
| tree | 8c2de35af5906a3ded70a69398eacf1f9cff65dd /include | |
| parent | 1f78881cbb42f35e2be64b89dc7847e247af38b3 (diff) | |
Refactored packet API to support struct layer (using union to contain different types of encapsulation headers)
Diffstat (limited to 'include')
| -rw-r--r-- | include/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | include/stellar/layer.h | 99 | ||||
| -rw-r--r-- | include/stellar/packet.h | 163 | ||||
| -rw-r--r-- | include/stellar/session.h | 2 | ||||
| -rw-r--r-- | include/stellar/stellar.h | 2 |
5 files changed, 116 insertions, 151 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 91b7269..e231241 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,4 +1,5 @@ install(FILES stellar/utils.h DESTINATION include/stellar/ COMPONENT LIBRARIES) +install(FILES stellar/layer.h DESTINATION include/stellar/ COMPONENT LIBRARIES) install(FILES stellar/packet.h DESTINATION include/stellar/ COMPONENT LIBRARIES) install(FILES stellar/session.h DESTINATION include/stellar/ COMPONENT LIBRARIES) install(FILES stellar/stellar.h DESTINATION include/stellar/ COMPONENT LIBRARIES) diff --git a/include/stellar/layer.h b/include/stellar/layer.h new file mode 100644 index 0000000..fce1315 --- /dev/null +++ b/include/stellar/layer.h @@ -0,0 +1,99 @@ +#ifndef _LAYER_H +#define _LAYER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define __FAVOR_BSD 1 +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <netinet/icmp6.h> +#include <netinet/ip_icmp.h> +#include <linux/if_ether.h> +#include <linux/mpls.h> + +enum layer_proto +{ + LAYER_PROTO_NONE = 0, + + // L2 -- data link layer + LAYER_PROTO_ETHER = 1, + LAYER_PROTO_PWETH = 2, + LAYER_PROTO_PPP = 3, + LAYER_PROTO_L2TP = 4, + + // L2 -- tunnel + LAYER_PROTO_VLAN = 21, + LAYER_PROTO_PPPOE = 22, + LAYER_PROTO_MPLS = 23, + + // L3 -- network layer + LAYER_PROTO_IPV4 = 31, + LAYER_PROTO_IPV6 = 32, + LAYER_PROTO_IPAH = 33, + + // L3 -- tunnel + LAYER_PROTO_GRE = 41, + + // L4 -- transport layer + LAYER_PROTO_UDP = 51, + LAYER_PROTO_TCP = 52, + LAYER_PROTO_ICMP = 53, + LAYER_PROTO_ICMP6 = 54, + + // L4 -- tunnel + LAYER_PROTO_VXLAN = 61, + LAYER_PROTO_GTPV1_U = 62, +}; + +struct layer +{ + enum layer_proto proto; + uint16_t payload_len; + uint16_t header_len; + union + { + struct ethhdr *eth; + struct ip *ip4; + struct ip6_hdr *ip6; + struct tcphdr *tcp; + struct udphdr *udp; + struct icmphdr *icmp4; + struct icmp6_hdr *icmp6; + struct mpls_label *mpls; + const char *raw; + } header; + const char *payload; +}; + +int packet_get_layer_count(const struct packet *pkt); +// return 0: success +// return -1: failed +int packet_get_layer(const struct packet *pkt, int idx, struct layer *out); + +#define PACKET_FOREACH_LAYER_INORDER(pkt, layer) \ + for (int i = 0; i < packet_get_layer_count(pkt) && packet_get_layer(pkt, i, &layer) == 0; i++) + +#define PACKET_FOREACH_LAYER_REVERSE(pkt, layer) \ + for (int i = packet_get_layer_count(pkt) - 1; i >= 0 && packet_get_layer(pkt, i, &layer) == 0; i--) + +#define PACKET_GETALL_LAYERS(pkt, layers) \ + { \ + int size = sizeof(layers) / sizeof(layers[0]); \ + int num = packet_get_layer_count(pkt); \ + if (num > size) \ + num = size; \ + for (int i = 0; i < num && packet_get_layer(pkt, i, &layers[i]) == 0; i++) \ + /* void */; \ + return num; \ + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/stellar/packet.h b/include/stellar/packet.h index 09d0726..62b03e7 100644 --- a/include/stellar/packet.h +++ b/include/stellar/packet.h @@ -1,180 +1,45 @@ -#ifndef _PACKET_PUB_H -#define _PACKET_PUB_H +#ifndef _PACKET_H +#define _PACKET_H #ifdef __cplusplus extern "C" { #endif -#include <string.h> -#include <arpa/inet.h> -#define __FAVOR_BSD 1 -#include <netinet/tcp.h> -#include <netinet/udp.h> -#include <netinet/ip.h> -#include <netinet/ip6.h> +#include <stdint.h> -enum layer_proto +#define MAX_SIDS 8 +struct sids { - LAYER_PROTO_NONE = 0, - - // L2 -- data link layer - LAYER_PROTO_ETHER = 1, - LAYER_PROTO_PWETH = 2, - LAYER_PROTO_PPP = 3, - LAYER_PROTO_L2TP = 4, - - // L2 -- tunnel - LAYER_PROTO_VLAN = 21, - LAYER_PROTO_PPPOE = 22, - LAYER_PROTO_MPLS = 23, - - // L3 -- network layer - LAYER_PROTO_IPV4 = 31, - LAYER_PROTO_IPV6 = 32, - LAYER_PROTO_IPAH = 33, - - // L3 -- tunnel - LAYER_PROTO_GRE = 41, - - // L4 -- transport layer - LAYER_PROTO_UDP = 51, - LAYER_PROTO_TCP = 52, - LAYER_PROTO_ICMP = 53, - LAYER_PROTO_ICMP6 = 54, - - // L4 -- tunnel - LAYER_PROTO_VXLAN = 61, - LAYER_PROTO_GTPV1_U = 62, -}; - -struct raw_layer -{ - enum layer_proto 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 -}; - -#define MAX_SID_NUM 8 -struct sid_list -{ - uint16_t sid[MAX_SID_NUM]; + uint16_t sid[MAX_SIDS]; int used; }; +void packet_prepend_sids(struct packet *pkt, const struct sids *sids); enum packet_direction { PACKET_DIRECTION_OUTGOING = 0, // Internal -> External: 0 PACKET_DIRECTION_INCOMING = 1, // External -> Internal: 1 }; +enum packet_direction packet_get_direction(const struct packet *pkt); enum packet_action { - PACKET_ACTION_FORWARD = 0, + PACKET_ACTION_FORWARD = 0, // must be zero PACKET_ACTION_DROP = 1, + PACKET_ACTION_DEFER = 2, // TODO }; +void packet_set_action(struct packet *pkt, enum packet_action action); +enum packet_action packet_get_action(const struct packet *pkt); -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); -int packet_get_layer_count(const struct packet *pkt); -const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx); - -const char *packet_get_data(const struct packet *pkt); -uint16_t packet_get_len(const struct packet *pkt); +const char *packet_get_raw_data(const struct packet *pkt); +uint16_t packet_get_raw_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); - -struct address -{ - uint8_t family; // AF_INET or AF_INET6 - union - { - struct in_addr v4; /* network order */ - struct in6_addr v6; /* network order */ - } data; -}; - -static inline int packet_get_addr(const struct packet *pkt, struct address *src_addr, struct address *dst_addr) -{ - const struct ip *ip4_hdr = NULL; - const struct ip6_hdr *ip6_hdr = NULL; - const struct raw_layer *layer = NULL; - int num = packet_get_layer_count(pkt); - for (int i = num - 1; i >= 0; i--) - { - layer = packet_get_raw_layer(pkt, i); - if (layer->type == LAYER_PROTO_IPV4) - { - ip4_hdr = (const struct ip *)layer->hdr_ptr; - if (src_addr != NULL) - { - src_addr->family = AF_INET; - src_addr->data.v4.s_addr = ip4_hdr->ip_src.s_addr; - } - if (dst_addr != NULL) - { - dst_addr->family = AF_INET; - dst_addr->data.v4.s_addr = ip4_hdr->ip_dst.s_addr; - } - return 0; - } - if (layer->type == LAYER_PROTO_IPV6) - { - ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; - if (src_addr != NULL) - { - src_addr->family = AF_INET6; - src_addr->data.v6 = ip6_hdr->ip6_src; - } - if (dst_addr != NULL) - { - dst_addr->family = AF_INET6; - dst_addr->data.v6 = ip6_hdr->ip6_dst; - } - return 0; - } - } - - return -1; -} - -static inline int packet_get_port(const struct packet *pkt, uint16_t *src_port, uint16_t *dst_port) -{ - const struct tcphdr *tcp_hdr = NULL; - const struct udphdr *udp_hdr = NULL; - const struct raw_layer *layer = NULL; - int num = packet_get_layer_count(pkt); - for (int i = num - 1; i >= 0; i--) - { - layer = packet_get_raw_layer(pkt, i); - if (layer->type == LAYER_PROTO_TCP) - { - tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; - src_port != NULL ? *src_port = tcp_hdr->th_sport : 0; - dst_port != NULL ? *dst_port = tcp_hdr->th_dport : 0; - return 0; - } - if (layer->type == LAYER_PROTO_UDP) - { - udp_hdr = (const struct udphdr *)layer->hdr_ptr; - src_port != NULL ? *src_port = udp_hdr->uh_sport : 0; - dst_port != NULL ? *dst_port = udp_hdr->uh_dport : 0; - return 0; - } - } - - return -1; -} - #ifdef __cplusplus } #endif diff --git a/include/stellar/session.h b/include/stellar/session.h index 959ab50..5fb58fa 100644 --- a/include/stellar/session.h +++ b/include/stellar/session.h @@ -133,7 +133,7 @@ enum session_type session_get_type(const struct session *sess); enum session_state session_get_current_state(const struct session *sess); const struct packet *session_get0_current_packet(const struct session *sess); -const char *session_get0_current_payload(const struct session *sess, size_t *payload_len); +const char *session_get0_current_payload(const struct session *sess, uint16_t *payload_len); enum closing_reason session_get_closing_reason(const struct session *sess); enum session_direction session_get_direction(const struct session *sess); diff --git a/include/stellar/stellar.h b/include/stellar/stellar.h index 43d911f..598b279 100644 --- a/include/stellar/stellar.h +++ b/include/stellar/stellar.h @@ -56,7 +56,7 @@ int stellar_inject_tcp_rst(struct stellar *st, const struct session *sess, enum int stellar_inject_tcp_fin(struct stellar *st, const struct session *sess, enum flow_direction inject_dir); int stellar_inject_tcp_payload(struct stellar *st, const struct session *sess, enum flow_direction inject_dir, const char *payload, uint16_t len); int stellar_inject_udp_payload(struct stellar *st, const struct session *sess, enum flow_direction inject_dir, const char *payload, uint16_t len); -int stellar_inject_ctrl_msg(struct stellar *st, const struct session *sess, const struct sid_list *sids, const char *msg, uint16_t len); +int stellar_inject_ctrl_msg(struct stellar *st, const struct session *sess, const struct sids *sids, const char *msg, uint16_t len); int stellar_main(int argc, char **argv); |
