diff --git a/src/duplicated_packet_filter/duplicated_packet_filter.cpp b/src/duplicated_packet_filter/duplicated_packet_filter.cpp index 0de9e06..662455f 100644 --- a/src/duplicated_packet_filter/duplicated_packet_filter.cpp +++ b/src/duplicated_packet_filter/duplicated_packet_filter.cpp @@ -4,6 +4,8 @@ #include "tcp_utils.h" #include "udp_utils.h" #include "ipv4_utils.h" +#include "packet_def.h" +#include "packet_layer.h" #include "duplicated_packet_filter.h" struct duplicated_packet_key diff --git a/src/duplicated_packet_filter/duplicated_packet_filter.h b/src/duplicated_packet_filter/duplicated_packet_filter.h index 14b88d5..6ac4288 100644 --- a/src/duplicated_packet_filter/duplicated_packet_filter.h +++ b/src/duplicated_packet_filter/duplicated_packet_filter.h @@ -7,11 +7,6 @@ extern "C" // Duplicated Packet Filter for IPv4 Packet -#include "log.h" -#include "packet_priv.h" - -#define DUPLICATED_PACKET_FILTER_LOG_ERROR(format, ...) LOG_ERROR("duplicated packet filter", format, ##__VA_ARGS__) - struct duplicated_packet_filter; struct duplicated_packet_filter *duplicated_packet_filter_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now); void duplicated_packet_filter_free(struct duplicated_packet_filter *filter); diff --git a/src/duplicated_packet_filter/test/gtest_duplicated_packet_filter.cpp b/src/duplicated_packet_filter/test/gtest_duplicated_packet_filter.cpp index 00e3246..3d458b8 100644 --- a/src/duplicated_packet_filter/test/gtest_duplicated_packet_filter.cpp +++ b/src/duplicated_packet_filter/test/gtest_duplicated_packet_filter.cpp @@ -1,7 +1,9 @@ #include +#include "tuple.h" +#include "packet_def.h" +#include "packet_parse.h" #include "duplicated_packet_filter.h" -#include "packet_priv.h" /****************************************************************************** * [Protocols in frame: eth:ethertype:ip:ipv6:tcp] diff --git a/src/evicted_session_filter/evicted_session_filter.cpp b/src/evicted_session_filter/evicted_session_filter.cpp index 8a11bc6..42d6845 100644 --- a/src/evicted_session_filter/evicted_session_filter.cpp +++ b/src/evicted_session_filter/evicted_session_filter.cpp @@ -1,5 +1,6 @@ #include +#include "tuple.h" #include "dablooms.h" #include "udp_utils.h" #include "ipv4_utils.h" diff --git a/src/evicted_session_filter/evicted_session_filter.h b/src/evicted_session_filter/evicted_session_filter.h index 480e3c2..65864f0 100644 --- a/src/evicted_session_filter/evicted_session_filter.h +++ b/src/evicted_session_filter/evicted_session_filter.h @@ -5,11 +5,6 @@ extern "C" { #endif -#include "log.h" -#include "tuple.h" - -#define EVICTED_SESSION_FILTER_LOG_ERROR(format, ...) LOG_ERROR("evicted session filter", format, ##__VA_ARGS__) - struct evicted_session_filter *evicted_session_filter_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now); void evicted_session_filter_free(struct evicted_session_filter *filter); diff --git a/src/evicted_session_filter/test/gtest_evicted_session_filter.cpp b/src/evicted_session_filter/test/gtest_evicted_session_filter.cpp index 4ae721d..8482f7f 100644 --- a/src/evicted_session_filter/test/gtest_evicted_session_filter.cpp +++ b/src/evicted_session_filter/test/gtest_evicted_session_filter.cpp @@ -1,5 +1,6 @@ #include +#include "tuple.h" #include "evicted_session_filter.h" TEST(EVICTED_SESSION_FILTER, TEST) diff --git a/src/ip_reassembly/ip_reassembly.cpp b/src/ip_reassembly/ip_reassembly.cpp index d025980..de33b0b 100644 --- a/src/ip_reassembly/ip_reassembly.cpp +++ b/src/ip_reassembly/ip_reassembly.cpp @@ -3,14 +3,19 @@ #include #include -#include "packet_priv.h" +#include "log.h" +#include "packet_def.h" #include "packet_utils.h" +#include "packet_parse.h" #include "crc32_hash.h" #include "checksum.h" #include "ipv4_utils.h" #include "ipv6_utils.h" #include "ip_reassembly.h" +#define IP_REASSEMBLE_DEBUG(format, ...) LOG_DEBUG("ip_reassembly", format, ##__VA_ARGS__) +#define IP_REASSEMBLE_ERROR(format, ...) LOG_ERROR("ip_reassembly", format, ##__VA_ARGS__) + #define IPV4_KEYLEN 1 #define IPV6_KEYLEN 4 #define PRIME_VALUE 0xeaad8405 diff --git a/src/ip_reassembly/ip_reassembly.h b/src/ip_reassembly/ip_reassembly.h index 6162396..736cc1f 100644 --- a/src/ip_reassembly/ip_reassembly.h +++ b/src/ip_reassembly/ip_reassembly.h @@ -5,12 +5,6 @@ extern "C" { #endif -#include "packet_priv.h" -#include "log.h" - -#define IP_REASSEMBLE_DEBUG(format, ...) LOG_DEBUG("ip_reassembly", format, ##__VA_ARGS__) -#define IP_REASSEMBLE_ERROR(format, ...) LOG_ERROR("ip_reassembly", format, ##__VA_ARGS__) - struct ip_reassembly_options { uint8_t enable; diff --git a/src/ip_reassembly/test/gtest_utils.h b/src/ip_reassembly/test/gtest_utils.h index 5ff9b8d..84b9976 100644 --- a/src/ip_reassembly/test/gtest_utils.h +++ b/src/ip_reassembly/test/gtest_utils.h @@ -12,8 +12,10 @@ extern "C" #include "ipv4_utils.h" #include "ipv6_utils.h" #include "ip_reassembly.h" -#include "packet_priv.h" +#include "packet_def.h" #include "packet_utils.h" +#include "packet_parse.h" +#include "packet_layer.h" static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr) { diff --git a/src/packet/CMakeLists.txt b/src/packet/CMakeLists.txt index 7e95c34..a86d537 100644 --- a/src/packet/CMakeLists.txt +++ b/src/packet/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(packet packet.cpp packet_build.cpp packet_utils.cpp packet_layer.cpp packet_tunnel.cpp checksum.cpp) +add_library(packet packet_parse.cpp packet_build.cpp packet_utils.cpp packet_ldbc.cpp packet_layer.cpp packet_tunnel.cpp checksum.cpp) target_include_directories(packet PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash) target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/include) diff --git a/src/packet/packet_build.cpp b/src/packet/packet_build.cpp index 404c7c9..277e120 100644 --- a/src/packet/packet_build.cpp +++ b/src/packet/packet_build.cpp @@ -1,13 +1,16 @@ #include -#include "packet_build.h" +#include "log.h" #include "checksum.h" #include "tcp_utils.h" #include "udp_utils.h" #include "ipv4_utils.h" #include "ipv6_utils.h" -#include "packet_priv.h" +#include "packet_def.h" #include "packet_utils.h" +#include "packet_layer.h" +#include "packet_parse.h" +#include "packet_build.h" #define PACKET_BUILD_LOG_DEBUG(format, ...) LOG_DEBUG("packet build", format, ##__VA_ARGS__) #define PACKET_BUILD_LOG_ERROR(format, ...) LOG_ERROR("packet build", format, ##__VA_ARGS__) diff --git a/src/packet/packet_def.h b/src/packet/packet_def.h new file mode 100644 index 0000000..3e24343 --- /dev/null +++ b/src/packet/packet_def.h @@ -0,0 +1,62 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "stellar/layer.h" +#include "stellar/packet.h" + +#define PACKET_MAX_LAYERS 32 + +#define MAX_ROUTE_CTX 64 +struct route_ctx +{ + char data[MAX_ROUTE_CTX]; + int used; +}; + +struct metadata +{ + struct route_ctx route_ctx; + struct sids sids; + + uint64_t session_id; + uint64_t domain_id; + uint16_t link_id; + int is_ctrl; + + enum packet_direction direction; + enum packet_action action; + const void *origin_ctx; +}; + +struct raw_layer +{ + enum layer_proto proto; + 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 +}; + +struct packet +{ + struct raw_layer layers[PACKET_MAX_LAYERS]; + struct raw_layer *frag_layer; // fragment layer + int8_t layers_used; + int8_t layers_size; + int8_t need_free; + + const char *data_ptr; + uint16_t data_len; + uint16_t trim_len; // trim eth padding + + struct metadata meta; +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/packet_layer.cpp b/src/packet/packet_layer.cpp index 9776362..3104cd6 100644 --- a/src/packet/packet_layer.cpp +++ b/src/packet/packet_layer.cpp @@ -1,6 +1,12 @@ -#include "packet_priv.h" +#include "packet_def.h" +#include "packet_layer.h" #include "packet_utils.h" +int packet_get_layer_count(const struct packet *pkt) +{ + return pkt->layers_used; +} + int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out) { const struct raw_layer *raw = packet_get_raw_layer(pkt, idx); @@ -14,3 +20,44 @@ int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out return 0; } } + +const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx) +{ + if (idx < 0 || idx >= pkt->layers_used) + { + return NULL; + } + return &pkt->layers[idx]; +} + +const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto) +{ + const struct raw_layer *layer = NULL; + + for (int8_t i = pkt->layers_used - 1; i >= 0; i--) + { + layer = &pkt->layers[i]; + if (layer->proto == proto) + { + return layer; + } + } + + return NULL; +} + +const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto) +{ + const struct raw_layer *layer = NULL; + + for (int8_t i = 0; i < pkt->layers_used; i++) + { + layer = &pkt->layers[i]; + if (layer->proto == proto) + { + return layer; + } + } + + return NULL; +} diff --git a/src/packet/packet_layer.h b/src/packet/packet_layer.h new file mode 100644 index 0000000..8121ea5 --- /dev/null +++ b/src/packet/packet_layer.h @@ -0,0 +1,18 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "stellar/layer.h" + +int packet_get_layer_count(const struct packet *pkt); +int packet_get_layer_by_idx(const struct packet *pkt, int idx, struct layer *out); +const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx); +const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto); +const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto); + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/packet_ldbc.cpp b/src/packet/packet_ldbc.cpp new file mode 100644 index 0000000..5a94c60 --- /dev/null +++ b/src/packet/packet_ldbc.cpp @@ -0,0 +1,122 @@ +#include "tuple.h" +#include "uthash.h" +#include "packet_ldbc.h" +#include "packet_utils.h" + +uint64_t packet_ldbc_hash(const struct packet *pkt, enum load_balance ldbc, enum packet_direction direction) +{ + uint64_t temp = 0; + uint64_t hash_value = 1; + + int inner_addr_len = 0; + int outer_addr_len = 0; + const char *inner_src_addr = NULL; + const char *inner_dst_addr = NULL; + const char *outer_src_addr = NULL; + const char *outer_dst_addr = NULL; + + struct tuple2 inner_addr; + struct tuple2 outer_addr; + + if (pkt == NULL) + { + return hash_value; + } + + if (packet_get_innermost_tuple2(pkt, &inner_addr) == -1) + { + return hash_value; + } + + if (packet_get_outermost_tuple2(pkt, &outer_addr) == -1) + { + return hash_value; + } + + if (inner_addr.ip_type == IP_TYPE_V4) + { + inner_src_addr = (const char *)&inner_addr.src_addr.v4; + inner_dst_addr = (const char *)&inner_addr.dst_addr.v4; + inner_addr_len = sizeof(struct in_addr); + } + else + { + inner_src_addr = (const char *)&inner_addr.src_addr.v6; + inner_dst_addr = (const char *)&inner_addr.dst_addr.v6; + inner_addr_len = sizeof(struct in6_addr); + } + + if (outer_addr.ip_type == IP_TYPE_V4) + { + outer_src_addr = (const char *)&outer_addr.src_addr.v4; + outer_dst_addr = (const char *)&outer_addr.dst_addr.v4; + outer_addr_len = sizeof(struct in_addr); + } + else + { + outer_src_addr = (const char *)&outer_addr.src_addr.v6; + outer_dst_addr = (const char *)&outer_addr.dst_addr.v6; + outer_addr_len = sizeof(struct in6_addr); + } + + switch (ldbc) + { + case LDBC_HASH_OUTERMOST_INT_IP: + if (direction == PACKET_DIRECTION_INCOMING) + { + // direction 1: E2I + HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value); + } + else + { + // direction 0: I2E + HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); + } + break; + case LDBC_HASH_OUTERMOST_EXT_IP: + if (direction == PACKET_DIRECTION_INCOMING) + { + // direction 1: E2I + HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); + } + else + { + // direction 0: I2E + HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value); + } + break; + case LDBC_HASH_OUTERMOST_INT_EXT_IP: + HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); + HASH_VALUE(outer_dst_addr, outer_addr_len, temp); + hash_value = hash_value ^ temp; + break; + case LDBC_HASH_INNERMOST_INT_IP: + if (direction == PACKET_DIRECTION_INCOMING) + { + // direction 1: E2I + HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value); + } + else + { + // direction 0: I2E + HASH_VALUE(inner_src_addr, inner_addr_len, hash_value); + } + break; + case LDBC_HASH_INNERMOST_EXT_IP: + if (direction == PACKET_DIRECTION_INCOMING) + { + // direction 1: E2I + HASH_VALUE(inner_src_addr, inner_addr_len, hash_value); + } + else + { + // direction 0: I2E + HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value); + } + break; + default: + return hash_value; + } + + return hash_value; +} \ No newline at end of file diff --git a/src/packet/packet_ldbc.h b/src/packet/packet_ldbc.h new file mode 100644 index 0000000..76d174f --- /dev/null +++ b/src/packet/packet_ldbc.h @@ -0,0 +1,25 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#include "stellar/packet.h" + +enum load_balance +{ + LDBC_HASH_OUTERMOST_INT_IP = 1, + LDBC_HASH_OUTERMOST_EXT_IP = 2, + LDBC_HASH_OUTERMOST_INT_EXT_IP = 3, + LDBC_HASH_INNERMOST_INT_IP = 4, + LDBC_HASH_INNERMOST_EXT_IP = 5, +}; + +uint64_t packet_ldbc_hash(const struct packet *pkt, enum load_balance ldbc, enum packet_direction direction); + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/packet.cpp b/src/packet/packet_parse.cpp similarity index 67% rename from src/packet/packet.cpp rename to src/packet/packet_parse.cpp index e8f86ff..58b2998 100644 --- a/src/packet/packet.cpp +++ b/src/packet/packet_parse.cpp @@ -4,9 +4,7 @@ #include #include -#include "uthash.h" -#include "packet_priv.h" -#include "packet_utils.h" +#include "log.h" #include "eth_utils.h" #include "gre_utils.h" #include "udp_utils.h" @@ -17,47 +15,46 @@ #include "l2tp_utils.h" #include "vlan_utils.h" #include "vxlan_utils.h" +#include "packet_def.h" +#include "packet_parse.h" #define likely(expr) __builtin_expect((expr), 1) #define unlikely(expr) __builtin_expect((expr), 0) -#define PACKET_LOG_DATA_INSUFFICIENCY(pkt, layer) \ - { \ - PACKET_LOG_WARN("pkt: %p, layer: %s, data insufficiency", \ - (pkt), layer_proto_to_str(layer)); \ +#define PACKET_PARSE_LOG_DEBUG(format, ...) void(0) // LOG_DEBUG("packet parse", format, ##__VA_ARGS__) +#define PACKET_PARSE_LOG_WARN(format, ...) LOG_WARN("packet parse", format, ##__VA_ARGS__) +#define PACKET_PARSE_LOG_ERROR(format, ...) LOG_ERROR("packet parse", format, ##__VA_ARGS__) + +#define PACKET_LOG_DATA_INSUFFICIENCY(pkt, layer) \ + { \ + PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, data insufficiency", \ + (pkt), layer_proto_to_str(layer)); \ } -#define PACKET_LOG_UNSUPPORT_PROTO(pkt, layer, next_proto) \ - { \ - PACKET_LOG_WARN("pkt: %p, layer: %s, unsupport next proto %d", \ - (pkt), layer_proto_to_str(layer), (next_proto)); \ +#define PACKET_LOG_UNSUPPORT_PROTO(pkt, layer, next_proto) \ + { \ + PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, unsupport next proto %d", \ + (pkt), layer_proto_to_str(layer), (next_proto)); \ } -#define PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto) \ - { \ - PACKET_LOG_WARN("pkt: %p, layer: l3, unsupport next eth proto %s", \ - (pkt), eth_proto_to_str(next_proto)); \ +#define PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto) \ + { \ + PACKET_PARSE_LOG_WARN("pkt: %p, layer: l3, unsupport next eth proto %s", \ + (pkt), eth_proto_to_str(next_proto)); \ } -#define PACKET_LOG_UNSUPPORT_IPPROTO(pkt, next_proto) \ - { \ - PACKET_LOG_WARN("pkt: %p, layer: l4, unsupport next ip proto %s", \ - (pkt), ip_proto_to_str(next_proto)); \ +#define PACKET_LOG_UNSUPPORT_IPPROTO(pkt, next_proto) \ + { \ + PACKET_PARSE_LOG_WARN("pkt: %p, layer: l4, unsupport next ip proto %s", \ + (pkt), ip_proto_to_str(next_proto)); \ } /****************************************************************************** * Static API ******************************************************************************/ -static inline const char *ldbc_method_to_str(enum ldbc_method method); static inline const char *layer_proto_to_str(enum layer_proto proto); - -static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple); -static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple); -static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain); - static inline struct raw_layer *get_free_layer(struct packet *pkt); - static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len); // 数据链路层 @@ -94,25 +91,6 @@ static inline const char *parse_l4(struct packet *pkt, uint8_t next_proto, const * Private API -- Utils ******************************************************************************/ -static inline const char *ldbc_method_to_str(enum ldbc_method method) -{ - switch (method) - { - case LDBC_METHOD_HASH_INT_IP: - return "outter_internal_ip"; - case LDBC_METHOD_HASH_EXT_IP: - return "outter_external_ip"; - case LDBC_METHOD_HASH_INT_IP_AND_EXT_IP: - return "outter_internal_ip_and_external_ip"; - case LDBC_METHOD_HASH_INNERMOST_INT_IP: - return "inner_internal_ip"; - case LDBC_METHOD_HASH_INNERMOST_EXT_IP: - return "inner_external_ip"; - default: - return "unknown"; - } -} - static inline const char *layer_proto_to_str(enum layer_proto proto) { switch (proto) @@ -156,106 +134,6 @@ static inline const char *layer_proto_to_str(enum layer_proto proto) } } -static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple) -{ - const struct ip *ipv4 = NULL; - const struct ip6_hdr *ipv6 = NULL; - - switch (proto) - { - case LAYER_PROTO_IPV4: - ipv4 = (const struct ip *)data; - tuple->ip_type = IP_TYPE_V4; - tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr; - tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr; - break; - case LAYER_PROTO_IPV6: - ipv6 = (const struct ip6_hdr *)data; - tuple->ip_type = IP_TYPE_V6; - tuple->src_addr.v6 = ipv6->ip6_src; - tuple->dst_addr.v6 = ipv6->ip6_dst; - break; - default: - break; - } -} - -static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple) -{ - const struct ip *ipv4 = NULL; - const struct ip6_hdr *ipv6 = NULL; - const struct tcphdr *tcp = NULL; - const struct udphdr *udp = NULL; - - switch (proto) - { - case LAYER_PROTO_TCP: - tcp = (const struct tcphdr *)data; - tuple->src_port = tcp->th_sport; - tuple->dst_port = tcp->th_dport; - break; - case LAYER_PROTO_UDP: - udp = (const struct udphdr *)data; - tuple->src_port = udp->uh_sport; - tuple->dst_port = udp->uh_dport; - break; - case LAYER_PROTO_IPV4: - ipv4 = (const struct ip *)data; - tuple->ip_type = IP_TYPE_V4; - tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr; - tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr; - break; - case LAYER_PROTO_IPV6: - ipv6 = (const struct ip6_hdr *)data; - tuple->ip_type = IP_TYPE_V6; - tuple->src_addr.v6 = ipv6->ip6_src; - tuple->dst_addr.v6 = ipv6->ip6_dst; - break; - default: - break; - } -} - -static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain) -{ - const struct ip *ipv4 = NULL; - const struct ip6_hdr *ipv6 = NULL; - const struct tcphdr *tcp = NULL; - const struct udphdr *udp = NULL; - - tuple->domain = domain; - - switch (proto) - { - case LAYER_PROTO_TCP: - tcp = (const struct tcphdr *)data; - tuple->ip_proto = IPPROTO_TCP; - tuple->src_port = tcp->th_sport; - tuple->dst_port = tcp->th_dport; - break; - case LAYER_PROTO_UDP: - udp = (const struct udphdr *)data; - tuple->ip_proto = IPPROTO_UDP; - tuple->src_port = udp->uh_sport; - tuple->dst_port = udp->uh_dport; - break; - case LAYER_PROTO_IPV4: - ipv4 = (const struct ip *)data; - tuple->ip_type = IP_TYPE_V4; - tuple->src_addr.v4.s_addr = ipv4->ip_src.s_addr; - tuple->dst_addr.v4.s_addr = ipv4->ip_dst.s_addr; - break; - case LAYER_PROTO_IPV6: - ipv6 = (const struct ip6_hdr *)data; - tuple->ip_type = IP_TYPE_V6; - tuple->src_addr.v6 = ipv6->ip6_src; - tuple->dst_addr.v6 = ipv6->ip6_dst; - break; - default: - break; - } -} - static inline struct raw_layer *get_free_layer(struct packet *pkt) { if (pkt->layers_used >= pkt->layers_size) @@ -266,19 +144,19 @@ static inline struct raw_layer *get_free_layer(struct packet *pkt) return &pkt->layers[pkt->layers_used]; } -#define SET_LAYER(_pkt, _layer, _proto, _hdr_len, _data, _len, _trim) \ - { \ - (_layer)->proto = (_proto); \ - (_layer)->hdr_offset = (_pkt)->data_len - (_pkt)->trim_len - (_len); \ - (_layer)->hdr_ptr = (_data); \ - (_layer)->hdr_len = (_hdr_len); \ - (_layer)->pld_ptr = (_data) + (_hdr_len); \ - (_layer)->pld_len = (_len) - (_hdr_len) - (_trim); \ - (_pkt)->trim_len += (_trim); \ - (_pkt)->layers_used++; \ - PACKET_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \ - (_pkt)->layers_used - 1, (_pkt)->layers_size, layer_proto_to_str((_proto)), \ - (_layer)->hdr_offset, (_layer)->hdr_ptr, (_layer)->hdr_len, (_layer)->pld_ptr, (_layer)->pld_len); \ +#define SET_LAYER(_pkt, _layer, _proto, _hdr_len, _data, _len, _trim) \ + { \ + (_layer)->proto = (_proto); \ + (_layer)->hdr_offset = (_pkt)->data_len - (_pkt)->trim_len - (_len); \ + (_layer)->hdr_ptr = (_data); \ + (_layer)->hdr_len = (_hdr_len); \ + (_layer)->pld_ptr = (_data) + (_hdr_len); \ + (_layer)->pld_len = (_len) - (_hdr_len) - (_trim); \ + (_pkt)->trim_len += (_trim); \ + (_pkt)->layers_used++; \ + PACKET_PARSE_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \ + (_pkt)->layers_used - 1, (_pkt)->layers_size, layer_proto_to_str((_proto)), \ + (_layer)->hdr_offset, (_layer)->hdr_ptr, (_layer)->hdr_len, (_layer)->pld_ptr, (_layer)->pld_len); \ } /****************************************************************************** @@ -701,7 +579,7 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1 } if (unlikely(total_len < hdr_len)) { - PACKET_LOG_ERROR("packet %p ip total_len %d < hdr_len %d", pkt, total_len, hdr_len); + PACKET_PARSE_LOG_ERROR("packet %p ip total_len %d < hdr_len %d", pkt, total_len, hdr_len); return data; } uint16_t trim_len = len - total_len; @@ -710,7 +588,7 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1 // ip fragmented if (ipv4_hdr_get_mf_flag(hdr) || ipv4_hdr_get_frag_offset(hdr)) { - PACKET_LOG_WARN("packet %p ip layer %p is fragmented", pkt, layer); + PACKET_PARSE_LOG_WARN("packet %p ip layer %p is fragmented", pkt, layer); pkt->frag_layer = layer; return layer->pld_ptr; } @@ -800,7 +678,7 @@ static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint1 // ipv6 fragment if (next_proto == IPPROTO_FRAGMENT) { - PACKET_LOG_WARN("packet %p ipv6 layer %p is fragmented", pkt, layer); + PACKET_PARSE_LOG_WARN("packet %p ipv6 layer %p is fragmented", pkt, layer); pkt->frag_layer = layer; return layer->pld_ptr; } @@ -1208,399 +1086,3 @@ void packet_print(const struct packet *pkt) } } } - -// return 0 : found -// return -1 : not found -int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple2)); - const struct raw_layer *layer = NULL; - - for (int8_t i = pkt->layers_used - 1; i >= 0; i--) - { - layer = &pkt->layers[i]; - - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple); - return 0; - } - } - - return -1; -} - -// return 0 : found -// return -1 : not found -int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple2)); - const struct raw_layer *layer = NULL; - - for (int8_t i = 0; i < pkt->layers_used; i++) - { - layer = &pkt->layers[i]; - - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple); - return 0; - } - } - - return -1; -} - -// return 0 : found -// return -1 : not found -int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple4)); - const struct raw_layer *layer_l3 = NULL; - const struct raw_layer *layer_l4 = NULL; - const struct raw_layer *layer = NULL; - - for (int8_t i = pkt->layers_used - 1; i >= 0; i--) - { - layer = &pkt->layers[i]; - - // first get L4 layer - if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP) - { - layer_l4 = layer; - continue; - } - - // second get L3 layer - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - layer_l3 = layer; - break; - } - } - - if (layer_l3 && layer_l4) - { - set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple); - set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple); - return 0; - } - else - { - return -1; - } -} - -// return 0 : found -// return -1 : not found -int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple4)); - const struct raw_layer *layer_l3 = NULL; - const struct raw_layer *layer_l4 = NULL; - const struct raw_layer *layer = NULL; - - for (int8_t i = 0; i < pkt->layers_used; i++) - { - layer = &pkt->layers[i]; - - // first get L3 layer - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - layer_l3 = layer; - continue; - } - - // second get L4 layer - if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP) - { - layer_l4 = layer; - break; - } - } - - if (layer_l3 && layer_l4) - { - set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple); - set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple); - return 0; - } - else - { - return -1; - } -} - -// return 0 : found -// return -1 : not found -int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple6)); - const struct raw_layer *layer_l3 = NULL; - const struct raw_layer *layer_l4 = NULL; - const struct raw_layer *layer = NULL; - uint64_t domain = packet_get_domain_id(pkt); - - for (int8_t i = pkt->layers_used - 1; i >= 0; i--) - { - layer = &pkt->layers[i]; - - // first get L4 layer - if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP) - { - layer_l4 = layer; - continue; - } - - // second get L3 layer - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - layer_l3 = layer; - break; - } - } - - if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) - { - set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain); - set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain); - return 0; - } - else - { - return -1; - } -} - -// return 0 : found -// return -1 : not found -int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple) -{ - memset(tuple, 0, sizeof(struct tuple6)); - const struct raw_layer *layer_l3 = NULL; - const struct raw_layer *layer_l4 = NULL; - const struct raw_layer *layer = NULL; - uint64_t domain = packet_get_domain_id(pkt); - - for (int8_t i = 0; i < pkt->layers_used; i++) - { - layer = &pkt->layers[i]; - - // first get L3 layer - if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6) - { - layer_l3 = layer; - continue; - } - - // second get L4 layer - if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP) - { - layer_l4 = layer; - break; - } - } - - if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) - { - set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain); - set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain); - return 0; - } - else - { - return -1; - } -} - -const char *packet_get_raw_data(const struct packet *pkt) -{ - return pkt->data_ptr; -} - -uint16_t packet_get_raw_len(const struct packet *pkt) -{ - return pkt->data_len; -} - -const char *packet_get_payload(const struct packet *pkt) -{ - if (pkt->layers_used == 0) - { - return NULL; - } - return pkt->layers[pkt->layers_used - 1].pld_ptr; -} - -uint16_t packet_get_payload_len(const struct packet *pkt) -{ - if (pkt->layers_used == 0) - { - return 0; - } - return pkt->layers[pkt->layers_used - 1].pld_len; -} - -int packet_get_layer_count(const struct packet *pkt) -{ - return pkt->layers_used; -} - -const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx) -{ - if (idx < 0 || idx >= pkt->layers_used) - { - return NULL; - } - return &pkt->layers[idx]; -} - -const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto) -{ - const struct raw_layer *layer = NULL; - - for (int8_t i = pkt->layers_used - 1; i >= 0; i--) - { - layer = &pkt->layers[i]; - if (layer->proto == proto) - { - return layer; - } - } - - return NULL; -} - -const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto) -{ - const struct raw_layer *layer = NULL; - - for (int8_t i = 0; i < pkt->layers_used; i++) - { - layer = &pkt->layers[i]; - if (layer->proto == proto) - { - return layer; - } - } - - return NULL; -} - -uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, enum packet_direction direction) -{ - uint64_t temp = 0; - uint64_t hash_value = 1; - - int inner_addr_len = 0; - int outer_addr_len = 0; - const char *inner_src_addr = NULL; - const char *inner_dst_addr = NULL; - const char *outer_src_addr = NULL; - const char *outer_dst_addr = NULL; - - struct tuple2 inner_addr; - struct tuple2 outer_addr; - - if (pkt == NULL) - { - return hash_value; - } - - if (packet_get_innermost_tuple2(pkt, &inner_addr) == -1) - { - return hash_value; - } - - if (packet_get_outermost_tuple2(pkt, &outer_addr) == -1) - { - return hash_value; - } - - if (inner_addr.ip_type == IP_TYPE_V4) - { - inner_src_addr = (const char *)&inner_addr.src_addr.v4; - inner_dst_addr = (const char *)&inner_addr.dst_addr.v4; - inner_addr_len = sizeof(struct in_addr); - } - else - { - inner_src_addr = (const char *)&inner_addr.src_addr.v6; - inner_dst_addr = (const char *)&inner_addr.dst_addr.v6; - inner_addr_len = sizeof(struct in6_addr); - } - - if (outer_addr.ip_type == IP_TYPE_V4) - { - outer_src_addr = (const char *)&outer_addr.src_addr.v4; - outer_dst_addr = (const char *)&outer_addr.dst_addr.v4; - outer_addr_len = sizeof(struct in_addr); - } - else - { - outer_src_addr = (const char *)&outer_addr.src_addr.v6; - outer_dst_addr = (const char *)&outer_addr.dst_addr.v6; - outer_addr_len = sizeof(struct in6_addr); - } - - switch (method) - { - case LDBC_METHOD_HASH_INT_IP: - if (direction == PACKET_DIRECTION_INCOMING) - { - // direction 1: E2I - HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value); - } - else - { - // direction 0: I2E - HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); - } - break; - case LDBC_METHOD_HASH_EXT_IP: - if (direction == PACKET_DIRECTION_INCOMING) - { - // direction 1: E2I - HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); - } - else - { - // direction 0: I2E - HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value); - } - break; - case LDBC_METHOD_HASH_INT_IP_AND_EXT_IP: - HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); - HASH_VALUE(outer_dst_addr, outer_addr_len, temp); - hash_value = hash_value ^ temp; - break; - case LDBC_METHOD_HASH_INNERMOST_INT_IP: - if (direction == PACKET_DIRECTION_INCOMING) - { - // direction 1: E2I - HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value); - } - else - { - // direction 0: I2E - HASH_VALUE(inner_src_addr, inner_addr_len, hash_value); - } - break; - case LDBC_METHOD_HASH_INNERMOST_EXT_IP: - if (direction == PACKET_DIRECTION_INCOMING) - { - // direction 1: E2I - HASH_VALUE(inner_src_addr, inner_addr_len, hash_value); - } - else - { - // direction 0: I2E - HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value); - } - break; - default: - return hash_value; - } - - return hash_value; -} \ No newline at end of file diff --git a/src/packet/packet_parse.h b/src/packet/packet_parse.h new file mode 100644 index 0000000..bbd8ea3 --- /dev/null +++ b/src/packet/packet_parse.h @@ -0,0 +1,15 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +const char *packet_parse(struct packet *pkt, const char *data, uint16_t len); +void packet_print(const struct packet *pkt); + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/packet_priv.h b/src/packet/packet_priv.h deleted file mode 100644 index c0a6e5f..0000000 --- a/src/packet/packet_priv.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "log.h" -#include "tuple.h" -#include "stellar/layer.h" -#include "stellar/packet.h" - -#define PACKET_MAX_LAYERS 32 -#define PACKET_LOG_ERROR(format, ...) LOG_ERROR("packet", format, ##__VA_ARGS__) -#define PACKET_LOG_WARN(format, ...) LOG_WARN("packet", format, ##__VA_ARGS__) -#define PACKET_LOG_DEBUG(format, ...) void(0) - -enum ldbc_method -{ - LDBC_METHOD_HASH_INT_IP = 1, - LDBC_METHOD_HASH_EXT_IP = 2, - LDBC_METHOD_HASH_INT_IP_AND_EXT_IP = 3, - LDBC_METHOD_HASH_INNERMOST_INT_IP = 4, - LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5, -}; - -#define MAX_ROUTE_CTX 64 -struct route_ctx -{ - char data[MAX_ROUTE_CTX]; - int used; -}; - -struct metadata -{ - struct route_ctx route_ctx; - struct sids sids; - - uint64_t session_id; - uint64_t domain_id; - uint16_t link_id; - int is_ctrl; - - enum packet_direction direction; - enum packet_action action; - const void *origin_ctx; -}; - -struct raw_layer -{ - enum layer_proto proto; - 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 -}; - -struct packet -{ - struct raw_layer layers[PACKET_MAX_LAYERS]; - struct raw_layer *frag_layer; // fragment layer - int8_t layers_used; - int8_t layers_size; - int8_t need_free; - - const char *data_ptr; - uint16_t data_len; - uint16_t trim_len; // trim eth padding - - struct metadata meta; -}; - -// return innermost payload -const char *packet_parse(struct packet *pkt, const char *data, uint16_t len); -void packet_print(const struct packet *pkt); - -// 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); - -int packet_get_layer_count(const struct packet *pkt); -const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx); -const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto type); -const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto type); - -// direction: PACKET_DIRECTION_OUTGOING = 0 (Internal -> External) -// direction: PACKET_DIRECTION_INCOMING = 1 (External -> Internal) -uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, enum packet_direction direction); - -#ifdef __cplusplus -} -#endif diff --git a/src/packet/packet_tunnel.cpp b/src/packet/packet_tunnel.cpp index d3b2dd1..f122a79 100644 --- a/src/packet/packet_tunnel.cpp +++ b/src/packet/packet_tunnel.cpp @@ -1,8 +1,9 @@ #include #include "stellar/tunnel.h" -#include "packet_priv.h" +#include "packet_def.h" #include "packet_utils.h" +#include "packet_layer.h" struct tunnel_detector { diff --git a/src/packet/packet_utils.cpp b/src/packet/packet_utils.cpp index 26ce4fc..6b249f8 100644 --- a/src/packet/packet_utils.cpp +++ b/src/packet/packet_utils.cpp @@ -1,8 +1,16 @@ #include -#include "packet_priv.h" +#include "log.h" +#include "tuple.h" +#include "tcp_utils.h" +#include "udp_utils.h" +#include "ipv4_utils.h" +#include "ipv6_utils.h" +#include "packet_def.h" #include "packet_utils.h" +#define PACKET_UTILS_LOG_ERROR(format, ...) LOG_ERROR("packet utils", format, ##__VA_ARGS__) + /****************************************************************************** * metadata utils ******************************************************************************/ @@ -31,7 +39,7 @@ void packet_prepend_sids(struct packet *pkt, const struct sids *sids) { if (pkt->meta.sids.used + sids->used > MAX_SIDS) { - PACKET_LOG_ERROR("sids overflow"); + PACKET_UTILS_LOG_ERROR("sids overflow"); return; } else @@ -118,13 +126,360 @@ const void *packet_get_origin_ctx(const struct packet *pkt) return pkt->meta.origin_ctx; } +/****************************************************************************** + * tuple uitls + ******************************************************************************/ + +// return 0 : found +// return -1 : not found +int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple2)); + const struct raw_layer *layer = NULL; + + for (int8_t i = pkt->layers_used - 1; i >= 0; i--) + { + layer = &pkt->layers[i]; + + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + return 0; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + return 0; + } + } + + return -1; +} + +// return 0 : found +// return -1 : not found +int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple2)); + const struct raw_layer *layer = NULL; + + for (int8_t i = 0; i < pkt->layers_used; i++) + { + layer = &pkt->layers[i]; + + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + return 0; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + return 0; + } + } + + return -1; +} + +// return 0 : found +// return -1 : not found +int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple4)); + const struct raw_layer *layer_l3 = NULL; + const struct raw_layer *layer_l4 = NULL; + const struct raw_layer *layer = NULL; + + for (int8_t i = pkt->layers_used - 1; i >= 0; i--) + { + layer = &pkt->layers[i]; + + // first get L4 layer + if (layer->proto == LAYER_PROTO_UDP) + { + const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr; + tuple->src_port = udp_hdr->uh_sport; + tuple->dst_port = udp_hdr->uh_dport; + layer_l4 = layer; + continue; + } + if (layer->proto == LAYER_PROTO_TCP) + { + const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; + tuple->src_port = tcp_hdr->th_sport; + tuple->dst_port = tcp_hdr->th_dport; + layer_l4 = layer; + continue; + } + + // second get L3 layer + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + layer_l3 = layer; + break; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + layer_l3 = layer; + break; + } + } + + if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) + { + return 0; + } + else + { + return -1; + } +} + +// return 0 : found +// return -1 : not found +int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple4)); + const struct raw_layer *layer_l3 = NULL; + const struct raw_layer *layer_l4 = NULL; + const struct raw_layer *layer = NULL; + + for (int8_t i = 0; i < pkt->layers_used; i++) + { + layer = &pkt->layers[i]; + + // first get L3 layer + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + layer_l3 = layer; + continue; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + layer_l3 = layer; + continue; + } + + // second get L4 layer + if (layer->proto == LAYER_PROTO_UDP) + { + const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr; + tuple->src_port = udp_hdr->uh_sport; + tuple->dst_port = udp_hdr->uh_dport; + layer_l4 = layer; + break; + } + if (layer->proto == LAYER_PROTO_TCP) + { + const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; + tuple->src_port = tcp_hdr->th_sport; + tuple->dst_port = tcp_hdr->th_dport; + layer_l4 = layer; + break; + } + } + + if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) + { + return 0; + } + else + { + return -1; + } +} + +// return 0 : found +// return -1 : not found +int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple6)); + const struct raw_layer *layer_l3 = NULL; + const struct raw_layer *layer_l4 = NULL; + const struct raw_layer *layer = NULL; + uint64_t domain = packet_get_domain_id(pkt); + + for (int8_t i = pkt->layers_used - 1; i >= 0; i--) + { + layer = &pkt->layers[i]; + + // first get L4 layer + if (layer->proto == LAYER_PROTO_UDP) + { + const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr; + tuple->ip_proto = IPPROTO_UDP; + tuple->src_port = udp_hdr->uh_sport; + tuple->dst_port = udp_hdr->uh_dport; + layer_l4 = layer; + continue; + } + if (layer->proto == LAYER_PROTO_TCP) + { + const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; + tuple->ip_proto = IPPROTO_TCP; + tuple->src_port = tcp_hdr->th_sport; + tuple->dst_port = tcp_hdr->th_dport; + layer_l4 = layer; + continue; + } + + // second get L3 layer + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + layer_l3 = layer; + break; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + layer_l3 = layer; + break; + } + } + + if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) + { + tuple->domain = packet_get_domain_id(pkt); + return 0; + } + else + { + return -1; + } +} + +// return 0 : found +// return -1 : not found +int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple) +{ + memset(tuple, 0, sizeof(struct tuple6)); + const struct raw_layer *layer_l3 = NULL; + const struct raw_layer *layer_l4 = NULL; + const struct raw_layer *layer = NULL; + uint64_t domain = packet_get_domain_id(pkt); + + for (int8_t i = 0; i < pkt->layers_used; i++) + { + layer = &pkt->layers[i]; + + // first get L3 layer + if (layer->proto == LAYER_PROTO_IPV4) + { + const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V4; + tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr); + tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr); + layer_l3 = layer; + continue; + } + if (layer->proto == LAYER_PROTO_IPV6) + { + const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + tuple->ip_type = IP_TYPE_V6; + tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr); + tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr); + layer_l3 = layer; + continue; + } + + // second get L4 layer + if (layer->proto == LAYER_PROTO_UDP) + { + const struct udphdr *udp_hdr = (const struct udphdr *)layer->hdr_ptr; + tuple->ip_proto = IPPROTO_UDP; + tuple->src_port = udp_hdr->uh_sport; + tuple->dst_port = udp_hdr->uh_dport; + layer_l4 = layer; + break; + } + if (layer->proto == LAYER_PROTO_TCP) + { + const struct tcphdr *tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; + tuple->ip_proto = IPPROTO_TCP; + tuple->src_port = tcp_hdr->th_sport; + tuple->dst_port = tcp_hdr->th_dport; + layer_l4 = layer; + break; + } + } + + if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1) + { + tuple->domain = packet_get_domain_id(pkt); + return 0; + } + else + { + return -1; + } +} + /****************************************************************************** * other uitls ******************************************************************************/ -int packet_is_fragment(const struct packet *pkt) +const char *packet_get_raw_data(const struct packet *pkt) { - return (pkt->frag_layer) ? 1 : 0; + return pkt->data_ptr; +} + +uint16_t packet_get_raw_len(const struct packet *pkt) +{ + return pkt->data_len; +} + +const char *packet_get_payload(const struct packet *pkt) +{ + if (pkt->layers_used == 0) + { + return NULL; + } + return pkt->layers[pkt->layers_used - 1].pld_ptr; +} + +uint16_t packet_get_payload_len(const struct packet *pkt) +{ + if (pkt->layers_used == 0) + { + return 0; + } + return pkt->layers[pkt->layers_used - 1].pld_len; } struct packet *packet_new(uint16_t pkt_len) @@ -188,6 +543,11 @@ void packet_free(struct packet *pkt) } } +int packet_is_fragment(const struct packet *pkt) +{ + return (pkt->frag_layer) ? 1 : 0; +} + void layer_convert(const struct raw_layer *in, struct layer *out) { if (in == NULL || out == NULL) @@ -198,4 +558,4 @@ void layer_convert(const struct raw_layer *in, struct layer *out) out->proto = in->proto; out->hdr_len = in->hdr_len; out->hdr.raw = (char *)in->hdr_ptr; -} \ No newline at end of file +} diff --git a/src/packet/packet_utils.h b/src/packet/packet_utils.h index d71daef..3e4c4f9 100644 --- a/src/packet/packet_utils.h +++ b/src/packet/packet_utils.h @@ -6,7 +6,7 @@ extern "C" #endif #include -#include "packet_priv.h" +#include "stellar/packet.h" /****************************************************************************** * metadata utils @@ -40,15 +40,40 @@ enum packet_action packet_get_action(const struct packet *pkt); void packet_set_origin_ctx(struct packet *pkt, void *ctx); const void *packet_get_origin_ctx(const struct packet *pkt); +/****************************************************************************** + * tuple uitls + ******************************************************************************/ + +// 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); + /****************************************************************************** * other uitls ******************************************************************************/ -int packet_is_fragment(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); + struct packet *packet_new(uint16_t pkt_len); struct packet *packet_dup(const struct packet *pkt); void packet_free(struct packet *pkt); +int packet_is_fragment(const struct packet *pkt); void layer_convert(const struct raw_layer *in, struct layer *out); #ifdef __cplusplus diff --git a/src/packet/test/gtest_packet.cpp b/src/packet/test/gtest_packet.cpp index 5f5da25..826b24f 100644 --- a/src/packet/test/gtest_packet.cpp +++ b/src/packet/test/gtest_packet.cpp @@ -1,7 +1,13 @@ #include #include -#include "packet_priv.h" +#include "tuple.h" +#include "packet_def.h" +#include "packet_ldbc.h" +#include "packet_parse.h" +#include "packet_build.h" +#include "packet_utils.h" +#include "packet_layer.h" /****************************************************************************** * [Protocols in frame: eth:ethertype:vlan:ethertype:vlan:ethertype:ip:ip:udp:data] @@ -2851,11 +2857,11 @@ TEST(PACKET, HASH_VALUE) // buffer: "2001:da8:200:900e:200:5efe:d24d:58a3 0 2600:140e:6::1702:1058 0" // buffer: "210.77.88.163 0 59.66.4.50 0" - EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_EXT_IP, PACKET_DIRECTION_OUTGOING)); - EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP, PACKET_DIRECTION_OUTGOING)); + EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING)); + EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_IP, PACKET_DIRECTION_OUTGOING)); - EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_OUTGOING)); - EXPECT_TRUE(packet_get_hash(&handler, LDBC_METHOD_HASH_INNERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_get_hash(&handler, LDBC_METHOD_HASH_INNERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING)); + EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_OUTGOING)); + EXPECT_TRUE(packet_ldbc_hash(&handler, LDBC_HASH_INNERMOST_INT_IP, PACKET_DIRECTION_INCOMING) == packet_ldbc_hash(&handler, LDBC_HASH_INNERMOST_EXT_IP, PACKET_DIRECTION_OUTGOING)); } #endif diff --git a/src/packet/test/gtest_packet_frag.cpp b/src/packet/test/gtest_packet_frag.cpp index 3b5be70..82ad3c1 100644 --- a/src/packet/test/gtest_packet_frag.cpp +++ b/src/packet/test/gtest_packet_frag.cpp @@ -1,7 +1,8 @@ #include -#include "packet_priv.h" +#include "packet_def.h" #include "packet_utils.h" +#include "packet_parse.h" /****************************************************************************** * [Protocols in frame: eth:ethertype:ip:data] diff --git a/src/packet/test/gtest_tunnel.cpp b/src/packet/test/gtest_tunnel.cpp index 77295a5..8cc6b37 100644 --- a/src/packet/test/gtest_tunnel.cpp +++ b/src/packet/test/gtest_tunnel.cpp @@ -1,13 +1,14 @@ #include -#include "stellar/layer.h" -#include "stellar/tunnel.h" -#include "packet_priv.h" -#include "ipv4_utils.h" -#include "ipv6_utils.h" #include "udp_utils.h" #include "gre_utils.h" +#include "ipv4_utils.h" +#include "ipv6_utils.h" #include "vxlan_utils.h" +#include "packet_def.h" +#include "packet_parse.h" +#include "stellar/layer.h" +#include "stellar/tunnel.h" /****************************************************************************** * [Protocols in frame: eth:ethertype:vlan:ethertype:vlan:ethertype:ip:ip:udp:data] diff --git a/src/packet_io/dumpfile_io.cpp b/src/packet_io/dumpfile_io.cpp index e203e57..d03f8ea 100644 --- a/src/packet_io/dumpfile_io.cpp +++ b/src/packet_io/dumpfile_io.cpp @@ -9,12 +9,19 @@ #include #include +#include "log.h" +#include "tuple.h" #include "macro.h" #include "dumpfile_io.h" -#include "packet_priv.h" +#include "packet_def.h" +#include "packet_ldbc.h" #include "packet_utils.h" +#include "packet_parse.h" #include "lock_free_queue.h" +#define PACKET_IO_LOG_STATE(format, ...) LOG_STATE("dumpfile io", format, ##__VA_ARGS__) +#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("dumpfile io", format, ##__VA_ARGS__) + #define MAX_PACKET_QUEUE_SIZE (4096 * 1000) struct dumpfile_io @@ -203,7 +210,7 @@ static void pcap_packet_handler(u_char *user, const struct pcap_pkthdr *h, const struct packet pkt; memset(&pkt, 0, sizeof(struct packet)); packet_parse(&pkt, pcap_pkt->data, pcap_pkt->len); - uint64_t hash = packet_get_hash(&pkt, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, PACKET_DIRECTION_OUTGOING); + uint64_t hash = packet_ldbc_hash(&pkt, LDBC_HASH_OUTERMOST_INT_EXT_IP, PACKET_DIRECTION_OUTGOING); // push packet to queue struct lock_free_queue *queue = handle->queue[hash % handle->nr_threads]; diff --git a/src/packet_io/marsio_io.cpp b/src/packet_io/marsio_io.cpp index 59a6664..7add76b 100644 --- a/src/packet_io/marsio_io.cpp +++ b/src/packet_io/marsio_io.cpp @@ -4,11 +4,14 @@ #include #include -#include "macro.h" +#include "log.h" #include "marsio.h" -#include "packet_priv.h" -#include "packet_utils.h" #include "marsio_io.h" +#include "packet_def.h" +#include "packet_utils.h" +#include "packet_parse.h" + +#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("marsio io", format, ##__VA_ARGS__) struct marsio_io { diff --git a/src/packet_io/packet_io.cpp b/src/packet_io/packet_io.cpp index 822c35d..fac2832 100644 --- a/src/packet_io/packet_io.cpp +++ b/src/packet_io/packet_io.cpp @@ -16,7 +16,6 @@ struct packet_io *packet_io_new(struct packet_io_options *opts) struct packet_io *packet_io = (struct packet_io *)calloc(1, sizeof(struct packet_io)); if (packet_io == NULL) { - PACKET_IO_LOG_ERROR("unable to alloc packet io"); return NULL; } diff --git a/src/packet_io/packet_io.h b/src/packet_io/packet_io.h index 26e695e..969fceb 100644 --- a/src/packet_io/packet_io.h +++ b/src/packet_io/packet_io.h @@ -5,13 +5,9 @@ extern "C" { #endif -#include "log.h" -#include "macro.h" -#include "packet_priv.h" +#include -#define PACKET_IO_LOG_STATE(format, ...) LOG_STATE("packet_io", format, ##__VA_ARGS__) -#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("packet_io", format, ##__VA_ARGS__) -#define PACKET_IO_LOG_DEBUG(format, ...) LOG_DEBUG("packet_io", format, ##__VA_ARGS__) +#include "macro.h" struct io_stat { diff --git a/src/session/session.cpp b/src/session/session.cpp index 1aace22..cb90fee 100644 --- a/src/session/session.cpp +++ b/src/session/session.cpp @@ -1,6 +1,6 @@ #include -#include "packet_priv.h" +#include "packet_def.h" #include "session_priv.h" #include "tcp_utils.h" #include "tcp_reassembly.h" diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index 8d7106e..1ccd9ec 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -6,6 +6,7 @@ #include "times.h" #include "tcp_utils.h" #include "udp_utils.h" +#include "packet_layer.h" #include "id_generator.h" #include "session_pool.h" #include "session_table.h" diff --git a/src/session/session_priv.h b/src/session/session_priv.h index c596b98..c53fbeb 100644 --- a/src/session/session_priv.h +++ b/src/session/session_priv.h @@ -6,11 +6,11 @@ extern "C" #endif #include "list.h" -#include "packet_priv.h" -#include "packet_utils.h" -#include "timeout.h" -#include "uthash.h" #include "tuple.h" +#include "uthash.h" +#include "timeout.h" +#include "packet_def.h" +#include "packet_utils.h" #include "stellar/session.h" #include "tcp_reassembly.h" #include "session_manager.h" diff --git a/src/session/test/gtest_case_tcp_fast_open.cpp b/src/session/test/gtest_case_tcp_fast_open.cpp index 0be44f8..5af9e20 100644 --- a/src/session/test/gtest_case_tcp_fast_open.cpp +++ b/src/session/test/gtest_case_tcp_fast_open.cpp @@ -1,6 +1,7 @@ #include #include "times.h" +#include "packet_parse.h" #include "session_priv.h" #include "session_manager.h" diff --git a/src/session/test/test_packets.h b/src/session/test/test_packets.h index e2f0225..12a62ed 100644 --- a/src/session/test/test_packets.h +++ b/src/session/test/test_packets.h @@ -5,6 +5,9 @@ extern "C" { #endif +#include "packet_parse.h" +#include "packet_layer.h" + /****************************************************************************** * test packet: HTTP www.example.com ******************************************************************************/ diff --git a/src/stellar/inject.cpp b/src/stellar/inject.cpp index 09fbc5e..1fa56e6 100644 --- a/src/stellar/inject.cpp +++ b/src/stellar/inject.cpp @@ -2,9 +2,9 @@ #include #include "times.h" -#include "packet_build.h" #include "packet_io.h" -#include "packet_priv.h" +#include "packet_def.h" +#include "packet_build.h" #include "session_priv.h" #include "stellar_priv.h" diff --git a/test/packet_parser/packet_parser.cpp b/test/packet_parser/packet_parser.cpp index b7d1550..52f2c02 100644 --- a/test/packet_parser/packet_parser.cpp +++ b/test/packet_parser/packet_parser.cpp @@ -1,7 +1,8 @@ #include #include -#include "ipv6_utils.h" -#include "packet_priv.h" +#include "packet_def.h" +#include "packet_layer.h" +#include "packet_parse.h" #include "eth_utils.h" #include "vlan_utils.h" #include "ipv4_utils.h"