diff --git a/common/include/tfe_proxy.h b/common/include/tfe_proxy.h index ea73d88..63b71c3 100644 --- a/common/include/tfe_proxy.h +++ b/common/include/tfe_proxy.h @@ -3,19 +3,16 @@ #include struct tfe_proxy; - -const char * tfe_proxy_default_conffile(); -const char * tfe_proxy_default_logger(); unsigned int tfe_proxy_get_work_thread_count(); struct event_base * tfe_proxy_get_work_thread_evbase(unsigned int thread_id); struct evdns_base* tfe_proxy_get_work_thread_dnsbase(unsigned int thread_id); struct event_base * tfe_proxy_get_gc_evbase(void); screen_stat_handle_t tfe_proxy_get_fs_handle(void); +void * tfe_proxy_get_error_logger(void); int tfe_proxy_ssl_add_trust_ca(const char* pem_file); int tfe_proxy_ssl_del_trust_ca(const char* pem_file); int tfe_proxy_ssl_add_crl(const char* pem_file); int tfe_proxy_ssl_del_crl(const char* pem_file); void tfe_proxy_ssl_reset_trust_ca(); - diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index c29950c..38ea2d5 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -495,6 +495,11 @@ screen_stat_handle_t tfe_proxy_get_fs_handle(void) return g_default_proxy->fs_handle; } +void * tfe_proxy_get_error_logger(void) +{ + return g_default_logger; +} + int tfe_proxy_ssl_add_trust_ca(const char* pem_file) { return ssl_manager_add_trust_ca(g_default_proxy->ssl_mgr_handler, pem_file); diff --git a/plugin/business/decrypt-mirroring/CMakeLists.txt b/plugin/business/decrypt-mirroring/CMakeLists.txt index 437813e..c954362 100644 --- a/plugin/business/decrypt-mirroring/CMakeLists.txt +++ b/plugin/business/decrypt-mirroring/CMakeLists.txt @@ -1,5 +1,4 @@ -add_library(decrypt-mirroring src/decrypt_mirror_plugin.cpp src/mirror_stream.cpp src/sendpkt.cpp) -target_include_directories(decrypt-mirroring PRIVATE include/internal) -target_include_directories(decrypt-mirroring PUBLIC include/external) -target_link_libraries(decrypt-mirroring common) +add_library(traffic-mirror src/entry.cpp src/ethdev.cpp src/rebuild.cpp) +target_include_directories(traffic-mirror PRIVATE include) +target_link_libraries(traffic-mirror common cjson) diff --git a/plugin/business/decrypt-mirroring/include/external/decrypt_mirror_plugin.h b/plugin/business/decrypt-mirroring/include/external/decrypt_mirror_plugin.h deleted file mode 100644 index 73d9e21..0000000 --- a/plugin/business/decrypt-mirroring/include/external/decrypt_mirror_plugin.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -int decrypt_mirror_init(void *proxy); - -enum tfe_stream_action decrypt_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme); - -enum tfe_stream_action decrypt_mirror_on_data_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme); - -void decrypt_mirror_on_close_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_stream_close_reason reason, void ** pme); -void decrypt_mirror_deinit(void); - diff --git a/plugin/business/decrypt-mirroring/include/internal/mirror_stream.h b/plugin/business/decrypt-mirroring/include/internal/mirror_stream.h deleted file mode 100644 index 7e36501..0000000 --- a/plugin/business/decrypt-mirroring/include/internal/mirror_stream.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef DELIVER_PROCESS_H -#define DELIVER_PROCESS_H - -#include -#include -#include - - - -struct origin_stream_addr -{ - struct sockaddr* client; - struct sockaddr* server; -}; - - - -/************************************************************************** -Description:deliver read config from filepath to init; -Paraments: - thread_num:[IN],total process data thread num - filepath:[IN], conf file path,read use MESA_prof_load; -Return: - 0:succes - <0:error -***************************************************************************/ -int mirror_stream_init(int thread_num, const char* filepath); - - - -/************************************************************************** -Description:call this function before send a new session data -Paraments: - thread_seq:[IN], thread seq - addr:[IN],addr of the session to be send - pme:[OUT],buffer alive in the session,deliver malloc and free *pme; -Return: - 0:succes - <0:error -***************************************************************************/ -int mirror_stream_open(int thread_id, const struct tfe_stream_addr* addr,void** pme); - - - -/************************************************************************** -Description:call this function when send session data -Paraments: - cur_dir:[IN], direction of current data,definition in DELIVER_DIR_*** - thread_seq:[IN],thread seq - buflen:[IN],buffer len,tcp payload len; - buf:[IN],data fo the session to be send,tcp payload - pme:[OUT] -Return: - 0:succes - <0:error -***************************************************************************/ -int mirror_stream_write(int cur_dir,const unsigned char * data, size_t len, void** pme,int thread_id); - - - -/************************************************************************** -Description:call this function after send all of session data -Paraments: - thread_seq:[IN], thread seq - pme:[OUT]; free *pme when deliver_end() -Return: - 0:succes - <0:error -***************************************************************************/ -void mirror_stream_close(void** pme, int thread_id); - - -#endif - diff --git a/plugin/business/decrypt-mirroring/include/internal/mirror_stream_inl.h b/plugin/business/decrypt-mirroring/include/internal/mirror_stream_inl.h deleted file mode 100644 index 3e39b92..0000000 --- a/plugin/business/decrypt-mirroring/include/internal/mirror_stream_inl.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef DELIVER_PRIVATE_H -#define DELIVER_PRIVATE_H - -#include -#include - -#ifndef MAX_THREAD_NUM -#define MAX_THREAD_NUM 128 -#endif - -#define DELIVER_DEFAULT_MTU 1500 -#define DELIVER_SENDPKT_BUFLEN 2048 - -//runtime log -#define DELIVER_MODULE_INIT "mirror_stream_init" -#define DELIVER_MODULE_SENDPKT "mirror_stream_sendpkt" -#define DELIVER_SENDPKT_START "sendpkt_start" -#define DELIVER_SENDPKT_DEBUG "sendpkt_debug" -#define DELIVER_RECVPKT_DEBUG "recvpkt_debug" -#define DELIVER_SENDPKT_END "sendpkt_end" - -#define DELIVER_FLAG_SENDPKT 0 -#define DELIVER_FLAG_RECVPKT 1 -#define DELIVER_FLAG_ENT 2 - -//init profile info -#define DELIVER_CARDNAME_LEN 128 -#define DELIVER_CONF_MAXLEN 1024 -#define DELIVER_CONF_MODE "DELIVER" -#define DELIVER_RCV_MAC "reveiver_mac" - -#define PROTO_TYPE_TCP 6 -#define PROTO_TYPE_UDP 17 - - -//lqueue info -#define DELIVER_THREAD_SAFE 1 -#define DELIVER_USLEEP_TIME 10 -#define DELIVER_LQUEUE_MAXNUM 100000 - - -//send pkt -#define DELIVER_MACADDR_LEN 6 -#define DELIVER_MACADDR_STR_LEN 18 -#define DELIVER_ETHER_LEN 14 -#define TCPHDR_DEFAULT_LEN 20 - -//fs2 info -#define FS2_COLUMN_NUM 5 -#define FS2_APPNAME "DELIVER" - - -enum deliver_fs_colume -{ - FS2_COLUME_RECVPKT=0, - FS2_COLUME_RECVBYTE, - FS2_COLUME_SENDPKT, - FS2_COLUME_SENDBYTE, - FS2_COLUME_ERROR, -}; - - -struct deliver_fs2_info -{ - screen_stat_handle_t handler; - int column_id[FS2_COLUMN_NUM]; - unsigned long long column_value[MAX_THREAD_NUM][FS2_COLUMN_NUM]; -}; - -struct deliver_comm_info -{ - int threadnum; - void* logger; -}; - - -struct deliver_pkt_info -{ - int dir; - unsigned int seq; //host order - unsigned int ack; //host order - unsigned int len; //host order,tcp payload len - unsigned short ipid; //host order - unsigned short win; //host order - unsigned char flag; - unsigned char ttl; - -}; - -struct deliver_session_info -{ - int recv_pkt; - int send_pkt; - long long recv_byte; - long long send_byte; -}; - - -struct deliver_pme_info -{ - unsigned char dst_macaddr[DELIVER_MACADDR_LEN]; - const struct tfe_stream_addr* addr_info; - struct deliver_pkt_info pkt_info; - struct deliver_session_info session_info; -}; - -struct deliver_recver_info -{ - unsigned char dst_macaddr[DELIVER_MACADDR_LEN]; -}; - -struct deliver_sendpkt_info -{ - int mtu; - int thread_num; - int receiver_num; - struct ifreq ifr; - int* send_socket; - char senddevice[DELIVER_CARDNAME_LEN]; - unsigned char src_macaddr[DELIVER_MACADDR_LEN]; - struct deliver_recver_info* receiver_info; -}; - -struct deliver_globle_info -{ - int deliver_switch; - char *fs2_name[FS2_COLUMN_NUM]; - unsigned char* sendbuf[MAX_THREAD_NUM]; - struct deliver_comm_info comminfo; - struct deliver_sendpkt_info sendinfo; - struct deliver_fs2_info fs2info; - - -}; -#endif - diff --git a/plugin/business/decrypt-mirroring/include/internal/sendpkt-inl.h b/plugin/business/decrypt-mirroring/include/internal/sendpkt-inl.h deleted file mode 100644 index cc9c57a..0000000 --- a/plugin/business/decrypt-mirroring/include/internal/sendpkt-inl.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef DELIVER_SENDPKT_H -#define DELIVER_SENDPKT_H - -#include -#include - - - -#ifndef ETHER_ADDR_LEN -#define ETHER_ADDR_LEN 6 -#endif - -#define ARPHRD_ETHER 1 /* ethernet hardware format */ - -#define SENDPACKET_ETH_H 0xe /* Etherner header: 14 bytes */ -#define SENDPACKET_IP_H 0x14 /* IP header: 20 bytes */ -#define SENDPACKET_TCP_H 0x14 /* TCP header: 20 bytes */ - - -struct mesa_ethernet_hdr -{ - unsigned char ether_dhost[ETHER_ADDR_LEN]; /* destination ethernet address */ - unsigned char ether_shost[ETHER_ADDR_LEN]; /* source ethernet address */ - unsigned short ether_type; /* packet type ID */ -}; - - - -struct mesa_ip4_hdr -{ -#if __BYTE_ORDER == __LITTLE_ENDIAN - u_int8_t ip_hl:4, /* header length */ - ip_v:4; /* version */ -#elif __BYTE_ORDER == __BIG_ENDIAN - u_int8_t ip_v:4, /* version */ - ip_hl:4; /* header length */ -#else -#error "Please check " -#endif - u_int8_t ip_tos; /* type of service */ - u_int16_t ip_len; /* total length */ - u_int16_t ip_id; /* identification */ - u_int16_t ip_off; - u_int8_t ip_ttl; /* time to live */ - u_int8_t ip_p; /* protocol */ - u_int16_t ip_sum; /* checksum */ - struct in_addr ip_src, ip_dst; /* source and dest address */ -}; - - - - -/* - * IPv6 packet header prototype, add by LiJia 2012-03-19. - */ -struct mesa_ip6_hdr -{ - u_int8_t ip6_flags[4]; /* version, traffic-class, flow-label */ - u_int16_t ip6_payload_len; /* payload length, not contain header */ - u_int8_t ip6_nxt_hdr; /* next header, same as protocol in IPv4 */ - u_int8_t ip6_hop; /* hop limit, same as TTL in IPv4 */ - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* dest address */ -}; - - -#ifndef TH_FIN -#define TH_FIN 0x01 -#endif -#ifndef TH_SYN -#define TH_SYN 0x02 -#endif -#ifndef TH_RST -#define TH_RST 0x04 -#endif -#ifndef TH_PUSH -#define TH_PUSH 0x08 -#endif -#ifndef TH_ACK -#define TH_ACK 0x10 -#endif -#ifndef TH_URG -#define TH_URG 0x20 -#endif - - -struct mesa_tcp_hdr -{ - u_int16_t th_sport; /* source port */ - u_int16_t th_dport; /* destination port */ - u_int32_t th_seq; /* sequence number */ - u_int32_t th_ack; /* acknowledgement number */ -#if __BYTE_ORDER == __LITTLE_ENDIAN - u_int8_t th_x2:4, /* (unused) */ - th_off:4; /* data offset */ -#elif __BYTE_ORDER == __BIG_ENDIAN - u_int8_t th_off:4, /* data offset */ - th_x2:4; /* (unused) */ -#else -#error "Please check " -#endif - u_int8_t th_flags; /* control flags */ - u_int16_t th_win; /* window */ - u_int16_t th_sum; /* checksum */ - u_int16_t th_urp; /* urgent pointer */ -}; - - -/* - * UDP packet header prototype. - */ -struct mesa_udp_hdr -{ - u_int16_t uh_sport; /* soure port */ - u_int16_t uh_dport; /* destination port */ - u_int16_t uh_ulen; /* length */ - u_int16_t uh_sum; /* checksum */ -}; - -unsigned int deliver_rand(void); -unsigned int deliver_rand_range(unsigned int start, unsigned int end); -int deliver_get_dev_mac(const char *device, unsigned char mac[6]); -int deliver_mac_pton(const char *str, int delim, char *mac); -int deliver_do_checksum(unsigned char *buf, int protocol, int len); -int deliver_build_ethernet(unsigned char *dst, unsigned char *src, unsigned short type, - const unsigned char *payload, int payload_s, unsigned char *buf); -int deliver_build_ethhdr(unsigned char *dst, unsigned char *src, unsigned short type,unsigned char *buf); -int deliver_build_ipv6(unsigned char traffic_class, unsigned int flow_lable, - unsigned short len, unsigned char next_header, unsigned char hop, - const struct in6_addr *src, const struct in6_addr *dst, - const unsigned char *payload, int payload_s, unsigned char *buf); -int deliver_build_ipv4(unsigned short carry_layer_len, unsigned char tos, unsigned short id, - unsigned short frag, unsigned char ttl, unsigned char prot, unsigned int src, unsigned int dst, - const unsigned char *payload,int payload_s, unsigned char *buf); -int deliver_build_tcp(unsigned short sp, unsigned short dp, unsigned int seq, unsigned int ack, - unsigned char th_flags, unsigned short win, unsigned short urg, - const unsigned char *payload, int payload_s, unsigned char *buf); - -#endif - diff --git a/plugin/business/decrypt-mirroring/include/traffic_mirror.h b/plugin/business/decrypt-mirroring/include/traffic_mirror.h new file mode 100644 index 0000000..2925c09 --- /dev/null +++ b/plugin/business/decrypt-mirroring/include/traffic_mirror.h @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include + +enum traffic_mirror_ethdev_type +{ + TRAFFIC_MIRROR_ETHDEV_AF_PACKET, + TRAFFIC_MIRROR_ETHDEV_MARSIO +}; + +enum traffic_mirror_target_addr_type +{ + TRAFFIC_MIRROR_TARGET_BY_VLAN_ID, + TRAFFIC_MIRROR_TARGET_BY_ETHER_ADDR, +}; + +struct traffic_mirror_instance +{ + void * logger; + unsigned int nr_threads; + + Maat_feather_t maat_feather; + int policy_table_id; + int profile_table_id; + + /* DEFAULT MAC ADDRESS, IN VLAN MODE */ + char default_ether_addr_src; + char default_ether_addr_dst; +}; + +struct policy_table_ex_data +{ + unsigned int atomic_refcnt; + unsigned int enable; + unsigned int profile_id; +}; + +struct profile_table_ex_data +{ + unsigned int atomic_refcnt; + + enum traffic_mirror_target_addr_type target_addr_type; + unsigned int nr_targets; + + /* Target VLANS */ + unsigned int * vlans; + struct ether_addr * ether_addrs; +}; + +struct traffic_mirror_ethdev +{ + /* PUBLIC */ + char str_device[TFE_SYMBOL_MAX]; + enum traffic_mirror_ethdev_type type; + + unsigned int mtu; + unsigned int en_offload_vlan; + unsigned int en_offload_ip_cksum; + unsigned int en_offload_tcp_cksum; + + /* PRIVATE, FOR PCAP */ + pcap_t * pcap_device_handle; + char local_ether_addr[6]; + + /* FUNCTIONS */ + int (*fn_inject)(struct traffic_mirror_ethdev *, const char * pkt, unsigned int pktlen); + void (*fn_destroy)(struct traffic_mirror_ethdev * ethdev); +}; + +struct traffic_mirror_ethdev * traffic_mirror_ethdev_pcap_create(const char * str_ethdev, void * logger); +void traffic_mirror_ethdev_destroy(struct traffic_mirror_ethdev * ethdev); +int traffic_mirror_ethdev_inject(struct traffic_mirror_ethdev * ethdev, const char * pkt, unsigned int pktlen); + + +struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr, + struct profile_table_ex_data * target, struct traffic_mirror_ethdev * ethdev); +void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance); +void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance); +void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance, + const char * data, unsigned int datalen, enum tfe_conn_dir dir); +void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance); + diff --git a/plugin/business/decrypt-mirroring/src/decrypt_mirror_plugin.cpp b/plugin/business/decrypt-mirroring/src/decrypt_mirror_plugin.cpp deleted file mode 100644 index 8eb3e35..0000000 --- a/plugin/business/decrypt-mirroring/src/decrypt_mirror_plugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "mirror_stream.h" -#include -#include -#include - - -extern unsigned int tfe_proxy_get_work_thread_count(void); - -int decrypt_mirror_init(struct tfe_proxy * proxy) -{ - const char* filepath="./conf/tfe/decrypt_mirror.conf"; - int ret=0; - int thread_num = tfe_proxy_get_work_thread_count(); - ret=mirror_stream_init(thread_num, filepath); - return ret; -} - -int decrypt_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_conn_dir dir, void ** pme) -{ - int ret=0; - ret=mirror_stream_open(thread_id, stream->addr, pme); - return ret; -} - -enum tfe_stream_action decrypt_mirror_on_data_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme) -{ - mirror_stream_write(dir, data,len, pme, thread_id); - return ACTION_FORWARD_DATA; -} - -void decrypt_mirror_on_close_cb(const struct tfe_stream * stream, unsigned int thread_id, - enum tfe_stream_close_reason reason, void ** pme) -{ - mirror_stream_close(pme, thread_id); - return; -} - -void decrypt_mirror_deinit(struct tfe_proxy * proxy) -{ - return; -} - -struct tfe_plugin decrypt_mirror_spec={ - .symbol=NULL, - .type = TFE_PLUGIN_TYPE_BUSINESS, - .on_init = decrypt_mirror_init, - .on_deinit = decrypt_mirror_deinit, - .on_open = decrypt_mirror_on_open_cb, - .on_data = decrypt_mirror_on_data_cb, - .on_close = decrypt_mirror_on_close_cb}; -TFE_PLUGIN_REGISTER(decrypt_mirror,decrypt_mirror_spec) - - diff --git a/plugin/business/decrypt-mirroring/src/entry.cpp b/plugin/business/decrypt-mirroring/src/entry.cpp new file mode 100644 index 0000000..4d351e5 --- /dev/null +++ b/plugin/business/decrypt-mirroring/src/entry.cpp @@ -0,0 +1,436 @@ +#include +#include +#include +#include +#include +#include "../include/traffic_mirror.h" + +extern Maat_feather_t g_business_maat; + +struct traffic_mirror_me +{ + struct profile_table_ex_data * profile_ex_data; + struct traffic_mirror_rebuild * rebuild_ctx; +}; + +struct traffic_mirror_instance __g_traffic_mirror_instance; +struct traffic_mirror_instance * g_traffic_mirror_instance = &__g_traffic_mirror_instance; + +void policy_table_ex_data_free(struct policy_table_ex_data * object) +{ + if ((__sync_sub_and_fetch(&object->atomic_refcnt, 1) == 0)) free(object); +} + +void policy_table_ex_data_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA * to, + MAAT_PLUGIN_EX_DATA * from, long argl, void * argp) +{ + struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)from; + __sync_add_and_fetch(&ex_data->atomic_refcnt, 1); + *to = (void *)ex_data; +} + +void policy_table_ex_data_free_cb(int table_id, MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) +{ + struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)argp; + policy_table_ex_data_free(ex_data); +} + +void policy_table_ex_data_new_cb(int table_id, const char * key, const char * table_line, + MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) +{ + struct traffic_mirror_instance * instance = (struct traffic_mirror_instance *) argp; + assert(instance != nullptr && instance->logger != nullptr); + + char * str_json = NULL; + cJSON * json_root = NULL; + cJSON * json_subroot = NULL; + cJSON * json_item = NULL; + + struct policy_table_ex_data * ex_data = NULL; + + unsigned int user_region_offset; + unsigned int user_region_len; + unsigned int policy_enable; + unsigned int policy_profile_id; + + int result = Maat_helper_read_column(table_line, 7, &user_region_offset, &user_region_len); + if (unlikely(result < 0)) + { + TFE_LOG_ERROR(instance->logger, "Failed at get policy table's user region."); + goto ignore; + } + + str_json = ALLOC(char, user_region_len + 1); + memcpy(str_json, table_line + user_region_offset, user_region_len); + + json_root = cJSON_Parse(str_json); + if (unlikely(!json_root)) + { + TFE_LOG_ERROR(instance->logger, "failed at parsing user region as JSON format."); + goto ignore; + } + + json_subroot = cJSON_GetObjectItem(json_root, "decrypt_mirror"); + if (unlikely(!json_subroot)) + { + TFE_LOG_ERROR(instance->logger, "invalid format, decrypt_mirror is not defined."); + goto ignore; + } + + ex_data = ALLOC(struct policy_table_ex_data, 1); + ex_data->atomic_refcnt = 1; + ex_data->enable = 0; + ex_data->profile_id = 0; + + json_item = cJSON_GetObjectItem(json_subroot, "enable"); + if (unlikely(!json_item || cJSON_IsNumber(json_item))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, decrypt_mirror->enable not existed or invalid type."); + goto ignore; + } + + ex_data->enable = json_item->valueint; + if (!ex_data->enable) + { + goto success; + } + + json_item = cJSON_GetObjectItem(json_subroot, "mirror_profile"); + if (unlikely(!json_item || cJSON_IsNumber(json_item))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, decrypt_mirror->mirror_profile not existed or invalid type."); + goto ignore; + } + +success: + TFE_LOG_DEBUG(instance->logger, "table line in PXY_INTERCEPT_COMPILE added: %s", table_line); + *ad = ex_data; + ex_data = nullptr; + goto out; + +ignore: + TFE_LOG_ERROR(instance->logger, "table line in PXY_INTERCEPT_COMPILE ignored: %s", table_line); + goto out; + +out: + if (ex_data) policy_table_ex_data_free(ex_data); + if (json_root) cJSON_Delete(json_root); + if (str_json) free(str_json); +} + +void profile_table_ex_data_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA * to, + MAAT_PLUGIN_EX_DATA * from, long argl, void * argp) +{ + struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)from; + __sync_add_and_fetch(&ex_data->atomic_refcnt, 1); + *to = (void *)ex_data; +} + +void profile_table_ex_data_free(struct profile_table_ex_data * object) +{ + if ((__sync_sub_and_fetch(&object->atomic_refcnt, 1) == 0)) free(object); +} + +void profile_table_ex_data_free_cb(int table_id, MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) +{ + struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)ad; + profile_table_ex_data_free(ex_data); +} + +void profile_table_ex_data_new_cb(int table_id, const char * key, const char * table_line, + MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) +{ + struct traffic_mirror_instance * instance = (struct traffic_mirror_instance *) argp; + assert(instance != nullptr && instance->logger != nullptr); + + char * str_json = NULL; + cJSON * json_root = NULL; + cJSON * json_item = NULL; + + struct profile_table_ex_data * ex_data = NULL; + + unsigned int addr_list_offset; + unsigned int addr_list_len; + + int result = Maat_helper_read_column(table_line, 3, &addr_list_offset, &addr_list_len); + if (unlikely(result < 0)) + { + TFE_LOG_ERROR(instance->logger, "Failed at get profile table's addrlist."); + goto ignore; + } + + str_json = ALLOC(char, addr_list_len + 1); + memcpy(str_json, table_line + addr_list_offset, addr_list_len); + + json_root = cJSON_Parse(str_json); + if (unlikely(!json_root)) + { + TFE_LOG_ERROR(instance->logger, "failed at parsing addrlist as JSON format."); + goto ignore; + } + + ex_data = ALLOC(struct profile_table_ex_data, 1); + ex_data->atomic_refcnt = 1; + + json_item = cJSON_GetObjectItem(json_root, "vlan"); + if (json_item) + { + if (unlikely(!cJSON_IsArray(json_item))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, mirror_profile->vlan is not a array."); + goto ignore; + } + + ex_data->target_addr_type = TRAFFIC_MIRROR_TARGET_BY_VLAN_ID; + ex_data->nr_targets = cJSON_GetArraySize(json_item); + ex_data->vlans = (unsigned int *)calloc(ex_data->nr_targets, sizeof(ex_data->vlans[0])); + + cJSON * element; + unsigned int iter = 0; + cJSON_ArrayForEach(element, json_item) + { + if (unlikely(!cJSON_IsNumber(element))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, " + "elements in mirror_profile->vlan is not a number"); + goto ignore; + } + + ex_data->vlans[iter++] = element->valueint; + } + + assert(iter + 1 == ex_data->nr_vlans); + goto success; + } + + json_item = cJSON_GetObjectItem(json_item, "mac"); + if (json_item) + { + if (unlikely(!cJSON_IsArray(json_item))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, mirror_profile->mac is not a array."); + goto ignore; + } + + ex_data->target_addr_type = TRAFFIC_MIRROR_TARGET_BY_ETHER_ADDR; + ex_data->nr_ether_addrs = cJSON_GetArraySize(json_item); + ex_data->ether_addrs = (struct ether_addr *)calloc(ex_data->nr_ether_addrs, sizeof(ex_data->ether_addrs[0])); + + cJSON * element; + unsigned int iter; + + cJSON_ArrayForEach(element, json_item) + { + if (unlikely(!cJSON_IsString(element))) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, " + "elements in mirror_profile->mac is not a string"); + goto ignore; + } + + struct ether_addr * result = ether_aton_r(element->valuestring, &ex_data->ether_addrs[iter++]); + if (unlikely(!result)) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, " + "elements in mirror_profile->mac is not a valid ether address"); + goto ignore; + } + } + } + +success: + *ad = (void *)ex_data; + ex_data = nullptr; + + TFE_LOG_DEBUG(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR added: %s", table_line); + goto out; + +ignore: + TFE_LOG_ERROR(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR ignored: %s", table_line); + goto out; + +out: + if (ex_data) + { + profile_table_ex_data_free(ex_data); + } + + if (str_json) + { + free(str_json); + } + + if (json_root) + { + cJSON_Delete(json_root); + } +} + +int traffic_mirror_init(struct tfe_proxy * proxy) +{ + int result = 0; + struct traffic_mirror_instance * instance = g_traffic_mirror_instance; + + /* INIT DECRYPT MIRROR INSTANCE */ + instance->maat_feather = g_business_maat; + instance->logger = tfe_proxy_get_error_logger(); + instance->nr_threads = tfe_proxy_get_work_thread_count(); + + /* REGISTER MAAT FEATHER */ + instance->policy_table_id = Maat_table_register(instance->maat_feather, "PXY_INTERCEPT_COMPILE"); + if (unlikely(instance->policy_table_id < 0)) + { + TFE_LOG_ERROR(instance->logger, "failed at register table PXY_INTERCEPT_COMPILE, ret = %d", + instance->policy_table_id); goto errout; + } + + instance->profile_table_id = Maat_table_register(instance->maat_feather, "PXY_PROFILE_TRAFFIC_MIRROR"); + if (unlikely(instance->profile_table_id < 0)) + { + TFE_LOG_ERROR(instance->logger, "failed at register table PXY_PROFILE_TRAFFIC_MIRROR, ret = %d", + instance->profile_table_id); goto errout; + } + + result = Maat_plugin_EX_register(instance->maat_feather, instance->policy_table_id, + policy_table_ex_data_new_cb, policy_table_ex_data_free_cb, policy_table_ex_data_dup_cb, + nullptr, 0, instance); + + if(unlikely(result < 0)) + { + TFE_LOG_ERROR(instance->logger, "failed at Maat_plugin_EX_register(PXY_INTERCEPT_COMPILE), " + "table_id = %d, ret = %d", instance->policy_table_id, result); + goto errout; + } + + result = Maat_plugin_EX_register(instance->maat_feather, instance->policy_table_id, + profile_table_ex_data_new_cb, profile_table_ex_data_free_cb, policy_table_ex_data_dup_cb, + nullptr, 0, instance); + + if (unlikely(result < 0)) + { + TFE_LOG_ERROR(instance->logger, "failed at Maat_plugin_EX_register(PXY_PROFILE_TRAFFIC_MIRROR), " + "table_id = %d, ret = %d", instance->policy_table_id, result); + } + +errout: + return 0; +} + +int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thread_id, + enum tfe_conn_dir dir, void ** pme) +{ + /* Firstly, fetch destination address of traffic mirror */ + struct traffic_mirror_me * me = NULL; + struct traffic_mirror_instance * instance = g_traffic_mirror_instance; + struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg(stream); + + assert(instance != NULL); + assert(cmsg != NULL); + + char str_policy_id[TFE_SYMBOL_MAX]; + char str_profile_id[TFE_SYMBOL_MAX]; + + unsigned int opt_val; + uint16_t opt_out_size; + + struct policy_table_ex_data * policy_ex_data = NULL; + struct profile_table_ex_data * profile_ex_data = NULL; + + int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char*)&opt_val, sizeof(opt_val), &opt_out_size); + if (ret < 0) + { + TFE_LOG_ERROR(instance->logger, "failed at getting policy id from cmsg, detach the stream."); + goto detach; + } + + snprintf(str_policy_id, sizeof(str_policy_id), "%u", opt_val); + policy_ex_data = (struct policy_table_ex_data *)Maat_plugin_get_EX_data(instance->maat_feather, + instance->policy_table_id, str_policy_id); + + if (!policy_ex_data) + { + TFE_LOG_ERROR(instance->logger, "failed at getting policy %s's EXDATA, detach the stream", str_policy_id); + goto detach; + } + + if (!policy_ex_data->enable) + { + goto detach; + } + + snprintf(str_profile_id, sizeof(str_policy_id), "%u", policy_ex_data->profile_id); + profile_ex_data = (struct profile_table_ex_data *)Maat_plugin_get_EX_data(instance->maat_feather, + instance->profile_table_id, str_profile_id); + + if (!profile_ex_data) + { + TFE_LOG_ERROR(instance->logger, "failed at getting policy %s's profile, profile id = %s, " + "detach the stream", str_policy_id, str_profile_id); + goto detach; + } + + + me = ALLOC(struct traffic_mirror_me, 1); + me->rebuild_ctx = traffic_mirror_rebuild_create(stream->addr, profile_ex_data, NULL); + me->profile_ex_data = profile_ex_data; + + /* profile_ex_data's ownership is transfer to me */ + profile_ex_data = NULL; + traffic_mirror_rebuild_handshake(me->rebuild_ctx); + + *pme = (void *)me; + return ACTION_FORWARD_DATA; + +detach: + if (me) + { + free(me); + } + + if (policy_ex_data) + { + policy_table_ex_data_free(policy_ex_data); + } + + if (profile_ex_data) + { + profile_table_ex_data_free(profile_ex_data); + } + + tfe_stream_detach(stream); + return ACTION_FORWARD_DATA; +} + +enum tfe_stream_action traffic_mirror_on_data_cb(const struct tfe_stream * stream, unsigned int thread_id, + enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme) +{ + struct traffic_mirror_me * me = (struct traffic_mirror_me *)(*pme); + traffic_mirror_rebuild_data(me->rebuild_ctx, (const char *)data, (size_t)len, dir); +} + +void traffic_mirror_on_close_cb(const struct tfe_stream * stream, unsigned int thread_id, + enum tfe_stream_close_reason reason, void ** pme) +{ + struct traffic_mirror_me * me = (struct traffic_mirror_me *)(*pme); + traffic_mirror_rebuild_farewell(me->rebuild_ctx); + traffic_mirror_rebuild_destroy(me->rebuild_ctx); + profile_table_ex_data_free(me->profile_ex_data); + + free(me); + *pme = NULL; +} + +void traffic_mirror_deinit(struct tfe_proxy * proxy){} + +struct tfe_plugin traffic_mirror_plugin_desc = +{ + .symbol= "traffic_mirror", + .type = TFE_PLUGIN_TYPE_BUSINESS, + .on_init = traffic_mirror_init, + .on_deinit = traffic_mirror_deinit, + .on_open = traffic_mirror_on_open_cb, + .on_data = traffic_mirror_on_data_cb, + .on_close = traffic_mirror_on_close_cb +}; + +TFE_PLUGIN_REGISTER(traffic_mirror, traffic_mirror_plugin_desc) diff --git a/plugin/business/decrypt-mirroring/src/ethdev.cpp b/plugin/business/decrypt-mirroring/src/ethdev.cpp new file mode 100644 index 0000000..93e57f2 --- /dev/null +++ b/plugin/business/decrypt-mirroring/src/ethdev.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include + +#include +#include + +struct traffic_mirror_ethdev_pkt_desc{}; +struct traffic_mirror_ethdev_pkt_desc_pcap +{ + unsigned int pktlen; + char * pkt; +}; + +static int pcap_ethdev_inject(struct traffic_mirror_ethdev * ethdev, const char * pkt, unsigned int pktlen) +{ + return pcap_sendpacket(ethdev->pcap_device_handle, (const u_char *)pkt, pktlen); +} + +static void pcap_ethdev_destroy(struct traffic_mirror_ethdev * ethdev) +{ + pcap_close(ethdev->pcap_device_handle); + return free(ethdev); +} + +void traffic_mirror_ethdev_destroy(struct traffic_mirror_ethdev * ethdev) +{ + ethdev->fn_destroy(ethdev); +} + +int traffic_mirror_ethdev_inject(struct traffic_mirror_ethdev * ethdev, const char * pkt, unsigned int pktlen) +{ + return ethdev->fn_inject(ethdev, pkt, pktlen); +} + +struct traffic_mirror_ethdev * traffic_mirror_ethdev_pcap_create(const char * str_ethdev, void * logger) +{ + struct traffic_mirror_ethdev * ethdev = ALLOC(struct traffic_mirror_ethdev, 1); + char pcap_errbuf[PCAP_ERRBUF_SIZE] = {}; + + int fd = 0; + struct ifreq if_req{}; + + ethdev->en_offload_ip_cksum = 0; + ethdev->en_offload_tcp_cksum = 0; + ethdev->en_offload_vlan = 0; + + /* open the device by pcap */ + ethdev->pcap_device_handle = pcap_open_live(str_ethdev, 0, 0, 0, pcap_errbuf); + if (!ethdev->pcap_device_handle) + { + TFE_LOG_ERROR(logger, "failed at pcap_open_live(), device = %s: %s", str_ethdev, pcap_errbuf); + goto errout; + } + + /* local ether address */ + fd = socket(AF_INET, SOCK_DGRAM, 0); + if(fd < 0) + { + TFE_LOG_ERROR(logger, "failed at create socket: %s", strerror(errno)); + goto errout; + } + + memset(&if_req, 0, sizeof(if_req)); + strncpy(if_req.ifr_ifrn.ifrn_name, str_ethdev, IFNAMSIZ - 1); + + if(ioctl(fd, SIOCGIFHWADDR, &if_req) < 0) + { + TFE_LOG_ERROR(logger, "failed at read hwaddr of device %s: %s", str_ethdev, strerror(errno)); + goto errout; + } + + for(int i = 0; i < 6; i++) + { + ethdev->local_ether_addr[i] = if_req.ifr_ifru.ifru_hwaddr.sa_data[i]; + } + + /* MTU */ + memset(&if_req, 0, sizeof(if_req)); + strncpy(if_req.ifr_ifrn.ifrn_name, str_ethdev, IFNAMSIZ - 1); + + if (ioctl(fd, SIOCGIFMTU, &if_req) < 0) + { + TFE_LOG_ERROR(logger, "failed at read mtu of device %s: %s", str_ethdev, strerror(errno)); + goto errout; + } + + ethdev->mtu = if_req.ifr_ifru.ifru_mtu; + strncpy(ethdev->str_device, str_ethdev, sizeof(ethdev->str_device) - 1); + + TFE_LOG_INFO(logger, "traffic mirror device %s (pcap mode): %02X:%02X:%02X:%02X:%02X:%02X, mtu=%u", + ethdev->str_device, ethdev->local_ether_addr[0], ethdev->local_ether_addr[1], + ethdev->local_ether_addr[2], ethdev->local_ether_addr[3], + ethdev->local_ether_addr[4], ethdev->local_ether_addr[5], ethdev->mtu); + + ethdev->fn_inject = pcap_ethdev_inject; + ethdev->fn_destroy = pcap_ethdev_destroy; + + close(fd); + return ethdev; + +errout: + if (fd > 0) close(fd); + if (ethdev->pcap_device_handle) pcap_close(ethdev->pcap_device_handle); + if (ethdev) FREE(ðdev); + return nullptr; +} diff --git a/plugin/business/decrypt-mirroring/src/mirror_stream.cpp b/plugin/business/decrypt-mirroring/src/mirror_stream.cpp deleted file mode 100644 index 2d1dcea..0000000 --- a/plugin/business/decrypt-mirroring/src/mirror_stream.cpp +++ /dev/null @@ -1,808 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -int g_deliver_version_VERSION_20180718; - -struct deliver_globle_info g_deliver_globle_info; - - - - -int deliver_set_filestate2(int thread_seq,int colum_index,int value) -{ - if(thread_seq>=g_deliver_globle_info.comminfo.threadnum) - { - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,RLOG_LV_FATAL,"deliver_set_filestate2","thread_seq:%d,thread_num:%d",thread_seq,g_deliver_globle_info.comminfo.threadnum); - } - - g_deliver_globle_info.fs2info.column_value[thread_seq][colum_index]+=value; - - return 0; - -} - - -int deliver_filestate2_init(char* filepath) -{ - int i=0; - int trans_switch=0; - int value=1; - unsigned int fs2_sport; - char fs2_filename[DELIVER_CONF_MAXLEN]={0}; - char fs2_sip[DELIVER_CONF_MAXLEN]={0}; - - MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_filename",fs2_filename,DELIVER_CONF_MAXLEN,(char*)"./log/deliver_fs2.log"); - MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sip",fs2_sip,DELIVER_CONF_MAXLEN,(char*)"192.168.11.241"); - MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,8125); - MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_trans_switch",(unsigned int*)&trans_switch,0); - - g_deliver_globle_info.fs2info.handler=FS_create_handle(); - - FS_set_para(g_deliver_globle_info.fs2info.handler, OUTPUT_DEVICE,fs2_filename, strlen(fs2_filename)+1); - FS_set_para(g_deliver_globle_info.fs2info.handler, PRINT_MODE, &value, sizeof(value)); - FS_set_para(g_deliver_globle_info.fs2info.handler, STAT_CYCLE, &value, sizeof(value)); - FS_set_para(g_deliver_globle_info.fs2info.handler, CREATE_THREAD, &value, sizeof(value)); - FS_set_para(g_deliver_globle_info.fs2info.handler, APP_NAME, FS2_APPNAME, strlen(FS2_APPNAME)+1); - - if(trans_switch==1) - { - FS_set_para(g_deliver_globle_info.fs2info.handler, STATS_SERVER_IP, fs2_sip, strlen(fs2_sip)+1); - FS_set_para(g_deliver_globle_info.fs2info.handler, STATS_SERVER_PORT,&fs2_sport,sizeof(int)); - } - - for(i=0;isession_info); - struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info); - - const struct tfe_stream_addr_tuple4_v6* tuple4_v6 = pmeinfo->addr_info->tuple4_v6; - - char saddr_v6[INET6_ADDRSTRLEN ]={0}; - char daddr_v6[INET6_ADDRSTRLEN ]={0}; - unsigned short sport=ntohs(tuple4_v6->source); - unsigned short dport=ntohs(tuple4_v6->dest); - - inet_ntop(AF_INET6, (void *)&(tuple4_v6->saddr), saddr_v6, INET6_ADDRSTRLEN); - inet_ntop(AF_INET6, (void *)&(tuple4_v6->daddr), daddr_v6, INET6_ADDRSTRLEN); - - switch(flag) - { - case DELIVER_FLAG_SENDPKT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d", - saddr_v6,sport,daddr_v6,dport,pkt_info->len,pkt_info->dir, - pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag); - break; - case DELIVER_FLAG_RECVPKT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d", - saddr_v6,sport,daddr_v6,dport,pkt_info->dir,recv_len); - break; - case DELIVER_FLAG_ENT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld", - saddr_v6,sport,daddr_v6,dport,session_info->recv_pkt,session_info->recv_byte, - session_info->send_pkt,session_info->recv_byte); - break; - } - - - return 0; - -} - - - -int deliver_debug_log_v4(int level,char* module,struct deliver_pme_info* pmeinfo,int flag,int recv_len) -{ - struct deliver_session_info* session_info=&(pmeinfo->session_info); - struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info); - - - const struct tfe_stream_addr_tuple4_v4* tuple4_v4 = pmeinfo->addr_info->tuple4_v4; - - char saddr_v4[INET_ADDRSTRLEN]={0}; - char daddr_v4[INET_ADDRSTRLEN]={0}; - unsigned short sport=ntohs(tuple4_v4->source); - unsigned short dport=ntohs(tuple4_v4->dest); - - inet_ntop(AF_INET, (void *)&(tuple4_v4->saddr), saddr_v4, INET_ADDRSTRLEN); - inet_ntop(AF_INET, (void *)&(tuple4_v4->daddr), daddr_v4, INET_ADDRSTRLEN); - - switch(flag) - { - case DELIVER_FLAG_SENDPKT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d", - saddr_v4,sport,daddr_v4,dport,pkt_info->len,pkt_info->dir, - pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag); - break; - case DELIVER_FLAG_RECVPKT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d", - saddr_v4,sport,daddr_v4,dport,pkt_info->dir,recv_len); - break; - case DELIVER_FLAG_ENT: - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld", - saddr_v4,sport,daddr_v4,dport,session_info->recv_pkt,session_info->recv_byte, - session_info->send_pkt,session_info->recv_byte); - break; - } - - return 0; - -} - - -int deliver_sendpkt_ether(int thread_seq,int buflen,unsigned char* buf,unsigned char* dmac) -{ - int ret=0; - - if(-1==ioctl(g_deliver_globle_info.sendinfo.send_socket[thread_seq],SIOCGIFINDEX,&(g_deliver_globle_info.sendinfo.ifr))) - { - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"get if index error:%d,%s,name:%d",errno,strerror(errno),g_deliver_globle_info.sendinfo.senddevice); - return -1; - } - -// struct sockaddr_ll addr={0}; - struct sockaddr_ll addr; - memset(&addr,0,sizeof(struct sockaddr_ll)); - - addr.sll_family=AF_PACKET; - addr.sll_halen=ETHER_ADDR_LEN; - addr.sll_ifindex=g_deliver_globle_info.sendinfo.ifr.ifr_ifindex; - addr.sll_protocol=htons(ETH_P_IP); - memcpy(addr.sll_addr,dmac,ETHER_ADDR_LEN); - - - if(ioctl(g_deliver_globle_info.sendinfo.send_socket[thread_seq],SIOCGIFHWADDR,&(g_deliver_globle_info.sendinfo.ifr))==-1) - { - return -1; - } - - ret=sendto(g_deliver_globle_info.sendinfo.send_socket[thread_seq],buf,buflen,0,(struct sockaddr*)&addr,sizeof(addr)); - if(ret<0) - { - deliver_set_filestate2(thread_seq,FS2_COLUME_ERROR,1); - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_SENDPKT,"sendto() error,errno:%d,msg:%s!",errno,strerror(errno)); - return ret; - } - - - deliver_set_filestate2(thread_seq,FS2_COLUME_SENDPKT,1); - deliver_set_filestate2(thread_seq,FS2_COLUME_SENDBYTE,buflen-14-20-20); - - return ret; - -} - - -int deliver_init_pmeinfo(const struct tfe_stream_addr* addr,void** pme) -{ -//TODO:choose dst mac - int i=deliver_rand()%(g_deliver_globle_info.sendinfo.receiver_num); - - struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)malloc(sizeof(struct deliver_pme_info)); - memset(pmeinfo,0,sizeof(struct deliver_pme_info)); - pmeinfo->addr_info = addr; - memcpy(pmeinfo->dst_macaddr,g_deliver_globle_info.sendinfo.receiver_info[i].dst_macaddr,DELIVER_MACADDR_LEN); - - *pme=pmeinfo; - - return 0; -} - - -int deliver_send_v6(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,const unsigned char* payload) -{ - int offset = 0; - unsigned short eth_type=0x0800; - - - int cur_dir=pmeinfo->pkt_info.dir; - const struct tfe_stream_addr* addr_info = pmeinfo->addr_info; - struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info); - - offset = sizeof(struct mesa_ethernet_hdr); - - if(cur_dir==CONN_DIR_DOWNSTREAM) - { - deliver_build_tcp(ntohs(addr_info->tuple4_v6->source), ntohs(addr_info->tuple4_v6->dest), - curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, - payload,payload_len, - g_deliver_globle_info.sendbuf[thread_seq]+offset+sizeof(struct mesa_ip6_hdr)); - - deliver_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, curpkt_info->ttl, - &(addr_info->tuple4_v6->saddr),&(addr_info->tuple4_v6->daddr),NULL, 0, - g_deliver_globle_info.sendbuf[thread_seq]+offset); - - } - else - { - deliver_build_tcp(ntohs(addr_info->tuple4_v6->dest), ntohs(addr_info->tuple4_v6->source), - curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, - payload,payload_len, - g_deliver_globle_info.sendbuf[thread_seq]+offset+sizeof(struct mesa_ip6_hdr)); - - deliver_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, curpkt_info->ttl, - &(addr_info->tuple4_v6->daddr),&(addr_info->tuple4_v6->saddr),NULL, 0, - g_deliver_globle_info.sendbuf[thread_seq]+offset); - } - - - - - - deliver_do_checksum(g_deliver_globle_info.sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); - -// deliver_do_checksum(g_deliver_globle_info.sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H); - - - deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_globle_info.sendinfo.src_macaddr), - eth_type,NULL,0,(unsigned char*)g_deliver_globle_info.sendbuf[thread_seq]); - - deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len, - g_deliver_globle_info.sendbuf[thread_seq],pmeinfo->dst_macaddr); - - - pmeinfo->session_info.send_pkt++; - pmeinfo->session_info.send_byte+=payload_len; - - deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0); - - return 0; - - -} - - -int deliver_send_v4(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,const unsigned char* payload) -{ - int offset = 0; - unsigned short eth_type=0x0800; - - - int cur_dir=pmeinfo->pkt_info.dir; - const struct tfe_stream_addr* addr_info = pmeinfo->addr_info; - struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info); - - offset = sizeof(struct mesa_ethernet_hdr); - - if(cur_dir==CONN_DIR_DOWNSTREAM) - { - deliver_build_tcp(ntohs(addr_info->tuple4_v4->source), ntohs(addr_info->tuple4_v4->dest), - curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, - payload,payload_len, - g_deliver_globle_info.sendbuf[thread_seq]+offset+sizeof(struct mesa_ip4_hdr)); - - deliver_build_ipv4(SENDPACKET_TCP_H+payload_len, 0, curpkt_info->ipid, 0, 64, IPPROTO_TCP, - addr_info->tuple4_v4->saddr.s_addr,addr_info->tuple4_v4->daddr.s_addr, NULL, 0, - g_deliver_globle_info.sendbuf[thread_seq]+offset); - } - else - { - deliver_build_tcp(ntohs(addr_info->tuple4_v4->dest), ntohs(addr_info->tuple4_v4->source), - curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, - payload,payload_len, - g_deliver_globle_info.sendbuf[thread_seq]+offset+sizeof(struct mesa_ip4_hdr)); - - deliver_build_ipv4(SENDPACKET_TCP_H+payload_len, 0, curpkt_info->ipid, 0, 64, IPPROTO_TCP, - addr_info->tuple4_v4->daddr.s_addr,addr_info->tuple4_v4->saddr.s_addr, NULL, 0, - g_deliver_globle_info.sendbuf[thread_seq]+offset); - } - - - deliver_do_checksum(g_deliver_globle_info.sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); - - deliver_do_checksum(g_deliver_globle_info.sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H); - - - deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_globle_info.sendinfo.src_macaddr), - eth_type,NULL,0,(unsigned char*)g_deliver_globle_info.sendbuf[thread_seq]); - - deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len, - g_deliver_globle_info.sendbuf[thread_seq],pmeinfo->dst_macaddr); - - - pmeinfo->session_info.send_pkt++; - pmeinfo->session_info.send_byte+=payload_len; - - deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0); - - - return 0; - - -} - -int deliver_send_syn(int thread_seq,struct deliver_pme_info* pmeinfo) -{ - pmeinfo->pkt_info.dir=CONN_DIR_DOWNSTREAM; - pmeinfo->pkt_info.len=0; - pmeinfo->pkt_info.seq= deliver_rand(); - pmeinfo->pkt_info.ack=0; - pmeinfo->pkt_info.flag=TH_SYN; - pmeinfo->pkt_info.win = deliver_rand_range(1460, 65500); - pmeinfo->pkt_info.ipid = deliver_rand() % 65535; - pmeinfo->pkt_info.ttl=deliver_rand_range(32,65); - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_seq,pmeinfo,0,NULL); - deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_seq,pmeinfo,0,NULL); - deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0); - } - else - { - //TODO - } - - return 0; -} - -int deliver_send_syn_ack(int thread_seq,struct deliver_pme_info* pmeinfo) -{ - pmeinfo->pkt_info.dir=CONN_DIR_UPSTREAM; - pmeinfo->pkt_info.len=0; - pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1; - pmeinfo->pkt_info.seq= deliver_rand(); - pmeinfo->pkt_info.flag=TH_SYN|TH_ACK; - - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_seq,pmeinfo,0,NULL); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_seq,pmeinfo,0,NULL); - } - else - { -//TODO - } - - return 0; -} - - - -int deliver_send_ack(int thread_seq,struct deliver_pme_info* pmeinfo) -{ - unsigned int ack_tmp=pmeinfo->pkt_info.ack; - - pmeinfo->pkt_info.dir=CONN_DIR_DOWNSTREAM; - pmeinfo->pkt_info.len=0; - pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1; - pmeinfo->pkt_info.seq= ack_tmp; - pmeinfo->pkt_info.flag=TH_ACK; - - - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_seq,pmeinfo,0,NULL); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_seq,pmeinfo,0,NULL); - } - else - { -//todo - } - - return 0; -} - - -int deliver_set_pktinfo(struct deliver_pme_info* pmeinfo,int flag, int cur_dir,int payload_len) -{ - struct deliver_pkt_info last_pkt_info; - memcpy((void*)&last_pkt_info,(void*)&(pmeinfo->pkt_info),sizeof(struct deliver_pkt_info)); - - pmeinfo->pkt_info.dir=cur_dir; - pmeinfo->pkt_info.len=payload_len; - pmeinfo->pkt_info.flag=flag; - - - if(cur_dir==last_pkt_info.dir) - { - pmeinfo->pkt_info.seq=last_pkt_info.seq+last_pkt_info.len; - pmeinfo->pkt_info.ack=last_pkt_info.ack; - } - else - { - pmeinfo->pkt_info.seq=last_pkt_info.ack; - pmeinfo->pkt_info.ack=last_pkt_info.seq+last_pkt_info.len; - } - - return 0; - -} - -int deliver_send_rst(int thread_seq,struct deliver_pme_info* pmeinfo) -{ - deliver_set_pktinfo(pmeinfo,TH_RST,CONN_DIR_DOWNSTREAM,0); - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_seq,pmeinfo,0,NULL); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_seq,pmeinfo,0,NULL); - } - else - { -//TODO - } - - - deliver_set_pktinfo(pmeinfo,TH_RST,CONN_DIR_UPSTREAM,0); - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_seq,pmeinfo,0,NULL); - deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_seq,pmeinfo,0,NULL); - deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0); - } - else - { -//TODO - } - - return 0; -} - - - -int mirror_stream_open(int thread_id, const struct tfe_stream_addr* addr,void** pme) -{ - if(g_deliver_globle_info.deliver_switch == 0) - { - MESA_handle_runtime_log(g_deliver_globle_info.comminfo.logger,RLOG_LV_INFO,DELIVER_MODULE_INIT,"mirror_stream switch is 0,not run...."); - return -1; - } - - struct deliver_pme_info* pmeinfo=NULL; - - deliver_init_pmeinfo(addr,pme); - pmeinfo=(struct deliver_pme_info*)*pme; - - deliver_send_syn(thread_id,pmeinfo); - deliver_send_syn_ack(thread_id,pmeinfo); - deliver_send_ack(thread_id,pmeinfo); - - return 0; - -} - -int mirror_stream_write(int cur_dir,const unsigned char * data, size_t len, void** pme,int thread_id) -{ - if(g_deliver_globle_info.deliver_switch == 0) - { - return -1; - } - - int i=0; - const unsigned char* payload=data; - int payload_len=0; - int remain_len=len; - int max_payloadlen_per=0; - int pkt_num=0; -// int pkt_num=(len/(g_deliver_globle_info.sendinfo.mtu))+1; - struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme; - - - deliver_set_filestate2(thread_id,FS2_COLUME_RECVPKT,1); - deliver_set_filestate2(thread_id,FS2_COLUME_RECVBYTE,len); - - pmeinfo->session_info.recv_pkt++; - pmeinfo->session_info.recv_byte+=len; - if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,len); - max_payloadlen_per=g_deliver_globle_info.sendinfo.mtu-sizeof(struct mesa_tcp_hdr)-sizeof(struct mesa_ip4_hdr); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,len); - max_payloadlen_per=g_deliver_globle_info.sendinfo.mtu-sizeof(struct mesa_tcp_hdr)-sizeof(struct mesa_ip6_hdr); - } - else - { - //TODO - } - - pkt_num=(len/(max_payloadlen_per))+1; - - for(i=0;iaddr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V4) - { - deliver_send_v4(thread_id,pmeinfo,payload_len,payload); - } - else if(pmeinfo->addr_info->addrtype==TFE_ADDR_STREAM_TUPLE4_V6) - { - deliver_send_v6(thread_id,pmeinfo,payload_len,payload); - } - else - { -//TODO - } - } - - return 0; -} - - -void mirror_stream_close(void** pme, int thread_id) -{ - if(g_deliver_globle_info.deliver_switch == 0) - { - return; - } - - - struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme; - - deliver_send_rst(thread_id,pmeinfo); - - - if(*pme!=NULL) - { - free(*pme); - *pme=NULL; - } - return; -} - - -int deliver_device_init() -{ - char* if_name=g_deliver_globle_info.sendinfo.senddevice; - -//init socket - size_t ifname_len=strlen(if_name); - if(ifname_len +#include +#include +#include + +struct traffic_mirror_rebuild +{ + struct tfe_stream_addr * addr; + struct profile_table_ex_data * target; + struct traffic_mirror_ethdev * ethdev; + + uint32_t c_seq; + uint32_t s_seq; + uint32_t c_ipid; + uint32_t s_ipid; + uint8_t c_ttl; + uint8_t s_ttl; +}; + +static int tcp_header_construct(unsigned char *buf, unsigned short sp, + unsigned short dp, unsigned int seq, unsigned int ack, + unsigned char flags, unsigned short win, unsigned short urg) +{ + struct tcphdr * tcp_hdr = (struct tcphdr *) buf; + assert(tcp_hdr != NULL); + + tcp_hdr->th_sport = sp; + tcp_hdr->th_dport = dp; + tcp_hdr->th_seq = htonl(seq); + tcp_hdr->th_ack = htonl(ack); + tcp_hdr->th_flags = flags; + tcp_hdr->th_x2 = 0; + tcp_hdr->th_off = 5; /* 20 byte header */ + tcp_hdr->th_win = htons(win); /* window size */ + tcp_hdr->th_sum = 0; /* checksum done in userland */ + tcp_hdr->th_urp = 0; /* urgent pointer */ + + return sizeof(struct tcphdr); +} + +static int tcp_header_construct_by_stream_addr(struct tfe_stream_addr * addr, unsigned char *buf, + unsigned int seq, unsigned int ack, unsigned char flags, unsigned short win, unsigned short urg) +{ + unsigned short sport; + unsigned short dport; + + if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4) + { + sport = addr->tuple4_v4->source; + dport = addr->tuple4_v4->dest; + } + else if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V6) + { + sport = addr->tuple4_v6->source; + dport = addr->tuple4_v6->dest; + } + else + { + assert(0); + } + + return tcp_header_construct(buf, sport, dport, seq, ack, flags, win, urg); +} + +static int ipv4_header_construct(unsigned char *buf, unsigned short carry_layer_len, + unsigned char tos, unsigned short id, unsigned short frag, unsigned char ttl, + unsigned char protocol, unsigned int src, unsigned int dst) +{ + struct iphdr * ip_hdr = (struct iphdr *) buf; + ip_hdr->version = 4; + ip_hdr->ihl = 5; + ip_hdr->tos = tos; + ip_hdr->tot_len = htons(sizeof(struct iphdr) + carry_layer_len); + ip_hdr->id = htons(id); + ip_hdr->frag_off = 0; + ip_hdr->ttl = ttl; + ip_hdr->protocol = protocol; + ip_hdr->check = 0; + ip_hdr->saddr = src; + ip_hdr->daddr = dst; + + return sizeof(struct iphdr); +} + +static int ip_header_construct_by_stream_addr(struct tfe_stream_addr * addr, + unsigned char *buf, unsigned short carry_layer_len, unsigned char tos, + unsigned short id, unsigned short frag, unsigned char ttl, unsigned char protocol) +{ + if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4) + { + return ipv4_header_construct(buf, carry_layer_len, tos, id, + frag, ttl, protocol, addr->tuple4_v4->saddr.s_addr, addr->tuple4_v4->daddr.s_addr); + } + + assert(0); + return -1; +} + +static void ether_header_construct(unsigned char *buf, unsigned char *dst, + unsigned char *src, unsigned short type) +{ + struct ethhdr * eth_hdr = (struct ethhdr *) buf; + memcpy(eth_hdr->h_dest, dst, ETHER_ADDR_LEN); + memcpy(eth_hdr->h_source, src, ETHER_ADDR_LEN); + eth_hdr->h_proto = htons(type); +} + +struct vlan_hdr +{ + uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */ + uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */ +} __attribute__((__packed__)); + +static void vlan_tag_construct(unsigned char *buf, unsigned short tci, unsigned short type) +{ + struct vlan_hdr * vlan_hdr = (struct vlan_hdr *)buf; + vlan_hdr->vlan_tci = htons(tci); + vlan_hdr->eth_proto = htons(type); +} + +static void l2_send_to_target(struct traffic_mirror_ethdev * ethdev, + unsigned char * snd_buffer, unsigned int l3_data_offset, unsigned int l3_data_len, + struct ether_addr * target_addr, unsigned int vlan_tci, unsigned l3_protocol) +{ + assert(l3_data_offset >= (sizeof(struct ethhdr) + sizeof(struct vlan_hdr))); + unsigned int header_offset = l3_data_offset; + + /* need to construct vlan header */ + if (vlan_tci > 0) + { + header_offset -= sizeof(struct vlan_hdr); + vlan_tag_construct(snd_buffer + header_offset, vlan_tci, l3_protocol); + } + + unsigned int eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol; + header_offset -= sizeof(struct ethhdr); + + ether_header_construct(snd_buffer + header_offset, (unsigned char *)target_addr->ether_addr_octet, + (unsigned char *)ethdev->local_ether_addr, eth_protocol); +} + +static void l2_send_to_target_group(struct traffic_mirror_ethdev * ethdev, struct profile_table_ex_data * t_group, + unsigned char * snd_buffer, unsigned int l3_data_offset, unsigned int l3_data_len, unsigned l3_protocol) +{ + for(unsigned int i = 0; i < t_group->nr_targets; i++) + { + l2_send_to_target(ethdev, snd_buffer, l3_data_offset, l3_data_len, + &t_group->ether_addrs[i], t_group->vlans[i], l3_protocol); + } +} + +static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev, + struct profile_table_ex_data * t_group, const char * payload, unsigned int payload_len, + unsigned int seq, unsigned int ack, char flags) +{ + char pkt[ETHER_MAX_LEN]; + unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct tcphdr); + unsigned l3_l4_header_len = 0; + + l3_l4_header_len += tcp_header_construct_by_stream_addr(addr, + (unsigned char *)pkt + sz_pkt_prepend, seq, ack, flags, 0xffff, 0); + + l3_l4_header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend, + sizeof(struct tcphdr) + payload_len, 0, 0x1000, 0, 128, IPPROTO_TCP); + + sz_pkt_prepend -= l3_l4_header_len; + + l2_send_to_target_group(ethdev, t_group, (unsigned char *)pkt, + sz_pkt_prepend, l3_l4_header_len + payload_len, ETHERTYPE_IP); +} + +static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev, + struct profile_table_ex_data * t_group, const char * payload, + unsigned int payload_len, unsigned int seq, unsigned int ack, char flags) +{ + unsigned int payload_offset = 0; + unsigned mss = ethdev->mtu - (sizeof(struct iphdr) + sizeof(struct tcphdr)); + + while(payload_offset < payload_len) + { + unsigned int payload_sz_seg = MIN(payload_offset, mss); + const char * payload_ptr_seg = payload + payload_offset; + + tcp_segment_send_to_target_group(addr, ethdev, t_group, payload_ptr_seg, payload_sz_seg, seq, ack, flags); + seq += payload_sz_seg; + payload_offset += payload_sz_seg; + } +} + +struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr, + struct profile_table_ex_data * target, struct traffic_mirror_ethdev * ethdev) +{ + struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1); + instance->target = target; + instance->ethdev = ethdev; + + /* the c_seq, s_seq, c_ipid, s_ipid is random + * TODO: use the fast random algorithm like Linux TCP/IP stack */ + instance->c_seq = random(); + instance->s_seq = random(); + instance->c_ipid = random(); + instance->s_ipid = random(); + instance->s_ttl = 128; + instance->c_ttl = 64; + return instance; +} + +void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance) +{ + free(instance); +} + +void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance) +{ + tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target, + NULL, 0, instance->c_seq, 0, TH_SYN); + + tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target, + NULL, 0, instance->s_seq, instance->c_seq + 1, TH_SYN | TH_ACK); + + tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target, + NULL, 0, instance->c_seq + 1, instance->s_seq + 1, TH_ACK); + + instance->s_seq++; + instance->c_seq++; +} + +void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance, + const char * data, unsigned int datalen, enum tfe_conn_dir dir) +{ + if (dir == CONN_DIR_DOWNSTREAM) + { + tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target, + NULL, 0, instance->c_seq, instance->s_seq + 1, TH_ACK); + + instance->c_seq += datalen; + } + else + { + tcp_send_to_target_group(instance->addr, instance->ethdev, instance->target, + NULL, 0, instance->s_seq, instance->c_seq + 1, TH_ACK); + + instance->s_seq += datalen; + } +} + +void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance) +{ + return; +} diff --git a/plugin/business/decrypt-mirroring/src/sendpkt.cpp b/plugin/business/decrypt-mirroring/src/sendpkt.cpp deleted file mode 100644 index 1360f33..0000000 --- a/plugin/business/decrypt-mirroring/src/sendpkt.cpp +++ /dev/null @@ -1,467 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static volatile uint64_t g_rand_seed = 0x013579ABCDEF; - -#define SENDPACKET_CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) - -unsigned int deliver_rand(void) -{ - return g_rand_seed ^ (unsigned int)random(); -} - -unsigned int deliver_rand_range(unsigned int start, unsigned int end) -{ - unsigned int rand_num = deliver_rand(); - - if(start > end) - { - return end + rand_num % (start - end + 1); - } - - return start + rand_num % (end - start + 1); -} - - - -/* ascii字符转16进制 */ -char MESA_ascii_to_hex(char ascii) -{ - char c = 0; - - switch(ascii) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - c = ascii - 0x30; - break; - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - c = 10 + ascii - 0x61; - break; - - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - c = 10 + ascii - 0x41; - break; - } - - return c; -} - - - -/* 2012-04-10 LiJia add, 获取网卡MAC地址 -参数: - device: 网卡名称 - mac: 存储MAC地址的数组,结果为网络序, - 如网卡MAC地址为11:22:33:44:55:66,则mac[0]为0x11,mac[5]为0x66. -返回值: - 0: 正常 - -1:错误 -*/ -int deliver_get_dev_mac(const char *device, unsigned char mac[6]) -{ - struct ifreq ifr; - int fd; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if(fd < 0) - { - return -1; - } - - memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name)); - strncpy(ifr.ifr_ifrn.ifrn_name, device, sizeof(ifr.ifr_ifrn.ifrn_name)); - if(ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) - { - printf("Cann't get hwaddr of %s:%s\n", device, strerror(errno)); - goto err_exit; - } - - if(ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) - { - printf("'%s' is not ethernet interface!\n", device); - goto err_exit; - } - - memcpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, 6); - - close(fd); - - return 0; - -err_exit: - close(fd); - return -1; -} - - - -/* 2012-04-11 LiJia add,将MAC字符串形式转换为16进制MAC地址. -参数: - str: MAC地址字符串 - delim: 字符串分隔符,常见为':', '-'等,如: xx:xx:xx:xx:xx:xx - 如果字符串无分隔符,delim设为-1. - mac: 存储MAC地址的数组(指针),结果为网络序, - 如网卡MAC地址为11:22:33:44:55:66,则mac[0]为0x11,mac[5]为0x66. -返回值: - 0: 正常 - -1:错误 -*/ -int deliver_mac_pton(const char *str, int delim, char *mac) -{ -#define MAC_STR_LEN_DELIM (17) /* length of "11:22:33:44:55:66" */ -#define MAC_STR_LEN_NODELIM (12) /* length of "112233445566" */ - const char *s = str; - int i; - - /* 检查输入合法性 */ - if(delim != -1) - { - if(strlen(str) != MAC_STR_LEN_DELIM) - { - printf("MAC string length error!\n"); - return -1; - } - } - else - { - if(strlen(str) != MAC_STR_LEN_NODELIM) - { - printf("MAC string length error!\n"); - return -1; - } - } - - /* 检查输入合法性,同时转换成16进制值 */ - for(i = 0; i < 6; i++) - { - mac[i] = 0; /* 先清零,赋值语句都是或操作 */ - if(isxdigit(*s)==0) - { - printf("MAC string type error!\n"); - return -1; - } - mac[i] |= MESA_ascii_to_hex(*s) << 4; - s++; - - if(isxdigit(*s)==0) - { - printf("MAC string type error!\n"); - return -1; - } - mac[i] |= MESA_ascii_to_hex(*s); - s++; - - if((delim != -1) && i<5 && (*s++ != (char)delim)) - { - printf("MAC string type error!\n"); - return -1; - } - } - - return 0; -} - - - - - -int sendpacket_in_cksum(unsigned short *addr, int len) -{ - int sum; - int nleft; - unsigned short ans; - unsigned short *w; - - sum = 0; - ans = 0; - nleft = len; - w = addr; - - while (nleft > 1) - { - sum += *w++; - nleft -= 2; - } - if (nleft == 1) - { - *(char *)(&ans) = *(char *)w; - sum += ans; - } - return (sum); -} - - - -int deliver_do_checksum(unsigned char *buf, int protocol, int len) -{ - struct mesa_ip4_hdr *iph_p; - struct mesa_ip6_hdr *ip6h_p; - int ip_hl; - int sum; - int is_ipv6 = 0; - - sum = 0; - iph_p = (struct mesa_ip4_hdr *)buf; - - if(4 == iph_p->ip_v) /* IP版本号字段,IPv4和IPv6格式是相同的 */ - { - ip_hl = iph_p->ip_hl << 2; - ip6h_p = NULL; - } - else if(6 == iph_p->ip_v) - { - ip6h_p = (struct mesa_ip6_hdr *)buf; - iph_p = NULL; - ip_hl = sizeof(struct mesa_ip6_hdr); - is_ipv6 = 1; - } - else - { - return (-1); - } - - switch (protocol) - { - case IPPROTO_TCP: - { - struct mesa_tcp_hdr *tcph_p = (struct mesa_tcp_hdr *)(buf + ip_hl); - - tcph_p->th_sum = 0; - if(is_ipv6) - { - sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32); - } - else - { - sum = sendpacket_in_cksum((unsigned short *)&iph_p->ip_src, 8); - } - sum += ntohs(IPPROTO_TCP + len); - sum += sendpacket_in_cksum((unsigned short *)tcph_p, len); - tcph_p->th_sum = SENDPACKET_CKSUM_CARRY(sum); - break; - } - - case IPPROTO_UDP: - { - struct mesa_udp_hdr *udph_p =(struct mesa_udp_hdr *)(buf + ip_hl); - - udph_p->uh_sum = 0; - if(is_ipv6) - { - sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32); - } - else - { - sum = sendpacket_in_cksum((unsigned short*)&iph_p->ip_src, 8); - } - sum += ntohs(IPPROTO_UDP + len); - sum += sendpacket_in_cksum((unsigned short*)udph_p, len); - udph_p->uh_sum = SENDPACKET_CKSUM_CARRY(sum); - break; - } - - case IPPROTO_IP: - { - iph_p->ip_sum = 0; - sum = sendpacket_in_cksum((unsigned short*)iph_p, len); - iph_p->ip_sum = SENDPACKET_CKSUM_CARRY(sum); - break; - } - - default: - { - return (-1); - } - } - return (1); -} - - - - -/* - if playload2 is not NULL, it means that there is ip spice, it must be copied first, then - playload is copied - otherwise, only payload is copied and it includes ip header -*/ -int deliver_build_ethhdr(unsigned char *dst, unsigned char *src, unsigned short type,unsigned char *buf) -{ - struct mesa_ethernet_hdr eth_hdr; - - if (!buf) - { - return (-1); - } - - memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */ - memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */ - eth_hdr.ether_type = htons(type); /* packet type */ - - memcpy(buf, ð_hdr, sizeof(eth_hdr)); - return (0); -} - - - -/* - if playload2 is not NULL, it means that there is ip spice, it must be copied first, then - playload is copied - otherwise, only payload is copied and it includes ip header -*/ -int deliver_build_ethernet(unsigned char *dst, unsigned char *src, unsigned short type, - const unsigned char *payload, int payload_s, unsigned char *buf) -{ - struct mesa_ethernet_hdr eth_hdr; - - if (!buf) - { - return (-1); - } - - memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */ - memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */ - eth_hdr.ether_type = htons(type); /* packet type */ - - if (payload && payload_s) - { - memcpy(buf + SENDPACKET_ETH_H, payload, payload_s); - } - memcpy(buf, ð_hdr, sizeof(eth_hdr)); - return (0); -} - - - -int deliver_build_ipv6(unsigned char traffic_class, unsigned int flow_lable, - unsigned short len, unsigned char next_header, unsigned char hop, - const struct in6_addr *src, const struct in6_addr *dst, - const unsigned char *payload, int payload_s, unsigned char *buf) -{ - struct mesa_ip6_hdr *ip6_h; - - if(!buf){ - return -1; - } - - ip6_h = (struct mesa_ip6_hdr *)buf; - - memset(ip6_h, 0, sizeof(struct mesa_ip6_hdr)); - - ip6_h->ip6_flags[0] = 0x60 | ((traffic_class & 0xF0) >> 4); - ip6_h->ip6_flags[1] = ((traffic_class & 0x0F) << 4) | ((flow_lable & 0xF0000) >> 16); - ip6_h->ip6_flags[2] = flow_lable & 0x0FF00 >> 8; - ip6_h->ip6_flags[3] = flow_lable & 0x000FF; - ip6_h->ip6_payload_len = htons(len); - ip6_h->ip6_nxt_hdr = next_header; - ip6_h->ip6_hop = hop; - memcpy(&ip6_h->ip6_src, src, sizeof(struct in6_addr)); - memcpy(&ip6_h->ip6_dst, dst, sizeof(struct in6_addr)); - - if(payload && payload_s) - { - memcpy(buf + sizeof(struct mesa_ip6_hdr), payload, payload_s); - } - - return 0; -} - - - -int deliver_build_ipv4(unsigned short carry_layer_len, unsigned char tos, unsigned short id, - unsigned short frag, unsigned char ttl, unsigned char prot, unsigned int src, unsigned int dst, - const unsigned char *payload,int payload_s, unsigned char *buf) -{ - struct mesa_ip4_hdr *ip_hdr; - - if (!buf) - { - return (-1); - } - - ip_hdr = (struct mesa_ip4_hdr *)buf; - - ip_hdr->ip_v = 4; /* version 4 */ - ip_hdr->ip_hl = 5; /* 20 byte header */ - ip_hdr->ip_tos = tos; /* IP tos */ - ip_hdr->ip_len = htons(SENDPACKET_IP_H + carry_layer_len); /* total length */ - ip_hdr->ip_id = htons(id); /* IP ID */ - ip_hdr->ip_off = htons(frag); /* fragmentation flags */ - ip_hdr->ip_ttl = ttl; /* time to live */ - ip_hdr->ip_p = prot; /* transport protocol */ - ip_hdr->ip_sum = 0; /* do this later */ - ip_hdr->ip_src.s_addr = src; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */ - ip_hdr->ip_dst.s_addr = dst; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */ - if (payload && payload_s) - { - memcpy(buf + SENDPACKET_IP_H, payload, payload_s); - } - - return (0); -} - - -int deliver_build_tcp(unsigned short sp, unsigned short dp, unsigned int seq, unsigned int ack, - unsigned char th_flags, unsigned short win, unsigned short urg, - const unsigned char *payload, int payload_s, unsigned char *buf) -{ - struct mesa_tcp_hdr *tcp_hdr; - - if (!buf) - { - return (-1); - } - - tcp_hdr = (struct mesa_tcp_hdr *)buf; - - tcp_hdr->th_sport = htons(sp); /* source port */ - tcp_hdr->th_dport = htons(dp); /* destination port */ - tcp_hdr->th_seq = htonl(seq); /* sequence number */ - tcp_hdr->th_ack = htonl(ack); /* acknowledgement number */ - tcp_hdr->th_flags = th_flags; /* control flags */ - tcp_hdr->th_x2 = 0; /* UNUSED */ - tcp_hdr->th_off = 5; /* 20 byte header */ - tcp_hdr->th_win = htons(win); /* window size */ - tcp_hdr->th_sum = 0; /* checksum done in userland */ - tcp_hdr->th_urp = urg; /* urgent pointer */ - - if (payload && payload_s) - { -// memcpy(buf + SENDPACKET_TCP_H, payload, payload_s); - memcpy(buf + sizeof(struct mesa_tcp_hdr), payload, payload_s); - } - - return (0); - -} - - - -