summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2020-12-15 15:59:33 +0800
committerlijia <[email protected]>2020-12-15 15:59:33 +0800
commitd529c6eb2eb516b7d69185f41d13c9030f4f76a5 (patch)
tree6c59fd4efbe6e5492313c5d65ea154a70bb36ddf
parent4bfc910b6fabbec7d9ae1bcac99a188cd714e4f7 (diff)
fs2增加tcp丢包计数,增加udp单向流C2S,S2C计数.v4.2.10
-rw-r--r--src/inner_plug/sapp_assistant.cpp16
-rw-r--r--src/packet_io/packet_io_status.cpp22
-rw-r--r--test/test_app_sapp_tcp_lost_len.c3340
3 files changed, 3376 insertions, 2 deletions
diff --git a/src/inner_plug/sapp_assistant.cpp b/src/inner_plug/sapp_assistant.cpp
index f6cb7ea..4f12a1a 100644
--- a/src/inner_plug/sapp_assistant.cpp
+++ b/src/inner_plug/sapp_assistant.cpp
@@ -980,6 +980,7 @@ static int sapp_fs2_init(void)
pfs_para->fs_id_count_array[SAPP_STAT_RCV_TCP] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Tcp_Pkt");
pfs_para->fs_id_length_array[SAPP_STAT_RCV_TCP] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Tcp_Bit");
+ pfs_para->fs_id_count_array[SAPP_STAT_TCP_LOST_PKT] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Tcp_Lost_Bit");
pfs_para->fs_id_count_array[SAPP_STAT_RCV_UDP] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Udp_Pkt");
pfs_para->fs_id_length_array[SAPP_STAT_RCV_UDP] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Udp_Bit");
@@ -995,10 +996,25 @@ static int sapp_fs2_init(void)
pfs_para->fs_id_count_array[SAPP_STAT_TCP_STREAM_C2S] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Tcp_Link_C2S");
pfs_para->fs_id_count_array[SAPP_STAT_TCP_STREAM_S2C] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Tcp_Link_S2C");
+ pfs_para->fs_id_count_array[SAPP_STAT_TCP_STREAM_TOTAL_DOUBLE] = FS_register(fs2_handle, FS_STYLE_STATUS,FS_CALC_CURRENT, "Tcp_Link_Double_ALL");
+ pfs_para->fs_id_count_array[SAPP_STAT_TCP_STREAM_TOTAL_C2S] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Tcp_Link_C2S_ALL");
+ pfs_para->fs_id_count_array[SAPP_STAT_TCP_STREAM_TOTAL_S2C] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Tcp_Link_S2C_ALL");
+
+
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_DOUBLE] = FS_register(fs2_handle, FS_STYLE_STATUS,FS_CALC_CURRENT, "Udp_Link_Double");
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_C2S] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Udp_Link_C2S");
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_S2C] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Udp_Link_S2C");
+
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_TOTAL_DOUBLE] = FS_register(fs2_handle, FS_STYLE_STATUS,FS_CALC_CURRENT, "Udp_Link_Double_ALL");
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_TOTAL_C2S] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Udp_Link_C2S_ALL");
+ pfs_para->fs_id_count_array[SAPP_STAT_UDP_STREAM_TOTAL_S2C] = FS_register(fs2_handle,FS_STYLE_STATUS, FS_CALC_CURRENT, "Udp_Link_S2C_ALL");
+
pfs_para->fs_id_count_array[SAPP_STAT_SND_TCP_RST] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Send_Tcp_Rst");
pfs_para->fs_id_count_array[SAPP_STAT_SND_TCP_SYNACK] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Send_Tcp_S/A");
pfs_para->fs_id_count_array[SAPP_STAT_SND_UDP] = FS_register(fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "Send_Udp");
+
+
if(unlikely(g_timestamp_record_sw))
{
diff --git a/src/packet_io/packet_io_status.cpp b/src/packet_io/packet_io_status.cpp
index ba4983a..23c5a54 100644
--- a/src/packet_io/packet_io_status.cpp
+++ b/src/packet_io/packet_io_status.cpp
@@ -138,6 +138,8 @@ static void field_stat2_update_metrics(void)
sapp_fs2_update_count(SAPP_STAT_RCV_TCP, cur_count[SAPP_STAT_RCV_TCP]);
sapp_fs2_update_length(SAPP_STAT_RCV_TCP, 8 *(cur_length[SAPP_STAT_RCV_TCP]));
+
+ sapp_fs2_update_length(SAPP_STAT_TCP_LOST_PKT, 8 *(cur_length[SAPP_STAT_TCP_LOST_PKT]));
sapp_fs2_update_count(SAPP_STAT_RCV_UDP, cur_count[SAPP_STAT_RCV_UDP]);
sapp_fs2_update_length(SAPP_STAT_RCV_UDP, 8 *(cur_length[SAPP_STAT_RCV_UDP]));
@@ -150,9 +152,25 @@ static void field_stat2_update_metrics(void)
sapp_fs2_update_count(SAPP_STAT_TCP_STREAM_C2S, cur_count[SAPP_STAT_TCP_STREAM_C2S]);
sapp_fs2_update_count(SAPP_STAT_TCP_STREAM_S2C, cur_count[SAPP_STAT_TCP_STREAM_S2C]);
+ sapp_fs2_update_count(SAPP_STAT_TCP_STREAM_TOTAL_DOUBLE,cur_count[SAPP_STAT_TCP_STREAM_TOTAL_DOUBLE]);
+ sapp_fs2_update_count(SAPP_STAT_TCP_STREAM_TOTAL_C2S, cur_count[SAPP_STAT_TCP_STREAM_TOTAL_C2S]);
+ sapp_fs2_update_count(SAPP_STAT_TCP_STREAM_TOTAL_S2C, cur_count[SAPP_STAT_TCP_STREAM_TOTAL_S2C]);
+
+
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_DOUBLE,cur_count[SAPP_STAT_UDP_STREAM_DOUBLE]);
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_C2S, cur_count[SAPP_STAT_UDP_STREAM_C2S]);
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_S2C, cur_count[SAPP_STAT_UDP_STREAM_S2C]);
+
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_TOTAL_DOUBLE,cur_count[SAPP_STAT_UDP_STREAM_TOTAL_DOUBLE]);
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_TOTAL_C2S, cur_count[SAPP_STAT_UDP_STREAM_TOTAL_C2S]);
+ sapp_fs2_update_count(SAPP_STAT_UDP_STREAM_TOTAL_S2C, cur_count[SAPP_STAT_UDP_STREAM_TOTAL_S2C]);
+
sapp_fs2_update_count(SAPP_STAT_SND_TCP_RST, cur_count[SAPP_STAT_SND_TCP_RST]);
sapp_fs2_update_count(SAPP_STAT_SND_TCP_SYNACK, cur_count[SAPP_STAT_SND_TCP_SYNACK]);
sapp_fs2_update_count(SAPP_STAT_SND_UDP, cur_count[SAPP_STAT_SND_UDP]);
+
+
+
}
void sysinfo_output(void)
@@ -281,12 +299,12 @@ void sysinfo_output(void)
fprintf(fp,"Network Link Quality:\n");
fprintf(fp,"%-12s %12s %12s %12s \n","LOST_STAT", "total", "lost", "percent");
if((cur_length[SAPP_STAT_RCV_TCP] > 0) && (cur_length[SAPP_STAT_TCP_LOST_PKT] > 0)){
- fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "bytes", cur_length[SAPP_STAT_RCV_TCP], cur_length[SAPP_STAT_TCP_LOST_PKT], (double)cur_length[SAPP_STAT_TCP_LOST_PKT]/(double)cur_length[SAPP_STAT_RCV_TCP]);
+ fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "bytes", cur_length[SAPP_STAT_RCV_TCP], cur_length[SAPP_STAT_TCP_LOST_PKT], (double)cur_length[SAPP_STAT_TCP_LOST_PKT]/(double)(cur_length[SAPP_STAT_RCV_TCP]+cur_length[SAPP_STAT_TCP_LOST_PKT]));
}else{
fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "bytes", cur_length[SAPP_STAT_RCV_TCP], cur_length[SAPP_STAT_TCP_LOST_PKT], 0.0);
}
if((cur_count[SAPP_STAT_TCP_STREAM_NEW] > 0) && (cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM] > 0)){
- fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "stream", cur_count[SAPP_STAT_TCP_STREAM_NEW], cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM], (double)cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM]/(double)cur_count[SAPP_STAT_TCP_STREAM_NEW]);
+ fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "stream", cur_count[SAPP_STAT_TCP_STREAM_NEW], cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM], (double)cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM]/(double)(cur_count[SAPP_STAT_TCP_STREAM_NEW]+cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM]));
}else{
fprintf(fp,"%-12s %12llu %12llu %2.10f\n", "stream", cur_count[SAPP_STAT_TCP_STREAM_NEW], cur_count[SAPP_STAT_TCP_LOST_PKT_STREAM_NUM], 0.0);
}
diff --git a/test/test_app_sapp_tcp_lost_len.c b/test/test_app_sapp_tcp_lost_len.c
new file mode 100644
index 0000000..0e30cc5
--- /dev/null
+++ b/test/test_app_sapp_tcp_lost_len.c
@@ -0,0 +1,3340 @@
+#include "stream.h"
+#include "sapp_api.h"
+#include "sapp_private_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static int test_tcp_flow_id = -1;
+static unsigned short phony_protocol_plugid;
+
+
+#define TEST_NETWORK_FLOW 1
+#define TEST_SAPP_API 1
+
+
+char test_gtp_volatile_addr_entry(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ enum stream_carry_tunnel_t tunnel_type;
+ int opt_len = sizeof(tunnel_type);
+ char addr_list_str[1024];
+
+ if(stream_addr_list_ntop(pstream, addr_list_str, sizeof(addr_list_str)) < 0){
+ printf("stream_addr_list_ntop() error!\n");
+ return -1;
+ }
+
+ if(pstream->opstate== OP_STATE_PENDING){
+ MESA_get_stream_opt(pstream, MSO_STREAM_TUNNEL_TYPE, &tunnel_type, &opt_len);
+ if(tunnel_type != STREAM_TUNNEL_GPRS_TUNNEL){
+ return APP_STATE_DROPME;
+ }
+
+ printf("gtp layer pending: %s\n", addr_list_str);
+ }else if(pstream->opstate== OP_STATE_CLOSE){
+ printf("gtp layer close : %s\n", addr_list_str);
+ }else{
+ printf("gtp layer data : %s\n", addr_list_str);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+struct hierarchical_layer{
+ int addrtype;
+ int layer_index;
+};
+#define MAX_LAYER_DEPTH (15)
+#define MAX_LAYER_STAT_NUM (128)
+
+static int hierarchical_layer_stat_num = 0;
+static struct hierarchical_layer g_hierarchical_layer_stat[MAX_LAYER_STAT_NUM][MAX_LAYER_DEPTH];
+
+extern const char *addr_type_to_prefix(enum addr_type_t layer_type);
+
+static int hierarchical_layer_stat_cmp(const struct hierarchical_layer *layer1, const struct hierarchical_layer *layer2)
+{
+ int i;
+
+ for(i = 0; i < MAX_LAYER_DEPTH; i++){
+ if(layer1[i].addrtype != layer2[i].addrtype){
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ return value:
+ 1: bingo, found;
+ 0: not found;
+*/
+static int search_g_hierarchical_layer_stat(const struct hierarchical_layer *stream_hierarchical_layer_stat)
+{
+ int i;
+
+ for(i = 0; i < hierarchical_layer_stat_num; i++){
+ if(hierarchical_layer_stat_cmp(&g_hierarchical_layer_stat[i][0], stream_hierarchical_layer_stat) == 0){
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static void show_hierarchical_layer_stat(void)
+{
+ int i, layer_index;
+
+ for(i = 0; i < hierarchical_layer_stat_num; i++){
+ for(layer_index = 0; layer_index < MAX_LAYER_DEPTH; layer_index++){
+ if(g_hierarchical_layer_stat[i][layer_index].addrtype <= 0){
+ break;
+ }
+ printf("%s-", addr_type_to_prefix((enum addr_type_t )g_hierarchical_layer_stat[i][layer_index].addrtype));
+ }
+ printf("\b\n");
+ }
+}
+
+
+static int update_hierarchical_layer_stat(const struct hierarchical_layer *stream_hierarchical_layer_stat)
+{
+ int i;
+
+ if(search_g_hierarchical_layer_stat(stream_hierarchical_layer_stat) == 0){ //不存�? 是新的流结构
+ memcpy(&g_hierarchical_layer_stat[hierarchical_layer_stat_num], stream_hierarchical_layer_stat, sizeof(struct hierarchical_layer) * MAX_LAYER_DEPTH);
+ hierarchical_layer_stat_num++;
+ show_hierarchical_layer_stat();
+ }
+
+ return 0;
+}
+
+char hierarchical_embed_layer_entry(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct hierarchical_layer stream_hierarchical_layer_stat[MAX_LAYER_DEPTH] = {};
+ int layer_num;
+ if(0 != thread_seq){
+ printf("hierarchical_embed_layer_entry only support one thread!\n");
+ return APP_STATE_DROPME;
+ }
+
+ if(OP_STATE_CLOSE == pstream->opstate){
+ layer_num = 0;
+ while(pstream){
+ stream_hierarchical_layer_stat[layer_num].addrtype = pstream->addr.addrtype;
+ layer_num++;
+ pstream = pstream->pfather;
+ }
+
+ update_hierarchical_layer_stat(stream_hierarchical_layer_stat);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+#if TEST_SAPP_API
+char phony_biz_test(stSessionInfo* session_info, void **pme, int thread_seq,struct streaminfo *a_stream,const void *a_packet)
+{
+ printf("I am biz plug, from pro info: %s\n", session_info->buf);
+
+
+ return APP_STATE_GIVEME;
+}
+
+void phony_protocol_funstat(unsigned long long protflag)
+{
+
+}
+
+long long phony_protocol_flag_change(char* flag_str)
+{
+ return 0xFFFF;
+}
+
+void phony_protocol_get_plugid(unsigned short plugid)
+{
+ phony_protocol_plugid= plugid;
+}
+
+/* ģ�������, �������ļ�PLUGNAME=xxxʶ�� */
+char phony_protocol_test(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ stSessionInfo stinfo;
+ static void *biz_pme = NULL;
+
+ memset(&stinfo, 0, sizeof(stSessionInfo));
+
+ stinfo.plugid = phony_protocol_plugid;
+ stinfo.session_state = SESSION_STATE_PENDING;
+ stinfo.buf = (void *)"hello!\n";
+ stinfo.buflen = strlen("hello!\n");
+ stinfo.prot_flag = 0xFFFF;
+
+ printf("I am protocol plug\n");
+ PROT_PROCESS(&stinfo, &biz_pme, thread_seq, a_tcp, a_packet);
+
+ return APP_STATE_GIVEME;
+}
+
+
+char print_vxlan_info(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct vxlan_info vinfo;
+ int opt_val_len = sizeof(vinfo);
+ int ret;
+
+ if(OP_STATE_PENDING == a_tcp->opstate || OP_STATE_CLOSE == a_tcp->opstate){
+ ret = MESA_get_stream_opt(a_tcp, MSO_STREAM_VXLAN_INFO, &vinfo, &opt_val_len);
+ if(ret < 0){
+ printf("get vxlan info error!\n");
+ }else{
+ printf("OPSTATE:%d, tuple4:%s, vxlan info:\n", a_tcp->opstate, printaddr(&a_tcp->addr, thread_seq));
+ printf("\tencap_type:%d\n", vinfo.encap_type);
+ printf("\tntrance_id:%d\n", vinfo.entrance_id);
+ printf("\tdev_id:%d\n", vinfo.dev_id);
+ printf("\tlink_id:%d\n", vinfo.link_id);
+ printf("\tlink_dir:%d\n", vinfo.link_dir);
+
+ printf("\tinner_smac:%s\n", vinfo.inner_smac);
+ printf("\tinner_dmac:%s\n", vinfo.inner_dmac);
+ }
+ }
+
+ return APP_STATE_DROPME;
+}
+
+
+char print_stream_tunnel_type(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ unsigned short tunnel_type = 0;
+ int opt_val_len = sizeof(short);
+
+ MESA_get_stream_opt(a_tcp, MSO_STREAM_TUNNEL_TYPE, &tunnel_type, &opt_val_len);
+ if(tunnel_type != 0){
+ printf("stream tunnel type:%d\n", tunnel_type);
+ }
+
+ return APP_STATE_DROPME;
+}
+char test_get_this_layer_header(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)get_this_layer_header(a_tcp);
+
+ printf("iphdr:%p, ip->v=%d, ip->hl=%d, ip->len=%u\n", ip4hdr, ip4hdr->ip_v, ip4hdr->ip_hl*4, ntohs(ip4hdr->ip_len));
+
+ return APP_STATE_GIVEME;
+}
+
+static void test_get_tcp_opts_show_detail(struct tcp_option *opt_array, int optnum)
+{
+ int i;
+
+ for(i = 0; i < optnum; i++){
+ if(opt_array[i].len > 0){
+ printf("\ttype:%d, len:%d, value:%llu\n", opt_array[i].type, opt_array[i].len, opt_array[i].long_value);
+ }else{
+ printf("\ttype:%d, len:%d, no value\n", opt_array[i].type, opt_array[i].len);
+ }
+ }
+}
+
+
+char test_get_pkt_tcp_opts(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct tcp_option to[20];
+ const struct mesa_ip4_hdr *iph = (const struct mesa_ip4_hdr *)a_packet;
+ const struct mesa_tcp_hdr *tcph;
+ int ret;
+
+ if(NULL == a_packet){
+ return APP_STATE_DROPME;
+ }
+
+ if(ADDR_TYPE_IPV4 == a_tcp->addr.addrtype){
+ tcph = (const struct mesa_tcp_hdr * )((char *)a_packet + iph->ip_hl *4);
+ }else{
+ tcph = (const struct mesa_tcp_hdr * )((char *)a_packet + 40);
+ }
+
+ ret = MESA_get_tcp_pkt_opts((const struct tcphdr *)tcph, to, 20);
+ if(ret > 0){
+ printf("MESA_get_tcp_pkt_opts OK:\n");
+ test_get_tcp_opts_show_detail(to, ret);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+static void test_get_tcp_opts_show_ext_detail(struct tcp_option_ext *opt_array, int optnum)
+{
+ int i;
+
+ for(i = 0; i < optnum; i++){
+ if(opt_array[i].len > 0){
+ printf("\ttype:%d, len:%d, value:%llu\n", opt_array[i].type, opt_array[i].len, opt_array[i].long_value);
+ }else{
+ printf("\ttype:%d, len:%d, no value\n", opt_array[i].type, opt_array[i].len);
+ }
+ }
+}
+
+char test_get_pkt_tcp_opts_ext(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct tcp_option_ext to[32];
+ const struct mesa_ip4_hdr *iph = (const struct mesa_ip4_hdr *)a_packet;
+ const struct mesa_tcp_hdr *tcph;
+ int ret;
+
+ if(NULL == a_packet){
+ return APP_STATE_DROPME;
+ }
+
+ if(ADDR_TYPE_IPV4 == a_tcp->addr.addrtype){
+ tcph = (const struct mesa_tcp_hdr * )((char *)a_packet + iph->ip_hl *4);
+ }else{
+ tcph = (const struct mesa_tcp_hdr * )((char *)a_packet + 40);
+ }
+
+ ret = MESA_get_tcp_pkt_opts_ext((const struct tcphdr *)tcph, to, 32);
+ if(ret > 0){
+ printf("MESA_get_tcp_pkt_opts_ext OK:\n");
+ test_get_tcp_opts_show_ext_detail(to, ret);
+ }
+
+ return APP_STATE_GIVEME;
+}
+/* ���Ե�����ͳ�� */
+char test_tcp_uni_stream_stats(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *raw_pdetail;
+ struct tcp_flow_stat *tflow_project;
+
+ if(-1 == test_tcp_flow_id){
+ test_tcp_flow_id = project_customer_register("tcp_flow_stat", "struct");
+ if(-1 == test_tcp_flow_id){
+ printf("'tcp_flow_stat' is disable, no statistics\n");
+ }
+ }
+
+ if(OP_STATE_CLOSE == a_tcp->opstate){
+ if(DIR_DOUBLE == a_tcp->dir){
+ /* ֻ�������� */
+ return APP_STATE_DROPME;
+ }
+
+ raw_pdetail=(struct tcpdetail *)a_tcp->pdetail;
+ printf("from-detail: server pkt=%d, count=%d, client pkt=%d, count=%d\n",
+ raw_pdetail->serverpktnum, raw_pdetail->serverbytes,
+ raw_pdetail->clientpktnum, raw_pdetail->clientbytes);
+
+ if(test_tcp_flow_id != -1){
+ /* 2015-12-29 lijia add */
+ tflow_project = (struct tcp_flow_stat *)project_req_get_struct(a_tcp, test_tcp_flow_id);
+ if(tflow_project){
+ printf("from-project: server pkt=%u, count=%lu, client pkt=%u, count=%lu\n",
+ tflow_project->C2S_data_pkt,tflow_project->C2S_data_byte,
+ tflow_project->S2C_data_pkt, tflow_project->S2C_data_byte);
+ }
+ }
+
+ if((raw_pdetail->serverbytes && raw_pdetail->clientbytes) == 0){
+ printf("stream-detail: %s\n", printaddr(&a_tcp->addr, thread_seq));
+ }
+
+ if((tflow_project->C2S_data_byte && tflow_project->S2C_data_byte) == 0){
+ printf("stream-project: %s\n", printaddr(&a_tcp->addr, thread_seq));
+ }
+
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_get_stream_tcp_opts(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct tcp_option *opt_array;
+ int opt_num = 8;
+ int ret;
+
+ unsigned int isn = -1;
+ int len = sizeof(int);
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_ISN_C2S, &isn, &len);
+ if(ret >= 0){
+ printf("MESA_get_stream_opt() MSO_TCP_ISN_C2S, %u!\n", isn);
+ }else{
+ printf("MESA_get_stream_opt() MSO_TCP_ISN_C2S error!\n");
+ abort();
+ }
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_ISN_S2C, &isn, &len);
+ if(ret >= 0){
+ printf("MESA_get_stream_opt() MSO_TCP_ISN_S2C, %u!\n", isn);
+ }else{
+ printf("MESA_get_stream_opt() MSO_TCP_ISN_S2C error!\n");
+ abort();
+ }
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_SYN_OPT, &opt_array, &opt_num);
+ if(ret >= 0){
+ printf("stream:%p, SYN-OPTS:\n", a_tcp);
+ test_get_tcp_opts_show_detail(opt_array, opt_num);
+ }else{
+ printf("MESA_get_stream_opt() MSO_TCP_SYN_OPT error!\n");
+ }
+
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_SYNACK_OPT, &opt_array, &opt_num);
+ if(ret >= 0){
+ printf("stream:%p, SYNACK-OPTS:\n", a_tcp);
+ test_get_tcp_opts_show_detail(opt_array, opt_num);
+ }else{
+ printf("MESA_get_stream_opt() MSO_TCP_SYNACK_OPT error!\n");
+ }
+
+ return APP_STATE_DROPME;
+}
+
+
+char test_set_stream_timeout(struct streaminfo *pstream, void **pme, int thread_seq,void *a_packet)
+{
+ int ret;
+ unsigned short tout_val;
+ unsigned char close_reason;
+ int opt_len;
+
+ if(pstream->opstate== OP_STATE_PENDING){
+ /*
+ for test, port 11111=timeout=11s, port 22222=timeout=22s,
+ ������nc����3��udp����, �˿ڷֱ�Ϊ11111, 22222, 33333,
+ ��11s֮��, 11111Ӧ�ý���,
+ 22s֮��, 22222Ӧ�ý���,
+ 33333����Ĭ��ȫ�ֳ�ʱ��̭ʱ��, �������ȫ�ֳ�ʱ��̭, Ӧ�ò������(dumpfileģʽ����).
+ */
+ if((pstream->addr.tuple4_v4->source == ntohs(11111))
+ || (pstream->addr.tuple4_v4->dest == ntohs(11111))){
+ tout_val = 11;
+ ret = MESA_set_stream_opt(pstream, MSO_TIMEOUT, &tout_val, sizeof(short));
+ if(ret < 0){
+ printf("stream:%p, MESA_set_stream_opt error:\n", pstream);
+ return APP_STATE_DROPME;
+ }
+ }
+
+ if((pstream->addr.tuple4_v4->source == ntohs(22222))
+ || (pstream->addr.tuple4_v4->dest == ntohs(22222))){
+ tout_val = 22;
+ ret = MESA_set_stream_opt(pstream, MSO_TIMEOUT, &tout_val, sizeof(short));
+ if(ret < 0){
+ printf("stream:%p, MESA_set_stream_opt error:\n", pstream);
+ return APP_STATE_DROPME;
+ }
+ }
+ }
+
+ if(pstream->opstate== OP_STATE_CLOSE){
+ opt_len = sizeof(char);
+ ret = MESA_get_stream_opt(pstream, MSO_STREAM_CLOSE_REASON, &close_reason, &opt_len);
+ if(ret >= 0){
+ printf("stream: %p %s closed, reason: %d!\n", pstream, printaddr(&pstream->addr, thread_seq), close_reason);
+ }else{
+ printf("stream: %p %s closed!\n", pstream, printaddr(&pstream->addr, thread_seq));
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_sapp_get_platform_opt(struct streaminfo *pstream, void **pme, int thread_seq,void *a_packet)
+{
+ unsigned long long totpkt, totbyte, rand_num;
+ unsigned long long totpkt_in, totpkt_out;
+ int opt_len;
+ char time_str[32];
+
+ opt_len = sizeof(long long);
+ sapp_get_platform_opt(SPO_TOTAL_RCV_PKT, &totpkt, &opt_len);
+
+ sapp_get_platform_opt(SPO_TOTAL_RCV_BYTE, &totbyte, &opt_len);
+
+ opt_len = 32;
+ sapp_get_platform_opt(SPO_CURTIME_STRING, time_str, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_RAND_NUMBER, &rand_num, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_INBOUND_PKT, &totpkt_in, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_OUTBOUND_PKT, &totpkt_out, &opt_len);
+
+
+ printf("tot recv pkt by sapp_get_platform_opt is:%llu\n", totpkt);
+
+ printf("tot recv byte by sapp_get_platform_opt is:%llu\n", totbyte);
+
+ printf("curtime-str by sapp_get_platform_opt is:%s\n", time_str);
+
+ printf("randnum by sapp_get_platform_opt is:%llu\n", rand_num);
+
+ printf("tot recv inbound pkt by sapp_get_platform_opt is:%llu\n", totpkt_in);
+ printf("tot recv outbound pkt by sapp_get_platform_opt is:%llu\n", totpkt_out);
+
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_get_stream_in_out_bound(struct streaminfo *pstream, void **pme, int thread_seq,void *a_packet)
+{
+ int ret;
+ unsigned long long inound_stat[2];
+ unsigned long long outound_stat[2];
+ int opt_len;
+
+
+
+ if(pstream->opstate== OP_STATE_CLOSE){
+ opt_len = sizeof(long long);
+ ret = MESA_get_stream_opt(pstream, MSO_TOTAL_INBOUND_PKT, &inound_stat[0], &opt_len);
+ assert(ret >= 0);
+
+ opt_len = sizeof(long long);
+ ret = MESA_get_stream_opt(pstream, MSO_TOTAL_INBOUND_BYTE, &inound_stat[1], &opt_len);
+ assert(ret >= 0);
+
+ opt_len = sizeof(long long);
+ ret = MESA_get_stream_opt(pstream, MSO_TOTAL_OUTBOUND_PKT, &outound_stat[0], &opt_len);
+ assert(ret >= 0);
+
+ opt_len = sizeof(long long);
+ ret = MESA_get_stream_opt(pstream, MSO_TOTAL_OUTBOUND_BYTE, &outound_stat[1], &opt_len);
+ assert(ret >= 0);
+
+ printf("stream: %s, inbound: %llu, %llu, outbound: %llu, %llu\n", printaddr(&pstream->addr, thread_seq),
+ inound_stat[0], inound_stat[1], outound_stat[0], outound_stat[1]);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_stream_with_platform_in_out_traffic(struct streaminfo *pstream, void **pme, int thread_seq,void *a_packet)
+{
+ unsigned long long stream_totpkt_in = 0, stream_totpkt_out = 0, stream_totbyte_in = 0, stream_totbyte_out = 0;
+ unsigned long long platform_totpkt_in = 0, platform_totpkt_out = 0, platform_totbyte_in = 0, platform_totbyte_out = 0;
+
+ int opt_len;
+
+ if(pstream->opstate== OP_STATE_CLOSE){
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_INBOUND_PKT, &platform_totpkt_in, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_OUTBOUND_PKT, &platform_totpkt_out, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_INBOUND_BYTE, &platform_totbyte_in, &opt_len);
+
+ opt_len = sizeof(long long );
+ sapp_get_platform_opt(SPO_TOTAL_OUTBOUND_BYTE, &platform_totbyte_out, &opt_len);
+
+
+
+ opt_len = sizeof(long long);
+ MESA_get_stream_opt(pstream, MSO_TOTAL_INBOUND_PKT, &stream_totpkt_in, &opt_len);
+
+ opt_len = sizeof(long long);
+ //MESA_get_stream_opt(pstream, MSO_TOTAL_INBOUND_BYTE, &stream_totbyte_in, &opt_len);
+ MESA_get_stream_opt(pstream, MSO_TOTAL_INBOUND_BYTE_RAW, &stream_totbyte_in, &opt_len);
+
+ opt_len = sizeof(long long);
+ MESA_get_stream_opt(pstream, MSO_TOTAL_OUTBOUND_PKT, &stream_totpkt_out, &opt_len);
+
+ opt_len = sizeof(long long);
+ //MESA_get_stream_opt(pstream, MSO_TOTAL_OUTBOUND_BYTE, &stream_totbyte_out, &opt_len);
+ MESA_get_stream_opt(pstream, MSO_TOTAL_OUTBOUND_BYTE_RAW, &stream_totbyte_out, &opt_len);
+
+ printf("stream : pkt_in:%llu, pkt_out:%llu, byte_in:%llu, byte_out:%llu\n", stream_totpkt_in, stream_totpkt_out, stream_totbyte_in, stream_totbyte_out);
+ printf("platform: pkt_in:%llu, pkt_out:%llu, byte_in:%llu, byte_out:%llu\n", platform_totpkt_in, platform_totpkt_out, platform_totbyte_in, platform_totbyte_out);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+int test_sapp_get_device_opt(const char *device)
+{
+ int ret;
+ unsigned char dev_mac[6];
+ unsigned int dev_ipaddr;
+ int dev_mtu;
+ int opt_len;
+
+ opt_len = 6;
+ ret = sapp_get_device_opt(device, SDO_MAC_ADDR, dev_mac, &opt_len);
+ if(ret < 0){
+ printf("sapp_get_device_opt->%s : SDO_MAC_ADDR error!\n ", device);
+ }else{
+ printf("sapp_get_device_opt->%s : SDO_MAC_ADDR: %02x, %02x, %02x, %02x, %02x, %02x\n", device, dev_mac[0],dev_mac[1],dev_mac[2],dev_mac[3],dev_mac[4],dev_mac[5]);
+ }
+
+ opt_len = 4;
+ ret = sapp_get_device_opt(device, SDO_IPV4_ADDR, &dev_ipaddr, &opt_len);
+ if(ret < 0){
+ printf("sapp_get_device_opt->%s : SDO_IPV4_ADDR error!\n ",device);
+ }else{
+ char ipstr[16];
+ inet_ntop(AF_INET, &dev_ipaddr, ipstr,16);
+ printf("sapp_get_device_opt->%s : SDO_IPV4_ADDR: %s\n", device, ipstr);
+ }
+ opt_len = 4;
+ ret = sapp_get_device_opt(device, SDO_MTU, &dev_mtu, &opt_len);
+ if(ret < 0){
+ printf("sapp_get_device_opt->%s : SDO_MTU error!\n ", device);
+ }else{
+ printf("sapp_get_device_opt->%s : SDO_MTU: %d\n", device, dev_mtu);
+ }
+}
+
+#endif
+
+
+#if TEST_NETWORK_FLOW
+static int check_ipv4_hdr(const struct mesa_ip4_hdr * iph)
+{
+ int tot_len = ntohs(iph->ip_len);
+
+ if (tot_len < (int)sizeof(struct mesa_ip4_hdr)
+ || iph->ip_hl < 5
+ || iph->ip_v != 4
+ || tot_len < iph->ip_hl << 2){
+ return -1;
+ }
+
+ switch(iph->ip_p){
+ case IPPROTO_IPIP:
+ case IPPROTO_ICMP:
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_IPV6:
+ case IPPROTO_GRE:
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+char testIPFragApp_1(struct streaminfo *pstream,unsigned char routedir, int thread_seq,void *a_packet)
+{
+ static int testcount;
+ printf("ip_frag_entry test %d\n",testcount++);
+ return APP_STATE_GIVEME;
+}
+
+char ipv4_pkt_detail_entry(struct streaminfo *pstream,unsigned char routedir, int thread_seq,void *a_packet)
+{
+ char ip_src_str[INET6_ADDRSTRLEN];
+ char ip_dst_str[INET6_ADDRSTRLEN];
+ struct mesa_ip4_hdr *ihdr4 = (struct mesa_ip4_hdr *)a_packet;
+ struct mesa_tcp_hdr *thdr;
+ struct mesa_udp_hdr *uhdr;
+ if(NULL == a_packet){
+ return APP_STATE_GIVEME;
+ }
+
+ inet_ntop(AF_INET, &ihdr4->ip_src.s_addr, ip_src_str, sizeof(ip_src_str));
+ inet_ntop(AF_INET, &ihdr4->ip_dst.s_addr, ip_dst_str, sizeof(ip_dst_str));
+
+ if(IPPROTO_TCP == ihdr4->ip_p){
+ thdr = (struct mesa_tcp_hdr *)((char *)ihdr4 + ihdr4->ip_hl * 4);
+ printf("IP pkt: %s:%u --> %s:%u, ipid:%u, proto:%d\n",
+ ip_src_str, ntohs(thdr->th_sport),
+ ip_dst_str, ntohs(thdr->th_dport),
+ ntohs(ihdr4->ip_id), ihdr4->ip_p);
+ }else if(IPPROTO_UDP == ihdr4->ip_p){
+ uhdr = (struct mesa_udp_hdr *)((char *)ihdr4 + ihdr4->ip_hl * 4);
+ printf("IP pkt: %s:%u --> %s:%u, ipid:%u, proto:%d\n",
+ ip_src_str, ntohs(uhdr->uh_sport),
+ ip_dst_str, ntohs(uhdr->uh_dport),
+ ntohs(ihdr4->ip_id), ihdr4->ip_p);
+ }else{
+ printf("IP pkt: %s --> %s, ipid:%u, proto:%d\n", ip_src_str, ip_dst_str, ntohs(ihdr4->ip_id), ihdr4->ip_p);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+
+char testIPApp_1(struct streaminfo *pstream,unsigned char routedir, int thread_seq,void *a_packet)
+{
+ static int testcount;
+ printf("ip_entry test %d\n",testcount++);
+ return APP_STATE_GIVEME;
+}
+
+char testIPv6App_1(struct streaminfo *pstream,unsigned char routedir, int thread_seq,void *a_packet)
+{
+ static int testcount;
+ printf("ip_v6 test %d\n",testcount++);
+ return APP_STATE_GIVEME;
+}
+
+static unsigned long long test_get_stream_id(struct streaminfo *a_stream)
+{
+ int ret = 0;
+ int device_id_size = sizeof(unsigned long long);
+ unsigned long long device_id = 0;
+
+ ret = MESA_get_stream_opt(a_stream, MSO_GLOBAL_STREAM_ID, (void *)&device_id, &device_id_size);
+ if (ret == 0)
+ {
+ return device_id;
+ }
+
+ return -1;
+}
+static int test_udp_flow_id = -1;
+char testudpApp_1(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct udpdetail *pdetail=(struct udpdetail *)pstream->pdetail;
+ struct udp_flow_stat *plug_stat;
+ char no_use[65536];
+
+ if(-1 == test_udp_flow_id){
+ test_udp_flow_id = project_customer_register(PROJECT_REQ_UDP_FLOW, "struct");
+ if(-1 == test_udp_flow_id){
+ printf("'udp_flow_stat' is disable, no statistics\n");
+ }
+ }
+
+ if(pstream->opstate== OP_STATE_PENDING)
+ {
+test_set_stream_timeout(pstream, pme, thread_seq, a_packet);
+ plug_stat = (struct udp_flow_stat *)malloc(sizeof(struct udp_flow_stat));
+ memset(plug_stat, 0, sizeof(struct udp_flow_stat));
+ *pme=plug_stat;
+ }
+
+ plug_stat = (struct udp_flow_stat *)(*pme);
+
+ if(pdetail->datalen > 0){
+ if(DIR_C2S == pstream->curdir){
+ plug_stat->C2S_byte += pdetail->datalen;
+ plug_stat->C2S_pkt++;
+ }else{
+ plug_stat->S2C_byte += pdetail->datalen;
+ plug_stat->S2C_pkt++;
+ }
+ memcpy(no_use, pdetail->pdata, pdetail->datalen);
+ }
+
+ if(pstream->opstate==OP_STATE_CLOSE)
+ {
+ if(pdetail != NULL){
+ printf("%20s: %s, %llu, ", "UdpallstreaM-inter", printaddr(&(pstream->addr), pstream->threadnum), test_get_stream_id(pstream));
+ printf("server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, datalen=%u, ",
+ pdetail->serverpktnum, pdetail->serverbytes,
+ pdetail->clientpktnum,pdetail->clientbytes, pdetail->datalen);
+ printf("total-pkt=%d, ", pdetail->serverpktnum + pdetail->clientpktnum);
+ printf("total-count=%u\n", pdetail->serverbytes + pdetail->clientbytes);
+ }
+
+ printf("%20s: %s, ", "udpallstream-plug", printaddr(&(pstream->addr), pstream->threadnum));
+ printf("server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, datalen=%u, ",
+ plug_stat->C2S_pkt,plug_stat->C2S_byte,
+ plug_stat->S2C_pkt,plug_stat->S2C_byte, pdetail->datalen);
+ printf("total-pkt=%d, ", plug_stat->C2S_pkt + plug_stat->S2C_pkt);
+ printf("total-count=%u\n", plug_stat->C2S_byte+plug_stat->S2C_byte);
+ free(*pme);
+
+ struct udp_flow_stat *flow_project = (struct udp_flow_stat *)project_req_get_struct(pstream, test_udp_flow_id);
+ if(flow_project != NULL){
+ printf("%20s: %s, ", "UdpallstreaM-project", printaddr(&(pstream->addr), pstream->threadnum));
+ printf("server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, datalen=%u, ",
+ flow_project->C2S_pkt,flow_project->C2S_byte,
+ flow_project->S2C_pkt,flow_project->S2C_byte, pdetail->datalen);
+ printf("total-pkt=%d, ", flow_project->C2S_pkt + flow_project->S2C_pkt);
+ printf("total-count=%u\n", flow_project->C2S_byte+flow_project->S2C_byte);
+ }
+ }
+ return APP_STATE_GIVEME;
+
+}
+
+char testudpApp_2(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct udpdetail *pdetail=(struct udpdetail *)pstream->pdetail;
+ if(pdetail->clientpktnum >10)
+ return APP_STATE_DROPME;
+ else
+ return APP_STATE_GIVEME;
+
+}
+
+char testtcpApp_1(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *pdetail=(struct tcpdetail *)pstream->pdetail;
+
+ if(pdetail->clientpktnum >3)
+ return APP_STATE_DROPME;
+ else
+ return APP_STATE_GIVEME;
+}
+
+char tcp_data_dump(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ char sip_str[20], dip_str[20];
+ char file_name[128];
+ if(pstream->opstate== OP_STATE_PENDING){
+ inet_ntop(AF_INET, &pstream->addr.tuple4_v4->saddr, sip_str, 20);
+ inet_ntop(AF_INET, &pstream->addr.tuple4_v4->daddr, dip_str, 20);
+ snprintf(file_name, 128, "%s_%u_%s_%u.T%ld.dump",
+ sip_str, ntohs(pstream->addr.tuple4_v4->source),
+ dip_str, ntohs(pstream->addr.tuple4_v4->dest),
+ (long)time(NULL));
+ *pme = malloc(sizeof(void *));
+ *pme = fopen(file_name, "w+");
+ }
+
+ if(NULL == *pme){
+ assert(0);
+ }
+ if(pstream->ptcpdetail->datalen > 0){
+ fwrite(pstream->ptcpdetail->pdata, pstream->ptcpdetail->datalen, 1, (FILE *)(*pme));
+ }
+
+ if(pstream->opstate== OP_STATE_CLOSE){
+ fclose((FILE *)(*pme));
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_print_mac(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+
+ if(pstream->opstate== OP_STATE_PENDING)
+ {
+ printf("tcpstream: %s, ",printaddr(&(pstream->addr), pstream->threadnum));
+ while(pstream){
+ if(pstream->addr.addrtype == ADDR_TYPE_MAC){
+ struct layer_addr_mac *mac_addr = (struct layer_addr_mac *)pstream->addr.mac;
+ printf("smac: %02x-%02x-%02x-%02x-%02x-%02x, dmac: %02x-%02x-%02x-%02x-%02x-%02x\n",
+ mac_addr->src_addr.h_source[0], mac_addr->src_addr.h_source[1], mac_addr->src_addr.h_source[2],
+ mac_addr->src_addr.h_source[3], mac_addr->src_addr.h_source[4], mac_addr->src_addr.h_source[5],
+ mac_addr->src_addr.h_dest[0], mac_addr->src_addr.h_dest[1], mac_addr->src_addr.h_dest[2],
+ mac_addr->src_addr.h_dest[3], mac_addr->src_addr.h_dest[4], mac_addr->src_addr.h_dest[5]);
+ break;
+ }else{
+ pstream = pstream->pfather;
+ }
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+static void sapp_timer_test_cbfun(sapp_timer_handle h, sapp_timer_event ev, int pkt_process_thread_id, void *user_arg)
+{
+ struct streaminfo *pstream = (struct streaminfo *)user_arg;
+ struct timeval curt;
+
+ gettimeofday(&curt, NULL);
+
+ printf("tid:%d, tcpstream %s timeout: %ld.%ld \n",
+ pstream->threadnum,
+ printaddr(&(pstream->addr),pstream->threadnum),
+ curt.tv_sec, curt.tv_usec);
+}
+
+
+
+static void *sapp_timer_ev_new(int tid, void *arg)
+{
+ sapp_timer_handle th;
+ sapp_timer_event tev;
+ int iopt, ret;
+ struct timeval topt;
+
+ th = sapp_get_platform_timer(tid);
+ assert(th);
+ tev = sapp_timer_event_new(th);
+ assert(tev);
+
+ iopt = tid;
+ sapp_event_set_opt(tev, STEO_EFFECTIVE_THREAD_ID, &iopt, sizeof(iopt));
+
+ topt.tv_sec = 1;
+ topt.tv_usec = 0;
+ sapp_event_set_opt(tev, STEO_TIMEOUT_VAL, &topt, sizeof(topt));
+ sapp_event_set_opt(tev, STEO_CALLBACK_FUN, (void *)&sapp_timer_test_cbfun, sizeof(void *));
+ sapp_event_set_opt(tev, STEO_CALLBACK_FUN_ARG, arg, sizeof(void *));
+
+ ret = sapp_timer_add(th, tev);
+ assert(ret >= 0);
+
+ return tev;
+}
+
+char on_tcp_sapp_timer_test(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ sapp_timer_handle th;
+ sapp_timer_event tev;
+
+ if(pstream->opstate== OP_STATE_PENDING){
+ tev = sapp_timer_ev_new(pstream->threadnum, pstream);
+ *pme = tev;
+ }else{
+ tev = *pme;
+
+ if(pstream->opstate== OP_STATE_CLOSE){
+ th = sapp_get_platform_timer(pstream->threadnum);
+ sapp_timer_del(th, tev);
+ printf("tid:%d, tcpstream close: %s, del timer\n",pstream->threadnum, printaddr(&(pstream->addr),pstream->threadnum));
+ return APP_STATE_DROPME;
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char record_tcp_lost_len(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *raw_pdetail=(struct tcpdetail *)pstream->pdetail;
+ struct tcp_flow_stat *plug_stat;
+
+ if(pstream->opstate== OP_STATE_PENDING)
+ {
+ plug_stat = (struct tcp_flow_stat *)calloc(1, sizeof(struct tcp_flow_stat));
+ *pme = plug_stat;
+ }
+ plug_stat = (struct tcp_flow_stat *)(*pme);
+
+ if(raw_pdetail->lostlen > 0){
+ if(DIR_C2S == pstream->curdir){
+ plug_stat->C2S_all_byte_raw += raw_pdetail->lostlen; /* �Ƚ���C2S_all_byte_raw�����洢�ۼƶ����� */
+ }else{
+ plug_stat->S2C_all_byte_raw += raw_pdetail->lostlen; /* �Ƚ���C2S_all_byte_raw�����洢�ۼƶ����� */
+ }
+ }
+
+ if(pstream->opstate== OP_STATE_CLOSE)
+ {
+ if((int)plug_stat->C2S_all_byte_raw < 0
+ || (int)plug_stat->S2C_all_byte_raw < 0){
+ printf("FATAL: stream:%s, server pkt=%d, count=%u, client pkt=%d, count=%u, C2S lostlen:%llu, S2C lostlen:%llu\n",
+ printaddr(&(pstream->addr), pstream->threadnum),
+ raw_pdetail->serverpktnum, raw_pdetail->serverbytes,
+ raw_pdetail->clientpktnum, raw_pdetail->clientbytes,
+ plug_stat->C2S_all_byte_raw,
+ plug_stat->S2C_all_byte_raw);
+ }
+
+ if(plug_stat->C2S_all_byte_raw > raw_pdetail->serverbytes
+ || plug_stat->S2C_all_byte_raw > raw_pdetail->clientbytes){
+ printf("INFO: stream:%s, server pkt=%d, count=%u, client pkt=%d, count=%u, C2S lostlen:%llu, S2C lostlen:%llu\n",
+ printaddr(&(pstream->addr), pstream->threadnum),
+ raw_pdetail->serverpktnum, raw_pdetail->serverbytes,
+ raw_pdetail->clientpktnum, raw_pdetail->clientbytes,
+ plug_stat->C2S_all_byte_raw,
+ plug_stat->S2C_all_byte_raw);
+ }else{
+ printf("DEBUG: stream:%s, server pkt=%d, count=%u, client pkt=%d, count=%u, C2S lostlen:%llu, S2C lostlen:%llu\n",
+ printaddr(&(pstream->addr), pstream->threadnum),
+ raw_pdetail->serverpktnum, raw_pdetail->serverbytes,
+ raw_pdetail->clientpktnum, raw_pdetail->clientbytes,
+ plug_stat->C2S_all_byte_raw,
+ plug_stat->S2C_all_byte_raw);
+
+ }
+ free(plug_stat);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char testtcpApp_2(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *raw_pdetail=(struct tcpdetail *)pstream->pdetail;
+ struct tcp_flow_stat *plug_stat;
+ char addr_str_buf[1024];
+
+ if(-1 == test_tcp_flow_id){
+ test_tcp_flow_id = project_customer_register("tcp_flow_stat", "struct");
+ if(-1 == test_tcp_flow_id){
+ printf("'tcp_flow_stat' is disable, no statistics\n");
+ }
+ }
+
+ if(pstream->opstate== OP_STATE_PENDING)
+ {
+ test_set_stream_timeout(pstream, pme, thread_seq, a_packet);
+ plug_stat = (struct tcp_flow_stat *)calloc(1, sizeof(struct tcp_flow_stat));
+ *pme = plug_stat;
+ }
+ plug_stat = (struct tcp_flow_stat *)(*pme);
+
+ if(raw_pdetail->datalen > 0){
+ if(DIR_C2S == pstream->curdir){
+ plug_stat->C2S_data_byte += raw_pdetail->datalen;
+ plug_stat->C2S_data_pkt++;
+ }else{
+ plug_stat->S2C_data_byte += raw_pdetail->datalen;
+ plug_stat->S2C_data_pkt++;
+ }
+ }
+
+ if(pstream->opstate== OP_STATE_CLOSE)
+ {
+ printf("%17s: %s, ","tcpstream-plug", printaddr(&(pstream->addr), pstream->threadnum));
+ //printf("%17s: %s, ","tcpstream-plug", printaddr_r(&(pstream->addr), addr_str_buf, 1024));
+ printf("opstate=%d, server pkt=%d, count=%d, client pkt=%d, count=%d\n",
+ pstream->opstate,
+ raw_pdetail->serverpktnum, raw_pdetail->serverbytes,
+ raw_pdetail->clientpktnum, raw_pdetail->clientbytes);
+ free(plug_stat);
+
+ /* 2015-12-29 lijia add */
+ struct tcp_flow_stat *tflow_inter = ((struct tcpdetail_private *)pstream->pdetail)->flow_stat;
+ if(tflow_inter){
+ printf("%17s: %s, %llu,", "TcpstreaM-inter", printaddr(&(pstream->addr), pstream->threadnum), test_get_stream_id(pstream));
+ printf("opstate=%d, server pkt=%u, count=%lu, client pkt=%u, count=%lu\n",
+ pstream->opstate,
+ tflow_inter->C2S_data_pkt,tflow_inter->C2S_data_byte,
+ tflow_inter->S2C_data_pkt, tflow_inter->S2C_data_byte);
+ }
+
+ if(test_tcp_flow_id != -1){
+ /* 2015-12-29 lijia add */
+ struct tcp_flow_stat *tflow_project = (struct tcp_flow_stat *)project_req_get_struct(pstream, test_tcp_flow_id);
+ if(tflow_project){
+ printf("%17s: %s, ", "TcpstreaM-project", printaddr(&(pstream->addr), pstream->threadnum));
+ printf("opstate=%d, server pkt=%u, count=%lu, client pkt=%u, count=%lu\n",
+ pstream->opstate,
+ tflow_project->C2S_data_pkt,tflow_project->C2S_data_byte,
+ tflow_project->S2C_data_pkt, tflow_project->S2C_data_byte);
+ }
+ }
+ }
+ return APP_STATE_GIVEME;
+}
+
+
+/* 关于网络相关字段, 均为网络�? network order */
+struct __inline_vxlan_hdr{
+ unsigned char flags;
+
+ /*------------byte delim -------*/
+#if 0
+ unsigned char reserved[3];
+#else
+ unsigned char nat_type; /* 复用�?个保留字�? 表示NAT类型 */
+ unsigned char reserved[2];
+#endif
+ /*--------int delim -------*/
+ unsigned char vlan_id_half_high;
+ unsigned char link_layer_type : 4; /* 二层报文封装格式 */
+ unsigned char vlan_id_half_low : 4;
+ unsigned int dir : 1;
+ unsigned int link_id : 6;
+ unsigned int online_test : 1;
+
+ unsigned int r7 : 1;
+ unsigned int r6 : 1;
+ unsigned int r5 : 1;
+ unsigned int r4 : 1;
+ unsigned int vni_flag : 1;
+ unsigned int r2 : 1;
+ unsigned int r1 : 1;
+ unsigned int r0 : 1;
+}__attribute__((packed));
+typedef struct __inline_vxlan_hdr test_inline_vxlan_hdr_t;
+
+
+char tcpentry_vlink_info(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+#if IOMODE_MARSIO
+ int ret;
+ char link_dir;
+ long long vlink_id;
+ const struct ip *ihdr;
+ char srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN];
+ const struct mesa_ethernet_hdr *ehdr;
+ unsigned char inline_dev_mac[6], local_dev_mac[6];
+ unsigned int inline_dev_ip, local_dev_ip;
+
+ if(pstream->opstate== OP_STATE_PENDING)
+ {
+ if(ADDR_TYPE_IPV4 != pstream->addr.addrtype){
+ return APP_STATE_DROPME;
+ }
+ ret = get_rawpkt_opt_from_streaminfo(pstream, RAW_PKT_GET_VXLAN_LINK_DIR, &link_dir);
+ if(ret < 0){
+ printf("tcpentry_vlink_info(): get_rawpkt_opt_from_streaminfo of RAW_PKT_GET_VXLAN_LINK_DIR error!\n");
+ return APP_STATE_DROPME;
+ }
+ ret = get_rawpkt_opt_from_streaminfo(pstream, RAW_PKT_GET_VIRTUAL_LINK_ID, &vlink_id);
+ if(ret < 0){
+ printf("tcpentry_vlink_info(): get_rawpkt_opt_from_streaminfo of RAW_PKT_GET_VIRTUAL_LINK_ID error!\n");
+ return APP_STATE_DROPME;
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(pstream, RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC, inline_dev_mac);
+ if(ret < 0){
+ printf("tcpentry_vlink_info(): get_rawpkt_opt_from_streaminfo of RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC error!\n");
+ return APP_STATE_DROPME;
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(pstream, RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, local_dev_mac);
+ if(ret < 0){
+ printf("tcpentry_vlink_info(): get_rawpkt_opt_from_streaminfo of RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC error!\n");
+ return APP_STATE_DROPME;
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(pstream, RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, local_dev_mac);
+ if(ret < 0){
+ printf("tcpentry_vlink_info(): get_rawpkt_opt_from_streaminfo of RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC error!\n");
+ return APP_STATE_DROPME;
+ }
+
+
+ ihdr = (struct ip *)a_packet;
+ inet_ntop(AF_INET, &ihdr->ip_src.s_addr, srcstr, sizeof(srcstr));
+ inet_ntop(AF_INET, &ihdr->ip_dst.s_addr, dststr, sizeof(dststr));
+
+ ehdr = (struct mesa_ethernet_hdr *)((char *)a_packet - 14);
+
+ printf("--------------------------------------------link info-----------------------------------------\n");
+ printf("outer mac:%02x-%02x-%02x-%02x-%02x-%02x -> %02x-%02x-%02x-%02x-%02x-%02x\n",
+ inline_dev_mac[0], inline_dev_mac[1],inline_dev_mac[2],inline_dev_mac[3],inline_dev_mac[4],inline_dev_mac[5],
+ local_dev_mac[0],local_dev_mac[1],local_dev_mac[2],local_dev_mac[3],local_dev_mac[4],local_dev_mac[5]);
+
+ printf("inner mac:%02x-%02x-%02x-%02x-%02x-%02x -> %02x-%02x-%02x-%02x-%02x-%02x\n",
+ ehdr->ether_shost[0], ehdr->ether_shost[1], ehdr->ether_shost[2], ehdr->ether_shost[3], ehdr->ether_shost[4], ehdr->ether_shost[5],
+ ehdr->ether_dhost[0],ehdr->ether_dhost[1],ehdr->ether_dhost[2],ehdr->ether_dhost[3],ehdr->ether_dhost[4],ehdr->ether_dhost[5]);
+ printf("inner ip: %s->%s\n", srcstr, dststr);
+ printf("link_dir:%d, mrzcpd_vlink_id:%lld\n", link_dir, vlink_id);
+
+ printf("--------------------------------------------------------------------------------------------\n");
+
+ }
+#else
+ printf("tcpentry_vlink_info(): not compile in marsio mode, do nothing!\n");
+#endif
+ return APP_STATE_DROPME;
+}
+
+
+static int test_tcpall_flow_id = -1;
+
+char testtcpApp_allpkt(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *pdetail=(struct tcpdetail *)pstream->pdetail;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
+ struct tcp_flow_stat *tcpallflow;
+
+ if(-1 == test_tcpall_flow_id){
+ test_tcpall_flow_id = project_customer_register("tcp_flow_stat", "struct");
+ if(-1 == test_tcpall_flow_id){
+ printf("'tcp_flow_stat' is disable, no statistics\n");
+ }
+ }
+
+ if(pstream->pktstate== OP_STATE_PENDING)
+ {
+ *pme=(void *)malloc(sizeof(struct tcp_flow_stat));
+ tcpallflow= (struct tcp_flow_stat *)*pme;
+ memset(tcpallflow, 0, sizeof(struct tcp_flow_stat));
+ }
+
+ tcpallflow= (struct tcp_flow_stat *)*pme;
+
+ if(a_packet != NULL){
+ if(DIR_C2S == pstream->curdir){
+ tcpallflow->C2S_all_byte += pdetail->datalen;
+ tcpallflow->C2S_all_pkt++;
+ }else{
+ tcpallflow->S2C_all_byte += pdetail->datalen;
+ tcpallflow->S2C_all_pkt++;
+ }
+ }
+
+ if(pstream->pktstate== OP_STATE_CLOSE)
+ {
+ printf("%20s: %s, ", "tcpallstream-plug", printaddr(&(pstream->addr), pstream->threadnum));
+ //printf("index=%d,state=%d ",*(int*)((char *)(pstream)-8),*(char *)((char *)(pstream)-4));
+ printf("out:%d, pktstate=%d, opstate=%d, server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, ",
+ pdetail_pr->link_state,pstream->pktstate,pstream->opstate,
+ tcpallflow->C2S_all_pkt, tcpallflow->C2S_all_byte,
+ tcpallflow->S2C_all_pkt, tcpallflow->S2C_all_byte);
+ printf("total-pkt=%u, ", tcpallflow->C2S_all_pkt + tcpallflow->S2C_all_pkt);
+ printf("total-count=%lu\n", tcpallflow->C2S_all_byte + tcpallflow->S2C_all_byte);
+ free(*pme);
+
+ /* 2015-12-29 lijia add */
+ struct tcp_flow_stat *tflow_inter = pdetail_pr->flow_stat;
+ if(tflow_inter){
+ printf("%20s: %s, %llu", "TcpallstreaM-inter", printaddr(&(pstream->addr), pstream->threadnum), test_get_stream_id(pstream));
+ printf("out:%d, pktstate=%d, opstate=%d, server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, ",
+ pdetail_pr->link_state,pstream->pktstate,pstream->opstate,
+ tflow_inter->C2S_all_pkt,tflow_inter->C2S_all_byte,
+ tflow_inter->S2C_all_pkt, tflow_inter->S2C_all_byte);
+ printf("total-pkt=%u, ", tflow_inter->C2S_all_pkt + tflow_inter->S2C_all_pkt);
+ printf("total-count=%lu\n", tflow_inter->C2S_all_byte + tflow_inter->S2C_all_byte);
+ }
+
+
+ if(-1 != test_tcpall_flow_id){
+ /* 2015-12-29 lijia add */
+ struct tcp_flow_stat *tflow_project = (struct tcp_flow_stat *)project_req_get_struct(pstream, test_tcpall_flow_id);
+ if(tflow_project){
+ printf("%20s: %s, ", "TcpallstreaM-project", printaddr(&(pstream->addr), pstream->threadnum));
+ printf("out:%d, pktstate=%d, opstate=%d, server-pkt=%u, server-count=%lu, client-pkt=%u, client-count=%lu, ",
+ pdetail_pr->link_state,pstream->pktstate,pstream->opstate,
+ tflow_project->C2S_all_pkt,tflow_project->C2S_all_byte,
+ tflow_project->S2C_all_pkt, tflow_project->S2C_all_byte);
+ printf("total-pkt=%u, ", tflow_project->C2S_all_pkt + tflow_project->S2C_all_pkt);
+ printf("total-count=%lu\n", tflow_project->C2S_all_byte + tflow_project->S2C_all_byte);
+ }
+ }
+ }
+ return APP_STATE_GIVEME;
+}
+
+char tcpall_valid_after_kill(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ unsigned char mopt = 1;
+
+ MESA_kill_tcp(pstream, a_packet);
+
+ if(pstream->pktstate== OP_STATE_PENDING){
+ if(MESA_set_stream_opt(pstream, MSO_TCPALL_VALID_AFTER_KILL, &mopt, sizeof(mopt)) < 0){
+ abort();
+ }
+ }
+
+ return testtcpApp_allpkt(pstream, pme, thread_seq, a_packet);
+}
+
+struct stream_static
+{
+ int pktnum;
+ int iplen;
+ int payloadlen;
+};
+
+char test_allpkt_v4_len(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet,char checklen)
+{
+ struct tcpdetail *pdetail=(struct tcpdetail *)pstream->pdetail;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
+ struct ip *this_iphdr =(struct ip *) a_packet;
+ struct tcphdr *this_tcphdr =NULL;
+ struct udphdr *udph =NULL;
+ int datalen, iplen;
+ struct stream_static *p=NULL;
+ char type=pstream->type;
+ char opstate;
+ int isprint=1;
+
+ if(a_packet && (check_ipv4_hdr((const struct mesa_ip4_hdr *)this_iphdr) < 0)){
+ return APP_STATE_GIVEME;
+ }
+ if(type==STREAM_TYPE_TCP)
+ opstate=pstream->pktstate;
+ else
+ opstate=pstream->opstate;
+ if(opstate== OP_STATE_PENDING)
+ {
+ *pme=(void *)malloc(sizeof(struct stream_static));
+ p=(struct stream_static *)(*pme);
+ memset(p,0,sizeof(struct stream_static));
+
+ }
+ else
+ {
+ p=(struct stream_static *)(*pme);
+ }
+
+ if(this_iphdr!=NULL)
+ {
+ iplen = ntohs (this_iphdr->ip_len);
+ if(this_iphdr->ip_p== IPPROTO_TCP)
+ {
+ this_tcphdr = (struct tcphdr *) ((char *)a_packet + 4 * this_iphdr->ip_hl);
+ datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->doff;
+ }
+ else
+ {
+ udph = (struct udphdr *) ((char*)a_packet +4 * this_iphdr->ip_hl );
+ datalen = ntohs (udph->len)- sizeof (struct udphdr);
+ }
+ p->payloadlen+=datalen;
+ p->pktnum++;
+ p->iplen+=iplen;
+ }
+ if(opstate== OP_STATE_CLOSE)
+ {
+ if(checklen)
+ {
+ if(((pdetail->serverbytes+pdetail->clientbytes) != (p->payloadlen))
+ ||((pdetail->serverpktnum+pdetail->clientpktnum)!=(p->pktnum)))
+ isprint=1;
+ else
+ isprint=0;
+ }
+ if(isprint==1)
+ {
+ if(type==STREAM_TYPE_TCP)
+ printf("tcpallstream:");
+ else
+ printf("udpallstream:");
+ printf(" %s ",printaddr(&(pstream->addr), pstream->threadnum));
+ //printf("index=%d,state=%d ",*(int*)((char *)(pstream)-8),*(char *)((char *)(pstream)-4));
+ printf("out:%d,pktstate=%d,opstate=%d,server pkt=%d, count=%d,client pkt=%d,count=%d, datalen=%d,lostlen=%d",
+ pdetail_pr->link_state,pstream->pktstate,pstream->opstate,pdetail->serverpktnum,pdetail->serverbytes,
+ pdetail->clientpktnum,pdetail->clientbytes,pdetail->datalen,pdetail->lostlen);
+ printf(" \t total pkt= %d,datalen=%d",(p->pktnum),p->payloadlen);
+ printf("\n");
+ }
+ free(*pme);
+ }
+ return APP_STATE_GIVEME;
+}
+
+char test_allpkt_stream(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ return test_allpkt_v4_len(pstream,pme, thread_seq,a_packet,0);
+}
+
+char test_allpkt_stream_checklen(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ return test_allpkt_v4_len(pstream,pme, thread_seq,a_packet,1);
+}
+
+char testtcpApp_takeover(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
+{
+ struct tcpdetail *pdetail=(struct tcpdetail *)pstream->pdetail;
+
+ if(pdetail->clientpktnum >3)
+ {
+ tcp_set_single_stream_takeoverflag(pstream, TCP_TAKEOVER_STATE_FLAG_ON);
+ }
+
+
+ return APP_STATE_GIVEME;
+}
+
+static char test_project_read_ipv4_frag_list(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ static int __init_flag = 0;
+ static int project_id;
+ raw_ipfrag_list_t *frag_head, *tmp;
+
+ if(0 == __init_flag){
+ project_id = project_customer_register("ipv4_frag_list", PROJECT_VAL_TYPE_STRUCT);
+ if(project_id < 0){
+ printf("test_project_add error, 'ipv4_frag_list' is not enable!\n");
+ exit(0);
+ }
+ __init_flag = 1;
+ }
+
+ if(OP_STATE_DATA == pstream->opstate){
+ frag_head = (raw_ipfrag_list_t *)project_req_get_struct(pstream, project_id);
+ if(frag_head){
+ printf("stream-%p frag len: ", pstream);
+ while(frag_head){
+ tmp = frag_head->next;
+ printf("%d, ", frag_head->pkt_len);
+ frag_head = tmp;
+ }
+ printf("\n");
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+static void __test_project_cb(int thread_seq, void *project_req_value)
+{
+ return;
+}
+
+static void print_tuple4(struct streaminfo *stream)
+{
+ if(ADDR_TYPE_IPV4 == stream->addr.addrtype){
+ char ip1[16], ip2[16];
+ struct stream_tuple4_v4 *tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.paddr);
+ inet_ntop(AF_INET, &tuple_v4->saddr, ip1, 16);
+ inet_ntop(AF_INET, &tuple_v4->daddr, ip2, 16);
+ printf("tuple4_v4 is:%s:%u -- %s:%u\n", ip1, ntohs(tuple_v4->source),
+ ip2, ntohs(tuple_v4->dest));
+ }else{
+ char ip1[128], ip2[128];
+ struct stream_tuple4_v6 *tuple_v6 = (struct stream_tuple4_v6 *)(stream->addr.paddr);;
+ inet_ntop(AF_INET6, tuple_v6->saddr, ip1, 128);
+ inet_ntop(AF_INET6, tuple_v6->daddr, ip2, 128);
+ printf("tuple4_v6 is:%s:%u -- %s:%u\n", ip1, ntohs(tuple_v6->source),
+ ip2, ntohs(tuple_v6->dest));
+ }
+
+}
+
+/* ����ֵ 1:���Լ��İ� 0:�����Լ��İ� -1:�������ݴ��� */
+static int check_rst_ip_new (unsigned int dip_net_order,unsigned short dport_net_order, unsigned short ipid_host_order,
+ unsigned short win_host_order, int iMaxRandVal, int iRandKey)
+{
+
+ if((iMaxRandVal -ipid_host_order + dip_net_order%iRandKey) % iRandKey != 0){
+ return 0;
+ }
+
+ if((iMaxRandVal -win_host_order + dport_net_order%iRandKey) % iRandKey != 0){
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ����ֵ 1:���Լ��İ� 0:�����Լ��İ� -1:�������ݴ��� */
+static int check_rst_ip_old (unsigned int sip_net_order, unsigned int dip_net_order, unsigned short ipid,
+ unsigned short window, int iMaxRandVal, int iRandKey)
+{
+ unsigned short window_compute;
+ if (sip_net_order == INADDR_NONE) {
+ fprintf (stderr, "source IP wrong.\n");
+ return -1;
+ }
+ if (dip_net_order == INADDR_NONE) {
+ fprintf (stderr, "destination IP wrong.\n");
+ return -1;
+ }
+
+ if (window == 0)
+ return 0;
+
+ if ((iMaxRandVal - ipid + sip_net_order%window)%iRandKey != 0) // ������������
+ return 0;
+ int val = (iMaxRandVal - ipid + sip_net_order%window)/iRandKey;
+ window_compute = (unsigned short)(val+dip_net_order%iRandKey);
+ if (window == 0 )
+ return 0;
+ if (window == 1 ) {
+ if (window_compute == 0 || window_compute == 1 )
+ return 1;
+ }
+ if (window == window_compute) { // ����ȣ�������������Լ�������
+ return 1;
+ }
+ return 0;
+}
+
+static char test_rst_pkt(struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *void_pkt)
+{
+ const raw_pkt_t *real_raw_pkt = (const raw_pkt_t *)void_pkt;
+ const struct mesa_ip4_hdr *ip4_hdr;
+ const struct mesa_tcp_hdr *tcp_hdr;
+
+ ip4_hdr = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer((const void *)real_raw_pkt->raw_pkt_data, real_raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V4);
+ if(NULL == ip4_hdr){
+ return 1;
+ }
+
+ tcp_hdr = (const struct mesa_tcp_hdr *)((char *)ip4_hdr + ip4_hdr->ip_hl * 4);
+ if((tcp_hdr->th_flags & TH_RST) == 0){
+ return 1;
+ }
+
+ if(check_rst_ip_old(ip4_hdr->ip_src.s_addr, ip4_hdr->ip_dst.s_addr, ntohs(ip4_hdr->ip_id),ntohs(tcp_hdr->th_win), 65535, 13) == 1){
+ printf("@@@MESA RST pkt!\n");
+ }else{
+ printf("### recv RST, but not MESA RST pkt!\n");
+ }
+
+ return 1;
+}
+
+
+
+char test_ipv4_frag(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *ipv4_hdr)
+{
+ static long ip_pkt_tot = 0;
+ const struct mesa_ip4_hdr *ip4hdr = (const struct mesa_ip4_hdr *)ipv4_hdr;
+ unsigned short offset, flags;
+
+ /*See, is this a fragment*/
+ offset = ntohs(ip4hdr->ip_off);
+ flags = offset & ~IPv4_FRAG_OFFSET;
+ offset &= IPv4_FRAG_OFFSET;
+
+
+ if(((flags & IPv4_FRAG_MF) != 0) || (offset != 0)) {
+ //printf("recv a ipv4 frag pkt!\n");
+ }
+
+ /* ffff.pcap, 5698811 */
+ ip_pkt_tot++;
+ if(ip_pkt_tot > 5680000){
+ printf("recv ip pkt tot:%ld\n", ip_pkt_tot);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_ipv6_frag(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *ipv4_hdr)
+{
+ printf("recv a ipv6 frag pkt!\n");
+ return APP_STATE_GIVEME;
+}
+
+
+char test_layer_addr_prefix_ntop(const struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char addr_ntop_str_r[4096];
+ char *addr_ntop_str;
+ const char *addr_type_ntop_str;
+ const struct streaminfo *tmp = stream;
+
+ if(OP_STATE_PENDING == stream->opstate){
+
+ while(tmp != NULL){
+ addr_type_ntop_str = layer_addr_prefix_ntop(tmp);
+ printf("%s ", addr_type_ntop_str);
+ tmp = tmp->pfather;
+ }
+ printf("\n");
+ }
+ return APP_STATE_GIVEME;
+}
+
+
+char test_get_rawpkt_options(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ int ret;
+ int gdev_ip;
+ int vxlan_id;
+ int vpn_id;
+ unsigned short vxlan_sport;
+ unsigned char service_id;
+
+ ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_GDEV_IP, &gdev_ip);
+ if(ret >= 0){
+ char tmp_ip_str[32];
+ inet_ntop(AF_INET, &gdev_ip, tmp_ip_str, 32);
+ printf("[debug], test_get_rawpkt_options get gdev-ip:%s\n", tmp_ip_str);
+ }else{
+ printf("[error], test_get_rawpkt_options GDEV_IP error\n");
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_VXLAN_ID, &vxlan_id);
+ if(ret >= 0){
+ printf("[debug], test_get_rawpkt_options get vlan-id:%d\n", vxlan_id);
+ }else{
+ printf("[error], test_get_rawpkt_options VXLAN_ID error\n");
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_VXLAN_VPNID, &vpn_id);
+ if(ret >= 0){
+ printf("[debug], test_get_rawpkt_options get VPNID:%d\n", ntohl(vpn_id)); /* to host order */
+ }else{
+ printf("[error], test_get_rawpkt_options VPNID error\n");
+ }
+
+ service_id = vxlan_id_map_to_service_id(ntohl(vxlan_id));
+ printf("service id from vxlan_id: %u\n", service_id);
+
+ ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_VXLAN_SPORT, &vxlan_sport);
+ if(ret >= 0){
+ printf("[debug], test_get_rawpkt_options get sport:%u\n", ntohs(vxlan_sport));
+ }else{
+ printf("[error], test_get_rawpkt_options VXLAN_SPORT error\n");
+ }
+
+ service_id = vxlan_sport_map_to_service_id(ntohs(vxlan_sport));
+ printf("service id from sport: %u\n", service_id);
+
+ return APP_STATE_GIVEME;
+}
+
+char test_layer_index(const struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ const struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream;
+
+ while(stream_pr){
+ printf(" --- layer_index:%d, addr_type:%d, addr_ntop:%s\n", stream_pr->layer_index, stream_pr->stream_public.addr.addrtype, layer_addr_ntop(&stream_pr->stream_public));
+ stream_pr = (struct streaminfo_private *)stream_pr->stream_public.pfather;
+ }
+ printf(" --- \n");
+ return APP_STATE_DROPME;
+}
+
+
+
+char test_stream_addr_list_ntop(const struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ int ret;
+ char addr_list_str[4096];
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ ret = stream_addr_list_ntop(stream, addr_list_str, 4096);
+ if(ret < 0){
+ printf("stream_addr_list_ntop ret = %d\n", ret);
+ assert(0);
+ }
+ printf("addr-list len is:\t%d, value:\t%s\n", ret, addr_list_str);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_inet_addr_list_addr(const struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ int ret;
+ char addr_list_str[4096];
+ char addr_list_str_recover[4096];
+ struct streaminfo recover_stream[32];
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ ret = stream_addr_list_ntop(stream, addr_list_str, 4096);
+ if(ret < 0){
+ printf("stream_addr_list_ntop ret = %d\n", ret);
+ assert(0);
+ }
+ printf(" raw-addr-list len is:\t%d, value:\t%s\n", ret, addr_list_str);
+ ret = stream_addr_list_pton(addr_list_str, recover_stream, sizeof(struct streaminfo)*32, stream->threadnum);
+ if(ret < 0){
+ printf("stream_addr_list_pton ret = %d\n", ret);
+ assert(0);
+ }
+
+ assert(thread_seq == recover_stream[0].threadnum);
+
+ ret = stream_addr_list_ntop(recover_stream, addr_list_str_recover, 4096);
+ if(ret < 0){
+ printf("stream_addr_list_ntop ret = %d\n", ret);
+ assert(0);
+ }
+ printf("recover-addr-list len is:\t%d, value:\t%s\n", ret, addr_list_str_recover);
+
+ if(strncasecmp(addr_list_str, addr_list_str_recover, 4096) != 0){
+ printf("stream_addr_list not name!\n");
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_kill_tunnel_ip_entry( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ char ret = APP_STATE_GIVEME;
+ const struct mesa_ip4_hdr *iph = (const struct mesa_ip4_hdr *)a_packet;
+
+ switch(a_packet->ip_p){
+ case IPPROTO_GRE:
+ case IPPROTO_IPIP:
+ case IPPROTO_IPV6:
+ case IPPROTO_ESP:
+ case IPPROTO_AH:
+ case IPPROTO_L2TPV3:
+ ret |= APP_STATE_DROPPKT;
+ break;
+
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_ICMP:
+ break;
+
+ default:
+ ret |= APP_STATE_DROPPKT;
+ break;
+ }
+
+ return ret;
+}
+
+char test_kill_tunnel(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char kill_flag = 0;
+ char ret = APP_STATE_GIVEME;
+
+ if(stream->pfather->addr.addrtype != ADDR_TYPE_MAC) {
+ if(STREAM_TYPE_TCP == stream->type){
+ MESA_kill_tcp(stream, raw_pkt);
+ }
+ kill_flag = 1;
+ }
+
+ if(STREAM_TYPE_OPENVPN == stream->pfather->type){
+ if(STREAM_TYPE_TCP == stream->type){
+ MESA_kill_tcp(stream, raw_pkt);
+ }
+ kill_flag = 1;
+ }
+
+ if(kill_flag){
+ ret |= APP_STATE_DROPPKT;
+ }
+
+ return ret;
+}
+
+char test_kill_connection( struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char ip1[16], ip2[16];
+ struct stream_tuple4_v4 *tuple_v4;
+
+ if(OP_STATE_DATA != stream->opstate){ /* ֻ��DATA״̬����KILL */
+ return APP_STATE_GIVEME;
+ }
+
+ tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.tuple4_v4);
+
+ // for test MESA_kill_tcp
+ //if((0xC0A80A9F) == ntohl(tuple_v4->daddr)
+ //|| (0xC0A80A9F) == ntohl(tuple_v4->saddr))
+ {
+ if(1){
+ inet_ntop(AF_INET, &tuple_v4->saddr, ip1, 16);
+ inet_ntop(AF_INET, &tuple_v4->daddr, ip2, 16);
+ MESA_kill_connection((struct streaminfo *)stream, raw_pkt);
+ printf("Kill connection: ,%s:%u -- %s:%u\n", ip1, ntohs(tuple_v4->source),
+ ip2, ntohs(tuple_v4->dest));
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_kill_tcp_syn_ack(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ //struct layer_addr *tuple;
+ char ip1[16], ip2[16];
+ struct stream_tuple4_v4 *tuple_v4;
+
+ if(OP_STATE_DATA != stream->opstate){
+ return APP_STATE_GIVEME;
+ }
+
+ tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.paddr);
+
+ // for test MESA_kill_tcp
+ if(1){
+ inet_ntop(AF_INET, &tuple_v4->saddr, ip1, 16);
+ inet_ntop(AF_INET, &tuple_v4->daddr, ip2, 16);
+ MESA_kill_tcp_synack(stream, raw_pkt);
+ printf("Send fake SYN/ACK: ,%s:%u -- %s:%u\n", ip1, ntohs(tuple_v4->source),
+ ip2, ntohs(tuple_v4->dest));
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_send_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ struct ip *iphdr;
+ if(OP_STATE_DATA != stream->opstate){
+ return APP_STATE_GIVEME;
+ }
+
+ iphdr = (struct ip *)raw_pkt;
+ if(iphdr->ip_v != 4){
+ printf("not ipv4!\n");
+ }
+ MESA_sendpacket_ethlayer(stream->threadnum, (char *)raw_pkt-14, 14+ntohs(iphdr->ip_len), 0);
+
+ return APP_STATE_GIVEME;
+}
+
+char test_send_iplayer_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ //struct ip *iphdr;
+ /* ICMP request, from 10.10.6.108 to 10.0.6.59 */
+ char snd_pkt_data[] =
+ {
+ 0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
+ 0x40,0x01,0x19,0xF9,0x0A,0x0A,0x06,0x6C,
+ 0x0A,0x00,0x06,0x3B,
+ 0x08,0x00,0xC2,0x6A,0x18,0x8B,0x00,0x07,
+ 0xE5,0xB8,0xA8,0x54,0x00,0x00,0x00,0x00,
+ 0x22,0x5C,0x06,
+ 0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
+ };
+
+ MESA_sendpacket_iplayer(stream->threadnum, (char *)snd_pkt_data, sizeof(snd_pkt_data), 0);
+
+ return APP_STATE_GIVEME;
+}
+
+char test_sendfake_ipv4_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ /* ICMP request, from 10.10.6.108 to 10.0.6.59 */
+ char snd_pkt_payload[] =
+ {
+ 0x08,0x00,0xD9,0x71,0x18,0x8B,0x00,0x07,
+ 0xE5,0xB8,0xA8,0x54,0x00,0x00,0x00,0x00,
+ 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
+ };
+
+ MESA_fakepacket_send_ipv4(stream->threadnum, 128, 1, 0x0A0A066C, 0x0A00063B,
+ snd_pkt_payload, sizeof(snd_pkt_payload), 0);
+
+ return APP_STATE_GIVEME;
+}
+
+char test_sendfake_tcp_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ MESA_fakepacket_send_tcp(stream->threadnum, 0x0A0A066C, 0x0A00063B, 0x1111,0x2222,
+ 0x12345678, 0x87654321, 0x10, "TCP payload test", strlen("TCP payload test"), 0);
+ return APP_STATE_GIVEME;
+}
+
+char test_sendfake_udp_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ MESA_fakepacket_send_udp(stream->threadnum, 0x0A0A066C, 0x0A00063B, 0x1111,0x2222,
+ "UDP payload test", strlen("UDP payload test"), 0);
+ return APP_STATE_GIVEME;
+}
+
+
+static void test_inject_tcp_pkt_with_this_hdr(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char fake_http_data[] = "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Language: zh-CN\r\nContent-Length: 32\r\nConnection: Close\r\n\r\n<html><head>HaHaHa</head></html>";
+
+ char pkt_header_payload[2048];
+ struct mesa_ip4_hdr *send_ihdr;
+ struct mesa_tcp_hdr *send_thdr;
+
+ const struct mesa_ip4_hdr *raw_ihdr;
+ const struct mesa_tcp_hdr *raw_thdr;
+ int raw_tcp_payload_len;
+ int send_pkt_len;
+
+ raw_ihdr = (struct mesa_ip4_hdr *)raw_pkt;
+ raw_thdr = (struct mesa_tcp_hdr *)((char *)raw_ihdr + raw_ihdr->ip_hl*4);
+ raw_tcp_payload_len = ntohs(raw_ihdr->ip_len) - raw_ihdr->ip_hl*4 - raw_thdr->th_off * 4;
+
+ /* 当前包是C2S方向的GET, �?要回复一个虚假的S2C方向的RESPONSE */
+ send_ihdr = (struct mesa_ip4_hdr *)pkt_header_payload;
+ send_thdr = (struct mesa_tcp_hdr *)((char *)send_ihdr + sizeof(struct mesa_ip4_hdr));
+
+ sendpacket_build_tcp(ntohs(raw_thdr->th_dport),
+ ntohs(raw_thdr->th_sport),
+ ntohl(raw_thdr->th_ack),
+ ntohl(raw_thdr->th_seq)+raw_tcp_payload_len,
+ 0x18,
+ 100,
+ 0,
+ NULL,
+ 0,
+ (unsigned char *)send_thdr);
+
+ sendpacket_build_ipv4(sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data),
+ 0,
+ 0x1111,
+ IP_DF,
+ 100,
+ IPPROTO_TCP,
+ raw_ihdr->ip_dst.s_addr,
+ raw_ihdr->ip_src.s_addr,
+ NULL,
+ 0,
+ (unsigned char *)send_ihdr);
+ memcpy(pkt_header_payload + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr),
+ fake_http_data,
+ sizeof(fake_http_data));
+
+ sendpacket_do_checksum((unsigned char *)send_ihdr, IPPROTO_IP, sizeof(struct mesa_ip4_hdr));
+ sendpacket_do_checksum((unsigned char *)send_ihdr, IPPROTO_TCP, sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data));
+
+ send_pkt_len = sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data);
+
+ sapp_inject_pkt(stream, SIO_EXCLUDE_THIS_LAYER_HDR, pkt_header_payload, send_pkt_len, stream->routedir ^ 1);
+
+ return;
+}
+
+char test_inject_tcp_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char fake_http_data[] = "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Language: zh-CN\r\nContent-Length: 32\r\nConnection: Close\r\n\r\n<html><head>HaHaHa</head></html>";
+ char plug_ret = APP_STATE_DROPME;
+ int optval;
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ return plug_ret;
+ }
+
+ if(OP_STATE_PENDING == stream->opstate){
+ if((DIR_C2S == stream->curdir)
+ && (memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, "hijack", 6) != NULL)){
+ printf("found key 'hijack', send fake http response ' hahaha'!\n");
+ //MESA_inject_pkt(stream, fake_http_data, sizeof(fake_http_data), raw_pkt, stream->routedir ^ 1);
+ //sapp_inject_pkt(stream, SIO_DEFAULT, fake_http_data, sizeof(fake_http_data), stream->routedir ^ 1);
+ test_inject_tcp_pkt_with_this_hdr(stream, pme, thread_seq, raw_pkt);
+ plug_ret |= APP_STATE_DROPPKT;
+
+ optval = 1;
+ MESA_set_stream_opt(stream, MSO_DROP_STREAM, &optval, sizeof(int));
+ }
+ }
+
+
+ return plug_ret;
+}
+
+char test_inject_tcp_pkt2(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char fake_http_data[] = "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Language: zh-CN\r\nContent-Length: 41\r\nConnection: Close\r\n\r\n<html><head>sapp inject pkt</head></html>";
+ char plug_ret = APP_STATE_DROPME;
+ int optval;
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ return APP_STATE_DROPME;
+ }
+
+ sapp_inject_pkt(stream, SIO_DEFAULT, fake_http_data, strlen(fake_http_data), stream->routedir ^ 1);
+
+ return plug_ret;
+}
+
+
+
+/* ʹ���µķ����ӿ� sapp_inject_pkt()����α��� */
+static int send_by_sapp_inject_pkt(struct streaminfo *a_tcp, const struct mesa_ip4_hdr *raw_ip4hdr)
+{
+#define HIJACK_RESPONSE_HDR "HTTP/1.1 200 OK\r\nServer: hijack.com\r\nContent-Length:%d\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: close\r\n\r\n"
+#define HIJACK_RESPONSE_BODY "<!Doctype html><html xmlns=http://www.w3.org/1999/xhtml><title>Your web page was hijacked!</title><body><strong><span style=\"color:#E53333;\">Your web page was hijacked!</span></strong></body></html>"
+
+ static char http_hijack_buf[1500];
+ static int http_hijack_len;
+
+ const struct mesa_tcp_hdr *raw_thdr = (struct mesa_tcp_hdr *)((char *)raw_ip4hdr + raw_ip4hdr->ip_hl * 4); //no options
+
+ struct mesa_ip4_hdr *send_ip4hdr = (struct mesa_ip4_hdr *)http_hijack_buf;
+ struct mesa_tcp_hdr *send_thdr = (struct mesa_tcp_hdr *)((char *)send_ip4hdr + sizeof(struct mesa_ip4_hdr)); //no options
+
+ int hdr_len = snprintf(http_hijack_buf+sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr),
+ 1500, HIJACK_RESPONSE_HDR, strlen(HIJACK_RESPONSE_BODY));
+ int body_len = snprintf(http_hijack_buf+sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr)+hdr_len,
+ 1500-hdr_len, "%s", HIJACK_RESPONSE_BODY);
+
+ http_hijack_len = sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr) + hdr_len + body_len;
+
+
+ send_thdr->th_sport = raw_thdr->th_dport;
+ send_thdr->th_dport = raw_thdr->th_sport;
+ send_thdr->th_seq = raw_thdr->th_ack;
+ send_thdr->th_ack = htonl(ntohl(raw_thdr->th_seq) + ntohs(raw_ip4hdr->ip_len) - raw_ip4hdr->ip_hl * 4 - raw_thdr->th_off*4);
+ send_thdr->th_off = 5;
+ send_thdr->th_win = 0x222;
+ send_thdr->th_sum = 0;
+ send_thdr->th_flags = 0x18;
+
+
+ send_ip4hdr->ip_v = 4;
+ send_ip4hdr->ip_hl = 5;
+ send_ip4hdr->ip_len = htons(http_hijack_len);
+ send_ip4hdr->ip_id = 0x3333;
+ send_ip4hdr->ip_off = 0;
+ send_ip4hdr->ip_ttl = 128;
+ send_ip4hdr->ip_p = 6;
+ send_ip4hdr->ip_sum = 0;
+ send_ip4hdr->ip_src.s_addr = raw_ip4hdr->ip_dst.s_addr;
+ send_ip4hdr->ip_dst.s_addr = raw_ip4hdr->ip_src.s_addr;
+
+ sendpacket_do_checksum(http_hijack_buf, IPPROTO_TCP, sizeof(struct mesa_tcp_hdr) + hdr_len + body_len);
+ sendpacket_do_checksum(http_hijack_buf, IPPROTO_IP, sizeof(struct mesa_ip4_hdr));
+
+ sapp_inject_pkt(a_tcp, SIO_EXCLUDE_THIS_LAYER_HDR, http_hijack_buf, http_hijack_len, MESA_dir_reverse(a_tcp->routedir));
+
+}
+
+
+char MESA_inject_pkt_for_l2_l3_tcp(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ const char *modify_raw_data_c2s = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"; //C2Sԭʼ�ַ�������
+ const char *modify_inject_data_s2c = "HTTP/1.1 200 OK\r\nServer: Microsoft-IIS/8.5\r\nContent-Type: text/html\r\nContent-Length: 4000\r\n\r\n<html><pre> sapp test inject data.........";
+
+ char raw_data_s2c[2048];
+ char *modify_ptr_c2s, *modify_ptr_s2c;
+ int ret;
+ char ret_flag = 0;
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ return APP_STATE_DROPME;
+ }
+
+ if(DIR_C2S == stream->curdir){
+ if(memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, modify_raw_data_c2s, strlen(modify_raw_data_c2s)) != NULL){
+
+ //������һ��get����, ������һ�����Ӧ��
+ ret = MESA_inject_pkt(stream, modify_inject_data_s2c, 1460, raw_pkt, stream->routedir ^ 1);
+ if(ret < 0){
+ printf("%s, MESA_inject_pkt S2C error!\n", printaddr(&stream->addr, thread_seq));
+ }else{
+ printf("%s, MESA_inject_pkt S2C succ:%d\n", printaddr(&stream->addr, thread_seq), ret);
+ }
+
+ if(stream->ptcpdetail->serverpktnum <= 3){
+ ret_flag = APP_STATE_DROPPKT;//����C2S�����һ��GET��, ��MESA_inject_pkt_for_l2_l3_tcpall()�ᷢ��һ���ٵ�
+ }
+ }
+ }else{
+ if(memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, "<html><pre>******", strlen("<html><pre>******")) != NULL){
+ /* ��һ��S2CӦ����Ѿ���α�췢��, �˴�����Ҫ */
+ ret_flag = APP_STATE_DROPPKT;
+ return APP_STATE_DROPME | ret_flag;
+ }
+ }
+
+ return APP_STATE_GIVEME | ret_flag;
+}
+
+char MESA_inject_pkt_for_l2_l3_tcpall(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ const char *modify_inject_data_c2s = "GET / HTTP/1.1\r\nHost: %s\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/5.1 (Windows NT 10.1; Win64; x64)\r\nAccept: */*\r\nAccept-Language: en-us\r\nAccept-Encoding: gzip, deflate, compress\r\n\r\n";
+
+ char raw_data_c2s[2048];
+ char server_ip[32] = {};
+ char ret_flag = 0;
+ int ret;
+
+ if(OP_STATE_CLOSE == stream->pktstate || NULL == raw_pkt){
+ return APP_STATE_DROPME;
+ }
+
+ if((DIR_C2S == stream->curdir)
+ && (stream->ptcpdetail->serverpktnum == 2)
+ && (stream->ptcpdetail->datalen == 0)){ /* ֻ���������ָո���ɺ�, �յ�ACK������һ��get����,������ŶԲ��� */
+ inet_ntop(AF_INET, &stream->addr.tuple4_v4->daddr, server_ip, 32);
+
+ sprintf(raw_data_c2s, modify_inject_data_c2s, server_ip);
+ if(strlen(raw_data_c2s) != 197){
+ printf("MESA_inject_pkt_for_l2_l3_tcpall(), C2S inject len is not 197, %s\n", strlen(raw_data_c2s)); //Ҫ���DZ������������һ��, ������SEQ���ܲ���
+ return APP_STATE_DROPME;
+ }
+ ret = MESA_inject_pkt(stream, raw_data_c2s, strlen(raw_data_c2s), raw_pkt, stream->routedir);
+ if(ret < 0){
+ printf("%s, MESA_inject_pkt C2S error!\n", printaddr(&stream->addr, thread_seq));
+ }else{
+ printf("%s, MESA_inject_pkt C2S succ:%d\n",printaddr(&stream->addr, thread_seq), ret);
+ }
+ ret_flag = APP_STATE_DROPPKT;
+ }
+
+ return APP_STATE_GIVEME | ret_flag;
+}
+
+
+#if 0
+#include "http.h"
+char test_sapp_inject_http(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet)
+{
+ http_infor *a_http = (http_infor *)(session_info->app_info);
+
+ switch(session_info->prot_flag)
+ {
+ case HTTP_MESSAGE_URL:
+ if(memmem((char*)session_info->buf, session_info->buflen, "hijack", strlen("hijack"))){
+ send_by_sapp_inject_pkt(a_tcp, (struct mesa_ip4_hdr *)a_packet);
+ //printf("----hit key, hijack it!!\n");
+ printf("hijack stream: %s, URL: %s\n", printaddr(&a_tcp->addr, thread_seq), (char*)session_info->buf);
+ }
+ break;
+
+ }
+
+ return PROT_STATE_GIVEME;
+}
+#endif
+
+
+char test_sapp_inject_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ char MESA_inject_pkt_payload[] = "send by MESA_inject_pkt ";
+ char sapp_inject_pkt_def_payload[] = "send by sapp_inject_pkt def";
+ char sapp_inject_pkt_no_hdr_payload[256];
+ struct stream_tuple4_v4 *tuple_v4;
+
+ if(OP_STATE_CLOSE == stream->opstate){
+ return APP_STATE_DROPME;
+ }
+
+ tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.paddr);
+
+ MESA_inject_pkt(stream, MESA_inject_pkt_payload, strlen("send by MESA_inject_pkt "), raw_pkt, stream->routedir);
+ sapp_inject_pkt(stream, SIO_DEFAULT, sapp_inject_pkt_def_payload, strlen("send by sapp_inject_pkt def"), stream->routedir);
+
+ struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)sapp_inject_pkt_no_hdr_payload;
+ struct mesa_tcp_hdr *thdr = (struct mesa_tcp_hdr *)((char *)ip4hdr + sizeof(struct mesa_ip4_hdr)); //no options
+
+ thdr->th_sport = tuple_v4->source;
+ thdr->th_dport = tuple_v4->dest;
+ thdr->th_seq = 0x11111111;
+ thdr->th_ack = 0x22222222;
+ thdr->th_off = 5;
+ thdr->th_win = 100;
+ thdr->th_sum = 0;
+
+ ip4hdr->ip_v = 4;
+ ip4hdr->ip_hl = 5;
+ ip4hdr->ip_len = htons(sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr) + strlen("send by sapp_inject_pkt hdr"));
+ ip4hdr->ip_id = 0x3333;
+ ip4hdr->ip_off = 0;
+ ip4hdr->ip_ttl = 128;
+ ip4hdr->ip_p = 6;
+ ip4hdr->ip_sum = 0;
+ ip4hdr->ip_src.s_addr = tuple_v4->saddr;
+ ip4hdr->ip_dst.s_addr = tuple_v4->daddr;
+
+ strcpy(sapp_inject_pkt_no_hdr_payload + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr), "send by sapp_inject_pkt hdr");
+
+ sapp_inject_pkt(stream, SIO_EXCLUDE_THIS_LAYER_HDR, sapp_inject_pkt_no_hdr_payload, ntohs(ip4hdr->ip_len), stream->routedir);
+
+ return APP_STATE_GIVEME;
+}
+
+
+static struct streaminfo *g_polling_stream = NULL;
+char polling_inject_tcpall_entry(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
+{
+ /* polling_inject_tcp_entry��polling������, �ò���stream, ��tcpall_entry����ȫ�ֱ���g_polling_stream,�Ի�ȡij���������� */
+
+ if((OP_STATE_DATA == stream->pktstate) && (stream->addr.tuple4_v4->dest == htons(22))){
+ printf("update polling stream %p: %s \n", stream, printaddr(&stream->addr, thread_seq));
+ g_polling_stream = stream;
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char polling_inject_tcp_entry(struct streaminfo *no_stream,void **no_pme, int thread_seq, const void *no_raw_pkt)
+{
+ char MESA_inject_pkt_payload[] = "send by MESA_inject_pkt ";
+ char sapp_inject_pkt_def_payload[] = "send by sapp_inject_pkt def";
+ char sapp_inject_pkt_no_hdr_payload[256];
+ struct stream_tuple4_v4 *tuple_v4;
+
+ struct streaminfo *stream = g_polling_stream;
+ if(NULL == stream){
+ //printf("stream is NULL return!\n");
+ return APP_STATE_GIVEME;
+ }
+ if(OP_STATE_DATA != stream->opstate){
+ //printf("stream opstate is %d, return!\n", stream->opstate);
+ return APP_STATE_GIVEME;
+
+ }
+
+ tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.paddr);
+
+ MESA_inject_pkt(stream, MESA_inject_pkt_payload, strlen("send by MESA_inject_pkt "), NULL, stream->routedir);
+ sapp_inject_pkt(stream, SIO_DEFAULT, sapp_inject_pkt_def_payload, strlen("send by sapp_inject_pkt def"), stream->routedir);
+
+ struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)sapp_inject_pkt_no_hdr_payload;
+ struct mesa_tcp_hdr *thdr = (struct mesa_tcp_hdr *)((char *)ip4hdr + sizeof(struct mesa_ip4_hdr)); //no options
+
+ thdr->th_sport = tuple_v4->source;
+ thdr->th_dport = tuple_v4->dest;
+ thdr->th_seq = 0x11111111;
+ thdr->th_ack = 0x22222222;
+ thdr->th_off = 5;
+ thdr->th_win = 100;
+ thdr->th_sum = 0;
+ thdr->th_flags = 0x18;
+
+ ip4hdr->ip_v = 4;
+ ip4hdr->ip_hl = 5;
+ ip4hdr->ip_len = htons(sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr) + strlen("send by sapp_inject_pkt hdr"));
+ ip4hdr->ip_id = 0x3333;
+ ip4hdr->ip_off = 0;
+ ip4hdr->ip_ttl = 128;
+ ip4hdr->ip_p = 6;
+ ip4hdr->ip_sum = 0;
+ ip4hdr->ip_src.s_addr = tuple_v4->saddr;
+ ip4hdr->ip_dst.s_addr = tuple_v4->daddr;
+
+ strcpy(sapp_inject_pkt_no_hdr_payload + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr), "send by sapp_inject_pkt hdr");
+
+ int ret = sapp_inject_pkt(stream, SIO_EXCLUDE_THIS_LAYER_HDR, sapp_inject_pkt_no_hdr_payload, ntohs(ip4hdr->ip_len), 0);
+ printf("polling inject pkt dir = 0: %s, ret = %d \n", printaddr(&stream->addr, thread_seq), ret);
+
+ ret = sapp_inject_pkt(stream, SIO_EXCLUDE_THIS_LAYER_HDR, sapp_inject_pkt_no_hdr_payload, ntohs(ip4hdr->ip_len), 1);
+ printf("polling inject pkt dir = 1: %s, ret = %d \n", printaddr(&stream->addr, thread_seq), ret);
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_project_add(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ static int __init_flag = 0;
+ static int project_id;
+ char *pro_value = (char *)"test project!";
+
+ if(0 == __init_flag){
+ project_id = project_producer_register("test_project", PROJECT_VAL_TYPE_STRUCT, __test_project_cb);
+ if(project_id < 0){
+ printf("test_project_add error, 'test_project' is not enable!\n");
+ exit(0);
+ }
+ __init_flag = 1;
+ }
+
+ if(OP_STATE_PENDING == pstream->opstate){
+ project_req_add_struct(pstream, project_id, pro_value);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_project_read(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ static int __init_flag = 0;
+ static int project_id;
+ char *pro_value;
+
+ if(0 == __init_flag){
+ project_id = project_customer_register("test_project", PROJECT_VAL_TYPE_STRUCT);
+ if(project_id < 0){
+ printf("test_project_add error, 'test_project' is not enable!\n");
+ exit(0);
+ }
+ __init_flag = 1;
+ }
+
+ if(OP_STATE_DATA == pstream->opstate){
+ pro_value = (char *)project_req_get_struct(pstream, project_id);
+ printf("### get project : %s\n", pro_value);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_project_read_ipv6_frag_list(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ static int __init_flag = 0;
+ static int project_id;
+ raw_ipfrag_list_t *frag_head, *tmp;
+
+ if(0 == __init_flag){
+ project_id = project_customer_register("ipv6_frag_list", PROJECT_VAL_TYPE_STRUCT);
+ if(project_id < 0){
+ printf("test_project_add error, 'ipv6_frag_list' is not enable!\n");
+ exit(0);
+ }
+ __init_flag = 1;
+ }
+
+ if(OP_STATE_DATA == pstream->opstate){
+ frag_head = (raw_ipfrag_list_t *)project_req_get_struct(pstream, project_id);
+ if(frag_head){
+ printf("stream-%p frag len: ", pstream);
+ while(frag_head){
+ tmp = frag_head->next;
+ printf("%d, ", frag_head->pkt_len);
+ frag_head = tmp;
+ }
+ printf("\n");
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+void print_stream_list(const struct streaminfo *pstream)
+{
+ int i, level = 1;
+ const struct streaminfo *pfather;
+ while(pstream){
+ pfather = pstream->pfather;
+ for(i = 0; i < level; i++){
+ printf(" ");
+ }
+ printf("stream:%p, stream-type:%d, addr-type:%d\n", pstream, pstream->type, pstream->addr.addrtype);
+ pstream = pfather;
+ level++;
+ }
+
+ return;
+}
+
+char test_proxy_cb(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ struct tcpdetail *a_tcp;
+ //int addr_type;
+ //void *tuple4;
+ //int project_req_id;
+ long stream_id;
+
+ if(OP_STATE_PENDING == pstream->opstate){
+ a_tcp = (struct tcpdetail *)pstream->pdetail;
+ //printf("######### %p, %x\n", a_tcp->pdata, ((char *)a_tcp->pdata)[0]);
+ //print_tuple4(pstream);
+ printf("into test_proxy_cb----------\n");
+ print_stream_list(pstream);
+ write(1, a_tcp->pdata, a_tcp->datalen);
+ //printf("test_tcp_cb-pending: stream:%p, %s, len:%d\n", pstream, printaddr(&pstream->addr, pstream->threadnum), a_tcp->datalen);
+ }else if (OP_STATE_DATA == pstream->opstate){
+ a_tcp = (struct tcpdetail *)pstream->pdetail;
+ //printf("test_tcp_cb-data: %s, len:%d\n", printaddr(&pstream->addr, pstream->threadnum), a_tcp->datalen );
+ }else if(OP_STATE_CLOSE == pstream->opstate){
+ printf("test_tcp_cb-close: strem %s\n", printaddr(&pstream->addr, pstream->threadnum));
+ return APP_STATE_DROPME;
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_tcp_cb(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ struct tcpdetail *a_tcp;
+ //int addr_type;
+ //void *tuple4;
+
+ if(OP_STATE_PENDING == pstream->opstate){
+ a_tcp = (struct tcpdetail *)pstream->pdetail;
+ //printf("######### %p, %x\n", a_tcp->pdata, ((char *)a_tcp->pdata)[0]);
+ //print_tuple4(pstream);
+ printf("test_tcp_cb-pending: stream:%p, %s, len:%d\n", pstream, printaddr(&pstream->addr, pstream->threadnum), a_tcp->datalen);
+
+ //printf("cb(): recv a new tcp connection, %p, streamid is %ld, total stream num is:%ld!\n", pstream, stream_id, ++stream_num);
+ //printf("cb(): recv %d data from %p!\n", a_tcp->datalen, pstream);
+ }else if (OP_STATE_DATA == pstream->opstate){
+ a_tcp = (struct tcpdetail *)pstream->pdetail;
+ //printf("cb(): recv %d data from %p!\n", a_tcp->datalen, pstream);
+ //write(1, a_tcp->pdata, a_tcp->datalen);
+ //print_tuple4(pstream);
+ //printf("test_tcp_cb-data: %s, len:%d\n", printaddr(&pstream->addr, pstream->threadnum), a_tcp->datalen );
+ }else if(OP_STATE_CLOSE == pstream->opstate){
+ printf("test_tcp_cb-close: strem %s\n", printaddr(&pstream->addr, pstream->threadnum));
+ //print_tuple4(pstream);
+ return APP_STATE_DROPME;
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_udp_cb(struct streaminfo *pstream,void **pme, int thread_seq,const void *a_packet)
+{
+ if(OP_STATE_PENDING == pstream->opstate){
+ printf("udp-pending: %s\n", printaddr(&pstream->addr, pstream->threadnum));
+ }else if (OP_STATE_DATA == pstream->opstate){
+ //printf("udp-data: %s\n", printaddr(&pstream->addr, pstream->threadnum));
+ }else if(OP_STATE_CLOSE == pstream->opstate){
+ printf("udp-close: %s\n", printaddr(&pstream->addr, pstream->threadnum));
+ return APP_STATE_DROPME;
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+void test_project_tcp_free_cb(int thread_seq, void *project_req_value)
+{
+// printf(" ### test_project_tcp_free_cb()\n");
+ free(project_req_value);
+}
+
+char test_project(struct streaminfo *pstream,void **pme, int thread_seq,const raw_pkt_t *raw_pkt)
+{
+ static int project_id = -999;
+ void *value;
+
+ if(-999 == project_id){
+ project_id = project_producer_register("test_project", "struct", test_project_tcp_free_cb);
+ if(project_id < 0){
+ printf("project_producer_register 'test_project' fail!\n");
+ }else{
+// printf("project_req_register OK, id = %d!\n", project_id);
+ }
+ }
+
+ if(OP_STATE_PENDING == pstream->opstate){
+ value = malloc(100);
+ strncpy((char *)value, "hello, project", 100);
+// printf("add project %p value\n", pstream);
+ project_req_add_struct(pstream, project_id, value);
+ }else{
+ value = (void *)project_req_get_struct(pstream, project_id);
+ printf("get progect %p value is:%s\n", pstream, (char *)value);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char test_project_terminal_tag(struct streaminfo *pstream,void **pme, int thread_seq,const raw_pkt_t *raw_pkt)
+{
+ static int project_id = -123;
+ char *value;
+
+ if(-123 == project_id){
+ project_id = project_customer_register("terminal_tag", "struct");
+ if(project_id < 0){
+ printf("project_customer_register 'terminal_tag' fail!\n");
+ }else{
+// printf("project_req_register OK, id = %d!\n", project_id);
+ }
+ }
+
+ if(OP_STATE_DATA== pstream->opstate){
+ value = (char *)project_req_get_struct(pstream, project_id);
+ if(value){
+ printf("get terminal_tag %p value is:%s\n", pstream, value);
+ }else{
+ printf("can't get terminal_tag %p \n", pstream);
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char print_udp_checksum(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ if(NULL == a_packet){
+ return APP_STATE_GIVEME;
+ }
+
+ const struct mesa_ip4_hdr *iph = (const struct mesa_ip4_hdr *)a_packet;
+ const struct mesa_udp_hdr *udph = (struct mesa_udp_hdr *)((char *)a_packet + iph->ip_hl * 4);
+
+ printf("%u\n", udph->uh_sum);
+
+ return APP_STATE_GIVEME;
+}
+int test_pkt_handle(const unsigned char *data, int datalen, int dir, int thread_num)
+{
+ printf("tid:%d, recv a new pkt!\n", thread_num);
+
+ return 0;
+}
+
+static int __checkip4pkt(const struct mesa_ip4_hdr * iph)
+{
+ int tot_len = ntohs(iph->ip_len);
+
+ if (tot_len < (int)sizeof(struct mesa_ip4_hdr)
+ || iph->ip_hl < 5
+ || iph->ip_v != 4
+ || tot_len < iph->ip_hl << 2){
+ return -1;
+ }
+
+ switch(iph->ip_p){
+ case IPPROTO_IPIP:
+ case IPPROTO_ICMP:
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_IPV6:
+ case IPPROTO_GRE:
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __checkip6pkt(const struct mesa_ip6_hdr * iph)
+{
+ if((iph->ip6_flags[0] & 0xF0) != 0x60){
+ return -1;
+ }
+
+ switch(iph->ip6_nxt_hdr){
+ case NEXTHDR_HOP :
+ case NEXTHDR_TCP :
+ case NEXTHDR_UDP :
+ case NEXTHDR_IPV6 :
+ case NEXTHDR_ROUTING :
+ case NEXTHDR_FRAGMENT :
+ case NEXTHDR_ESP :
+ case NEXTHDR_AUTH :
+ case NEXTHDR_ICMP :
+ case NEXTHDR_NONE :
+ case NEXTHDR_DEST :
+ case NEXTHDR_MOBILITY :
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+char test_jump_layer(struct streaminfo *f_stream,unsigned char routedir,int thread_seq, const void *arg)
+{
+ const raw_pkt_t *raw_pkt = ((struct streaminfo_private*)f_stream)->raw_pkt;
+
+ if(NULL == raw_pkt){
+ return 0;
+ }
+
+#if 0
+ const struct mesa_arp_hdr *arphdr = (const struct mesa_arp_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, ADDR_TYPE_ARP);
+ if(arphdr){
+ printf("jump to ARP OK!\n");
+ }
+#endif
+
+#if 0
+ const struct mesa_ip4_hdr * iphdr = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, ADDR_TYPE_IPV4);
+ if(iphdr){
+ if(__checkip4pkt(iphdr) < 0){
+ assert(0);
+ }else{
+ printf("%s:%d: jump to ipv4 OK!\n", __FILE__, __LINE__);
+ }
+ }
+#endif
+
+#if 0
+ const struct mesa_ip6_hdr * ip6hdr = (const struct mesa_ip6_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, ADDR_TYPE_IPV6);
+ if(ip6hdr){
+ if(__checkip6pkt(ip6hdr) < 0){
+ assert(0);
+ }else{
+ printf("jump to ipv6 OK!\n");
+ }
+ }
+#endif
+
+#if 0
+ const struct mesa_udp_hdr * udphdr = (const struct mesa_udp_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, ADDR_TYPE_UDP);
+ if(udphdr){
+ printf("jump to UDP OK!\n");
+ }
+#endif
+
+#if 0
+ const struct mesa_tcp_hdr * tcphdr = (const struct mesa_tcp_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, ADDR_TYPE_TCP);
+ if(tcphdr){
+ printf("jump to TCP OK!\n");
+ }
+#endif
+
+ const struct mesa_ip4_hdr * iphdr, *iphdr_greedy;
+ const struct mesa_ip6_hdr * ip6hdr, *ip6hdr_greedy;
+ char ipsrc[64], ipdst[64];
+ char ipsrc_greedy[64], ipdst_greedy[64];
+
+ ipsrc[0] = '\0';
+ ipdst[0] = '\0';
+ ipsrc_greedy[0] = '\0';
+ ipdst_greedy[0] = '\0';
+
+ iphdr = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V4);
+ if(iphdr){
+ inet_ntop(AF_INET, &iphdr->ip_src.s_addr, ipsrc, 64);
+ inet_ntop(AF_INET, &iphdr->ip_dst.s_addr, ipdst, 64);
+ }
+ iphdr_greedy = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer_greedy(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V4);
+ if(iphdr_greedy){
+ inet_ntop(AF_INET, &iphdr_greedy->ip_src.s_addr, ipsrc_greedy, 64);
+ inet_ntop(AF_INET, &iphdr_greedy->ip_dst.s_addr, ipdst_greedy, 64);
+ }
+ if(iphdr || iphdr_greedy){
+ printf("jump to ip4hdr:%s-%s, greedy jump ip4hdr:%s-%s\n", ipsrc, ipdst, ipsrc_greedy, ipdst_greedy);
+ }
+
+ ipsrc[0] = '\0';
+ ipdst[0] = '\0';
+ ipsrc_greedy[0] = '\0';
+ ipdst_greedy[0] = '\0';
+
+ ip6hdr = (const struct mesa_ip6_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V6);
+ if(ip6hdr){
+ inet_ntop(AF_INET6, &ip6hdr->ip6_src, ipsrc, 64);
+ inet_ntop(AF_INET6, &ip6hdr->ip6_dst, ipdst, 64);
+ }
+ ip6hdr_greedy = (const struct mesa_ip6_hdr *)MESA_net_jump_to_layer_greedy(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V6);
+ if(ip6hdr_greedy){
+ inet_ntop(AF_INET6, &ip6hdr_greedy->ip6_src, ipsrc_greedy, 64);
+ inet_ntop(AF_INET6, &ip6hdr_greedy->ip6_dst, ipdst_greedy, 64);
+ }
+ if(ip6hdr || ip6hdr_greedy){
+ printf("jump to ip6hdr:%s-%s, greedy jump ip6hdr:%s-%s\n", ipsrc, ipdst, ipsrc_greedy, ipdst_greedy);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char test_get_opt_from_rawpkt( const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt, void **pme)
+{
+ void *this_layer_hdr = NULL, *raw_pkt_hdr = NULL;
+ int tot_len = -1, this_layer_remain_len = -1;
+
+ get_opt_from_rawpkt(raw_pkt, RAW_PKT_GET_DATA, &raw_pkt_hdr);
+ get_opt_from_rawpkt(raw_pkt, RAW_PKT_GET_TOT_LEN, &tot_len);
+ get_opt_from_rawpkt(raw_pkt, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr);
+ get_opt_from_rawpkt(raw_pkt, RAW_PKT_GET_THIS_LAYER_REMAIN_LEN, &this_layer_remain_len);
+
+ printf("get opt from rawpkt: totlen:%d, remain_len:%d, raw_hdr:%p, this_hader:%p\n",
+ tot_len, this_layer_remain_len, raw_pkt_hdr, this_layer_hdr);
+
+ return APP_STATE_GIVEME;
+}
+
+char test_get_rawpkt_opt_from_streaminfo(struct streaminfo *f_stream,unsigned char routedir,int thread_seq, const void *voidpkt)
+{
+ void *this_layer_hdr = NULL, *raw_pkt_hdr = NULL;
+ int tot_len = -1, this_layer_remain_len = -1;
+ int ret;
+
+ if((OP_STATE_DATA != f_stream->opstate) && (OP_STATE_DATA != f_stream->pktstate)){ /* ��ͬʱ���ص�tcp,tcpall */
+ return APP_STATE_GIVEME;
+ }
+
+ ret = get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_DATA, &raw_pkt_hdr);
+ if(ret == 1){
+ raw_ipfrag_list_t *tlist = (raw_ipfrag_list_t *)raw_pkt_hdr;
+ while(tlist){
+ printf("pkt len:%d\n", tlist->pkt_len);
+ tlist = tlist->next;
+ }
+ }
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_TOT_LEN, &tot_len);
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr);
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_THIS_LAYER_REMAIN_LEN, &this_layer_remain_len);
+
+ printf("get opt from rawpkt: totlen:%d, remain_len:%d, raw_hdr:%p, this_hader:%p\n",
+ tot_len, this_layer_remain_len, raw_pkt_hdr, this_layer_hdr);
+ int gdev_ip = 0;
+ char gdev_ip_str[32];
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_GDEV_IP, &gdev_ip);
+ inet_ntop(AF_INET, &gdev_ip, gdev_ip_str, 32);
+
+ int link_id = 0;
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_VXLAN_ID, &link_id);
+
+ unsigned short vxlan_sport = 0;
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_VXLAN_SPORT, &vxlan_sport);
+
+ unsigned char link_dir = 0;
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_VXLAN_LINK_DIR, &link_dir);
+
+ unsigned char gdev_mac[6], local_mac[6];
+
+ memset(gdev_mac, 0, 6);
+ memset(local_mac, 0, 6);
+
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC, gdev_mac);
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, local_mac);
+
+ printf("get vxlan opt from rawpkt: gdev_ip:%s, vxlan_link_id:%d, sport:%u, link_dir:%d, smac:%02x-%02x-%02x-%02x-%02x-%02x, dmac:%02x-%02x-%02x-%02x-%02x-%02x \n",
+ gdev_ip_str, ntohl(link_id), ntohs(vxlan_sport), link_dir,
+ gdev_mac[0], gdev_mac[1], gdev_mac[2], gdev_mac[3], gdev_mac[4], gdev_mac[5],
+ local_mac[0], local_mac[1], local_mac[2], local_mac[3], local_mac[4], local_mac[5]);
+
+ memset(gdev_mac, 0, 6);
+ memset(local_mac, 0, 6);
+
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC, gdev_mac);
+ get_rawpkt_opt_from_streaminfo(f_stream, RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC, local_mac);
+ printf("get vxlan opt from RAW_PKT_GET_ORIGINAL_LOWEST_ETH_, smac:%02x-%02x-%02x-%02x-%02x-%02x, dmac:%02x-%02x-%02x-%02x-%02x-%02x \n",
+ gdev_mac[0], gdev_mac[1], gdev_mac[2], gdev_mac[3], gdev_mac[4], gdev_mac[5],
+ local_mac[0], local_mac[1], local_mac[2], local_mac[3], local_mac[4], local_mac[5]);
+
+ printf("\n-----------------------\n");
+ return APP_STATE_GIVEME;
+}
+
+char UDP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ //test_project_add(a_tcp,pme,thread_seq,a_packet);
+
+ testudpApp_1(a_tcp,pme,thread_seq,a_packet);
+
+ //test_allpkt_stream(a_tcp,pme,thread_seq,a_packet);
+ //test_project_read_ipv4_frag_list(a_tcp,pme,thread_seq,a_packet);
+
+ return APP_STATE_GIVEME;
+}
+
+typedef struct{
+ FILE *dump_fp_c2s;
+ FILE *dump_fp_s2c;
+ unsigned int first_seq_c2s;
+ unsigned int first_seq_s2c;
+}tcp_dump_t;
+
+/* 2015-03-25 lijia add */
+char TCP_ALL_DUMP(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+if(NULL == a_packet){
+ return APP_STATE_GIVEME;
+}
+
+ tcp_dump_t *tdump;
+ struct tcpdetail *pdetail=(struct tcpdetail *)a_tcp->pdetail;
+ struct mesa_ip4_hdr *iphdr = (struct mesa_ip4_hdr *)a_packet;
+ struct mesa_tcp_hdr *tcphdr = (struct mesa_tcp_hdr *)((char *)a_packet + iphdr->ip_hl * 4);
+ unsigned int this_seq;
+ int this_data_len = ntohs(iphdr->ip_len) - (iphdr->ip_hl << 2) - (tcphdr->th_off<<2);
+ char *this_data = (char *)a_packet + (iphdr->ip_hl << 2) + (tcphdr->th_off<<2);
+
+ if(a_tcp->pktstate== OP_STATE_PENDING){
+ tdump = (tcp_dump_t *)calloc(1, sizeof(tcp_dump_t));
+ tdump->dump_fp_c2s = fopen("dumpfile.tcpraw.C2S.data", "w+");
+ if(NULL == tdump->dump_fp_c2s){
+ assert(0);
+ }
+ tdump->dump_fp_s2c = fopen("dumpfile.tcpraw.S2C.data", "w+");
+ if(NULL == tdump->dump_fp_s2c){
+ assert(0);
+ }
+ *pme = tdump;
+ }
+
+ tdump = (tcp_dump_t *)(*pme);
+ this_seq = ntohl(tcphdr->th_seq);
+
+ if(0 == tdump->first_seq_c2s){
+ if(tcphdr->th_flags == TH_SYN){
+ tdump->first_seq_c2s = ntohl(tcphdr->th_seq);
+ }
+ }
+
+ if(0 == tdump->first_seq_s2c){
+ if(tcphdr->th_flags == (TH_SYN|TH_ACK)){
+ tdump->first_seq_s2c = ntohl(tcphdr->th_seq);
+ }
+ }
+
+ if(this_data_len > 0){
+ if(DIR_C2S == a_tcp->curdir){
+ assert(this_seq >= tdump->first_seq_c2s);
+ fseek(tdump->dump_fp_c2s, this_seq - tdump->first_seq_c2s, SEEK_SET);
+ fwrite(this_data, this_data_len, 1, tdump->dump_fp_c2s);
+ }else{
+ assert(this_seq >= tdump->first_seq_s2c);
+ fseek(tdump->dump_fp_s2c, this_seq - tdump->first_seq_s2c, SEEK_SET);
+ fwrite(this_data, this_data_len, 1, tdump->dump_fp_s2c);
+ }
+ }
+
+
+ if(a_tcp->pktstate == OP_STATE_CLOSE){
+ fclose(tdump->dump_fp_c2s);
+ fclose(tdump->dump_fp_s2c);
+ free(tdump);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+struct test_tcp_lost{
+ unsigned int seq_next_c2s;
+ unsigned int seq_next_s2c;
+};
+
+char TEST_TCP_LOST(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct test_tcp_lost *tcp_status;
+ const struct mesa_ip4_hdr *ipv4_hdr;
+ const struct mesa_tcp_hdr *tcp_hdr;
+ int ret, len;
+ const char *pkt_raw_data;
+ unsigned int actual_data_seq;
+
+ if(a_tcp->opstate== OP_STATE_PENDING){
+ *pme = malloc(sizeof(struct test_tcp_lost ));
+ tcp_status = (struct test_tcp_lost *)*pme;
+ len = sizeof(int);
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_ISN_C2S, &tcp_status->seq_next_c2s, &len);
+ if(ret < 0){ /* not create by SYN */
+ free(*pme);
+ return APP_STATE_DROPME;
+ }
+ ret = MESA_get_stream_opt(a_tcp, MSO_TCP_ISN_S2C, &tcp_status->seq_next_s2c, &len);
+ if(ret < 0){ /* not create by SYN */
+ free(*pme);
+ return APP_STATE_DROPME;
+ }
+ tcp_status->seq_next_c2s += 1; /* plus SYN flag */
+ tcp_status->seq_next_s2c += 1; /* plus SYN flag */
+ }
+
+ tcp_status = (struct test_tcp_lost *)*pme;
+
+ if(a_tcp->ptcpdetail->lostlen > 0){
+ printf("%s lost len:%d\n", printaddr(&a_tcp->addr, a_tcp->threadnum), a_tcp->ptcpdetail->lostlen);
+ }
+
+ if(a_tcp->ptcpdetail->datalen > 0){
+ ipv4_hdr = (const struct mesa_ip4_hdr *)a_packet;
+ tcp_hdr = (const struct mesa_tcp_hdr *)((char *)ipv4_hdr + ipv4_hdr->ip_hl * 4);
+ pkt_raw_data = (char *)tcp_hdr + tcp_hdr->th_off * 4; /* ���ݰ�ԭʼ����ָ�� */
+ /* �����ش�׷�����ݵ�ԭ��, ƽ̨�����������a_tcp->ptcpdetail->pdata����һ������pkt_raw_data, �������ƫ���� */
+ actual_data_seq = ntohl(tcp_hdr->th_seq) + ((char *)a_tcp->ptcpdetail->pdata - pkt_raw_data);
+
+ printf("stream:%s, dir:%d, pkt-seq:%u, actual-data-seq:%u\n", printaddr(&a_tcp->addr, a_tcp->threadnum),a_tcp->curdir, ntohl(tcp_hdr->th_seq), actual_data_seq);
+
+ if(DIR_C2S == a_tcp->curdir){
+ /* ����ʵ����� == ���ϴμ���ó�������Ӧ�õ������ + ���μ���ó��Ķ������� */
+ if(actual_data_seq != tcp_status->seq_next_c2s + a_tcp->ptcpdetail->lostlen){
+ printf("\033[41mstream:%s, seq check fail!\033[0m\n", printaddr(&a_tcp->addr, a_tcp->threadnum));
+ //assert(0);
+ goto err_exit;
+ }
+ /* ��һ���ڴ��������: ��ǰʵ����� + ʵ�����ݳ��� */
+ tcp_status->seq_next_c2s = actual_data_seq + a_tcp->ptcpdetail->datalen;
+ }else{
+ if(actual_data_seq != tcp_status->seq_next_s2c + a_tcp->ptcpdetail->lostlen){
+ printf("\033[41mstream:%s, seq check fail!\033[0m\n", printaddr(&a_tcp->addr, a_tcp->threadnum));
+ //assert(0);
+ goto err_exit;
+ }
+ /* ��һ���ڴ��������: ��ǰʵ����� + ʵ�����ݳ��� */
+ tcp_status->seq_next_s2c = actual_data_seq + a_tcp->ptcpdetail->datalen;
+ }
+ }
+
+ if(a_tcp->opstate == OP_STATE_CLOSE){
+ printf("\033[32mstream %s check SUCC!\033[0m\n", printaddr(&a_tcp->addr, a_tcp->threadnum));
+ free(*pme);
+ }
+
+ return APP_STATE_GIVEME;
+
+err_exit:
+ free(*pme);
+ return APP_STATE_DROPME;
+}
+
+char TCP_ENTRY_ALL(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ return testtcpApp_allpkt(a_tcp,pme,thread_seq,a_packet);
+ //return test_allpkt_stream(a_tcp,pme,thread_seq,a_packet);
+}
+
+typedef struct {
+ unsigned int magic;
+ unsigned short version_major;
+ unsigned short version_minor;
+ unsigned int thiszone; /* gmt to local correction */
+ unsigned int sigfigs; /* accuracy of timestamps */
+ unsigned int snaplen; /* max length saved portion of each pkt */
+ unsigned int linktype; /* data link type (LINKTYPE_*) */
+}pcap_file_hdr_t;
+
+typedef struct {
+ unsigned int tv_sec; /* time stamp */
+ unsigned int tv_usec; /* time stamp */
+ unsigned int caplen; /* length of portion present */
+ unsigned int len; /* length this packet (off wire) */
+}pcap_pkt_hdr_t;
+
+static const pcap_file_hdr_t test_pcap_file_hdr =
+{
+ 0xA1B2C3D4,
+ 0x0002,
+ 0x0004,
+ 0,
+ 0,
+ 0xFFFF,
+ 1
+};
+
+static unsigned char test_pcap_phony_mac_hdr[14] =
+{
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x12, 0x23, 0x34, 0x56, 0x67, 0x78,
+ 0x08, 0x00
+};
+
+char TCP_ALL_DUMP_PCAP_PKT(struct streaminfo *pstream, void **pme, int thread_seq,void *a_packet)
+{
+ FILE *fp;
+ pcap_pkt_hdr_t pcap_pkt_hdr;
+ struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)a_packet;
+
+ if(OP_STATE_PENDING == pstream->pktstate){
+ char tmp_file[32];
+ snprintf(tmp_file, 32, "%p.pcap", pstream);
+ FILE *fp = fopen(tmp_file, "a+");
+ if(NULL == fp){
+ printf("fopen ./%p.pcap error!\n", tmp_file);
+ return APP_STATE_DROPME;
+ }
+ fwrite(&test_pcap_file_hdr, sizeof(pcap_file_hdr_t), 1, fp);
+ *pme = fp;
+ }else if(OP_STATE_CLOSE == pstream->pktstate){
+ fclose((FILE *)(*pme));
+ return APP_STATE_DROPME;
+ }
+
+ fp = (FILE *)(*pme);
+
+ if(a_packet){
+ pcap_pkt_hdr.caplen = ntohs(ip4hdr->ip_len) + 14;
+ pcap_pkt_hdr.len = ntohs(ip4hdr->ip_len) + 14;
+ fwrite(&pcap_pkt_hdr, sizeof(pcap_pkt_hdr_t), 1, fp);
+ fwrite(test_pcap_phony_mac_hdr, 14, 1, fp);
+ fwrite(a_packet, ntohs(ip4hdr->ip_len), 1, fp);
+ fflush(fp);
+ }
+
+ return APP_STATE_GIVEME;
+}
+char IPV4_PKT_DUMP( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ FILE *fp;
+ int iphl = a_packet->ip_hl*4;
+ int payload_len = ntohs(a_packet->ip_len) - iphl;
+
+ fp = fopen("ipv4_dump.pcap", "w+");
+
+ fwrite((char *)a_packet + iphl, payload_len, 1, fp);
+
+
+ fclose(fp);
+
+ return APP_STATE_GIVEME;
+}
+
+char IPV6_PKT_DUMP( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct mesa_ip6_hdr* a_packet)
+{
+ FILE *fp;
+ int iphl = sizeof(struct mesa_ip6_hdr);
+ int payload_len = ntohs(a_packet->ip6_payload_len);
+
+ fp = fopen("ipv6_dump.pcap", "w+");
+
+ fwrite((char *)a_packet + iphl, payload_len, 1, fp);
+
+ fclose(fp);
+
+ return APP_STATE_GIVEME;
+}
+
+char KILL_STREAM_FEEDBACK(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ char pkt_buf[1500];
+ int pkt_len = 1500;
+ int ret;
+ FILE *fp;
+ pcap_file_hdr_t pfile_hdr;
+ pcap_pkt_hdr_t pkt_hdr;
+
+ if((80 != ntohs(a_tcp->addr.ipv4->source)) && (80 != ntohs(a_tcp->addr.ipv4->dest))){
+ return APP_STATE_GIVEME;
+ }
+
+ if(a_packet != NULL){
+ ret = MESA_kill_tcp_feedback(a_tcp, a_packet, pkt_buf, &pkt_len);
+ if(1500 == pkt_len){
+ printf("MESA_kill_tcp_feedback error!\n");
+ }else{
+ memset(&pfile_hdr, 0, sizeof(pfile_hdr));
+ memset(&pkt_hdr, 0, sizeof(pkt_hdr));
+ pfile_hdr.magic = 0xA1B2C3D4;
+ pfile_hdr.version_major = 2;
+ pfile_hdr.version_minor = 4;
+ pfile_hdr.linktype = 1;
+ pfile_hdr.snaplen = 65535;
+
+ pkt_hdr.caplen = pkt_len;
+ pkt_hdr.len = pkt_len;
+
+ fp = fopen("feedback.pcap", "w+");
+ fwrite(&pfile_hdr, sizeof(pcap_file_hdr_t), 1, fp);
+ fwrite(&pkt_hdr, sizeof(pcap_pkt_hdr_t), 1, fp);
+ fwrite(pkt_buf, pkt_len, 1, fp);
+ fclose(fp);
+ }
+ }
+ return APP_STATE_GIVEME;
+}
+
+
+char KILL_STREAM_SYNACK(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ MESA_kill_tcp_synack(a_tcp, a_packet);
+ return APP_STATE_GIVEME;
+}
+
+char SLEEP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ usleep(1);
+ return APP_STATE_GIVEME;
+}
+
+char KILL_STREAM(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ if(OP_STATE_CLOSE != a_tcp->opstate){
+ MESA_kill_connection(a_tcp, a_packet);
+ }
+ return APP_STATE_GIVEME | APP_STATE_DROPPKT;
+}
+
+char KILL_STREAM_ONLY_DOU(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ if(DIR_DOUBLE == a_tcp->dir){
+ MESA_kill_tcp(a_tcp, a_packet);
+ }
+ return APP_STATE_GIVEME | APP_STATE_DROPPKT;
+}
+
+char RST_STREAM_C2S(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct rst_tcp_para rst_args = {};
+
+ rst_args.th_flags = TH_RST;
+ rst_args.rst_pkt_num = 1;
+ rst_args.dir = DIR_C2S;
+ rst_args.signature_seed1 = 65535;
+ rst_args.signature_seed2 = 13;
+
+ MESA_rst_tcp(a_tcp, &rst_args, sizeof(struct rst_tcp_para));
+
+
+ return APP_STATE_GIVEME;
+
+}
+
+char RST_STREAM_S2C(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ struct rst_tcp_para rst_args = {};
+
+ rst_args.th_flags = TH_RST;
+ rst_args.rst_pkt_num = 1;
+ rst_args.dir = DIR_S2C;
+ rst_args.signature_seed1 = 65535;
+ rst_args.signature_seed2 = 31;
+
+ MESA_rst_tcp(a_tcp, &rst_args, sizeof(struct rst_tcp_para));
+
+
+ return APP_STATE_GIVEME;
+
+}
+
+
+char RST_STREAM(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ unsigned short sport_host;
+
+ if((OP_STATE_CLOSE != a_tcp->opstate) && (DIR_DOUBLE == a_tcp->dir)){
+ sport_host = ntohs(a_tcp->addr.tuple4_v4->source);
+
+ if((sport_host >= 10000) && (sport_host <= 19999)){
+ if(DIR_C2S == a_tcp->curdir){
+ RST_STREAM_C2S(a_tcp, pme, thread_seq, a_packet); /* C2Sԭʼ������C2Sע��RST */
+ printf("inject C2S rst by raw C2S pkt\n");
+ }
+ }else if((sport_host >= 20000) && (sport_host <= 29999)){
+ if(DIR_C2S == a_tcp->curdir){
+ RST_STREAM_S2C(a_tcp, pme, thread_seq, a_packet); /* C2Sԭʼ������S2Cע��RST */
+ printf("inject S2C rst by raw C2S pkt\n");
+ }
+ }else if((sport_host >= 30000) && (sport_host <= 39999)){
+ if(DIR_S2C == a_tcp->curdir){
+ RST_STREAM_C2S(a_tcp, pme, thread_seq, a_packet); /* S2Cԭʼ������C2Sע��RST */
+ printf("inject C2S rst by raw S2C pkt\n");
+ }
+ }else if((sport_host >= 40000) && (sport_host <= 49999)){
+ if(DIR_S2C == a_tcp->curdir){
+ RST_STREAM_S2C(a_tcp, pme, thread_seq, a_packet); /* S2Cԭʼ������S2Cע��RST */
+ printf("inject S2C rst by raw S2C pkt\n");
+ }
+ }else{
+ return APP_STATE_DROPME;
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char INJECT_STREAM(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ unsigned short sport_host;
+ const char *inject_C2S_by_C2S = "sapp inject_C2S_by_C2S payload......";
+ const char *inject_S2C_by_C2S = "sapp inject_S2C_by_C2S payload......";
+ const char *inject_C2S_by_S2C = "sapp inject_C2S_by_S2C payload......";
+ const char *inject_S2C_by_S2C = "sapp inject_S2C_by_S2C payload......";
+
+ if((OP_STATE_CLOSE != a_tcp->opstate) && (DIR_DOUBLE == a_tcp->dir)){
+ sport_host = ntohs(a_tcp->addr.tuple4_v4->source);
+
+ if((sport_host >= 10000) && (sport_host <= 19999)){
+ if(DIR_C2S == a_tcp->curdir){
+ sapp_inject_pkt(a_tcp, SIO_DEFAULT, inject_C2S_by_C2S, strlen(inject_C2S_by_C2S), a_tcp->routedir); /* C2Sԭʼ������C2Sע�� */
+ printf("inject C2S pkt by raw C2S pkt\n");
+ }
+ }else if((sport_host >= 20000) && (sport_host <= 29999)){
+ if(DIR_C2S == a_tcp->curdir){
+ sapp_inject_pkt(a_tcp, SIO_DEFAULT, inject_S2C_by_C2S, strlen(inject_S2C_by_C2S), a_tcp->routedir ^ 1); /* C2Sԭʼ������S2Cע�� */
+ printf("inject S2C pkt by raw C2S pkt\n");
+ }
+ }else if((sport_host >= 30000) && (sport_host <= 39999)){
+ if(DIR_S2C == a_tcp->curdir){
+ sapp_inject_pkt(a_tcp, SIO_DEFAULT, inject_C2S_by_S2C, strlen(inject_C2S_by_S2C), a_tcp->routedir ^ 1); /* S2Cԭʼ������C2Sע�� */
+ printf("inject C2S pkt by raw S2C pkt\n");
+ }
+ }else if((sport_host >= 40000) && (sport_host <= 49999)){
+ if(DIR_S2C == a_tcp->curdir){
+ sapp_inject_pkt(a_tcp, SIO_DEFAULT, inject_S2C_by_S2C, strlen(inject_S2C_by_S2C), a_tcp->routedir); /* S2Cԭʼ������S2Cע�� */
+ printf("inject S2C pkt by raw S2C pkt\n");
+ }
+ }else{
+ return APP_STATE_DROPME;
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+
+char TEST_STREAM(struct streaminfo *stream, void **pme, int thread_seq,void *a_packet)
+{
+ const char *data;
+ int datalen;
+ static char __tmp_use[65535];
+
+ if(STREAM_TYPE_TCP == stream->type){
+ data = (const char *)stream->ptcpdetail->pdata;
+ datalen = stream->ptcpdetail->datalen;
+ }else{
+ data = (const char *)stream->pudpdetail->pdata;
+ datalen = stream->pudpdetail->datalen;
+ }
+
+ if(data){
+ assert(datalen <= 65535);
+ memcpy(__tmp_use, data, datalen);
+ memcpy(__tmp_use, stream->addr.paddr, stream->addr.addrlen);
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char KEEP_STREAM(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ return APP_STATE_GIVEME;
+}
+
+char TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet)
+{
+ //test_project_add(a_tcp,pme,thread_seq,a_packet);
+
+ testtcpApp_2(a_tcp,pme,thread_seq,a_packet);
+
+ //test_project_read_ipv4_frag_list(a_tcp,pme,thread_seq,a_packet);
+
+ return APP_STATE_GIVEME;
+}
+
+char IP_FRAG_ENTRY( struct streaminfo *stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ static int call_times = 0;
+
+ printf("ip_frag_entry, times:%d\n", ++call_times);
+
+ if(PKT_TYPE_IP_FRAG_LAST & stream->addr.pktipfragtype){
+ printf("recv last ip frag pkt!\n");
+ return APP_STATE_GIVEME | APP_STATE_DROPPKT;
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+enum anti_flood_stat_type{
+ ANTI_FLOOD_TCP_SYN = 0,
+ ANTI_FLOOD_UDP_DNS,
+ ANTI_FLOOD_UDP_NTP,
+ ANTI_FLOOD_IP_FRAG,
+};
+static unsigned long long anti_flood_stat[MAX_THREAD_NUM][8];
+static time_t last_log_time;
+//extern int g_packet_io_thread_num;
+//extern time_t g_CurrentTime;
+static void anti_flood_stat_log(void)
+{
+ FILE *fp;
+ int tseq;
+ int tot_thread_count;
+ int opt_len = sizeof(int);
+
+ sapp_get_platform_opt(SPO_THREAD_COUNT, &tot_thread_count, &opt_len);
+
+ unsigned long long tmp_anti_flood_stat[8];
+ memset(tmp_anti_flood_stat, 0, sizeof(tmp_anti_flood_stat));
+
+ for(tseq =0; tseq < tot_thread_count; tseq++){
+ tmp_anti_flood_stat[ANTI_FLOOD_TCP_SYN] += anti_flood_stat[tseq][ANTI_FLOOD_TCP_SYN];
+ tmp_anti_flood_stat[ANTI_FLOOD_UDP_DNS] += anti_flood_stat[tseq][ANTI_FLOOD_UDP_DNS];
+ tmp_anti_flood_stat[ANTI_FLOOD_UDP_NTP] += anti_flood_stat[tseq][ANTI_FLOOD_UDP_NTP];
+ tmp_anti_flood_stat[ANTI_FLOOD_IP_FRAG] += anti_flood_stat[tseq][ANTI_FLOOD_IP_FRAG];
+ }
+
+ fp = fopen("./log/anti_flood_stat.log", "w+");
+
+ fprintf(fp, "tcp_syn\t %llu\n", tmp_anti_flood_stat[ANTI_FLOOD_TCP_SYN]);
+ fprintf(fp, "udp_dns\t %llu\n", tmp_anti_flood_stat[ANTI_FLOOD_UDP_DNS]);
+ fprintf(fp, "udp_ntp\t %llu\n", tmp_anti_flood_stat[ANTI_FLOOD_UDP_NTP]);
+ fprintf(fp, "ip_frag\t %llu\n", tmp_anti_flood_stat[ANTI_FLOOD_IP_FRAG]);
+
+ fclose(fp);
+}
+
+char ANTI_FLOOD_STAT_IP_FRAG_ENTRY( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ anti_flood_stat[thread_seq][ANTI_FLOOD_IP_FRAG]++;
+ return APP_STATE_GIVEME;
+}
+
+char ANTI_FLOOD_STAT_IP_ENTRY( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ const struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)a_packet;
+ const struct mesa_tcp_hdr *tcphdr;
+ const struct mesa_udp_hdr *udphdr;
+
+ time_t cur_time;
+ int opt_len = sizeof(cur_time);
+
+ sapp_get_platform_opt(SPO_CURTIME_TIMET, &cur_time, &opt_len);
+
+ if(IPPROTO_TCP == ip4hdr->ip_p){
+ tcphdr = (const struct mesa_tcp_hdr *)((char *)a_packet + ip4hdr->ip_hl*4);
+ if(TH_SYN == tcphdr->th_flags){
+ anti_flood_stat[thread_seq][ANTI_FLOOD_TCP_SYN]++;
+ }
+ }else if(IPPROTO_UDP == ip4hdr->ip_p){
+ udphdr = (const struct mesa_udp_hdr *)((char *)a_packet + ip4hdr->ip_hl*4);
+ if(53 == ntohs(udphdr->uh_sport) || 53 == ntohs(udphdr->uh_dport)){
+ anti_flood_stat[thread_seq][ANTI_FLOOD_UDP_DNS]++;
+ }else if(123 == ntohs(udphdr->uh_sport) || 123 == ntohs(udphdr->uh_dport)){
+ anti_flood_stat[thread_seq][ANTI_FLOOD_UDP_NTP]++;
+ }
+ }
+
+ if(0 == thread_seq){
+ if(cur_time > last_log_time){
+ last_log_time = cur_time;
+ anti_flood_stat_log();
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+char IP_ENTRY( struct streaminfo *f_stream,unsigned char routedir,int thread_seq,struct ip * a_packet)
+{
+ return testIPApp_1(f_stream,routedir,thread_seq,a_packet);
+}
+
+char IPv6_ENTRY(const struct streaminfo *pstream,unsigned char routedir,int thread_seq,const void *ipv6_hdr)
+{
+ char ips[128], ipd[128];
+ const struct mesa_ip6_hdr *ip6h = (const struct mesa_ip6_hdr *)ipv6_hdr;
+
+ inet_ntop(AF_INET6, &ip6h->ip6_src, ips, 128);
+ inet_ntop(AF_INET6, &ip6h->ip6_dst, ipd, 128);
+ printf("recv ip6 pkt, %s --> %s, protocol:%u\n", ips, ipd, ip6h->ip6_nxt_hdr);
+
+ return APP_STATE_GIVEME;
+}
+
+char IPv6_RAW_ENTRY(const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt)
+{
+ printf("into IPv6_RAW_ENTRY()!\n");
+ return APP_STATE_GIVEME;
+}
+
+#endif
+
+char arp_plug_entry(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *arp_hdr)
+{
+ const struct mesa_arp_hdr *aph = (struct mesa_arp_hdr *)arp_hdr;
+ char ip4_str[32];
+
+ inet_ntop(AF_INET, aph->ar_spa, ip4_str, 32);
+
+ printf("rev arp response: ip:%s--->mac:%02x-%02x-%02x-%02x-%02x-%02x \n", ip4_str,
+ aph->ar_sha[0],aph->ar_sha[1],aph->ar_sha[2],aph->ar_sha[3],aph->ar_sha[4],aph->ar_sha[5]);
+}
+
+
+char POLLING_ENTRY(struct streaminfo *stream, void **pme, int thread_seq,void *a_packet)
+{
+ printf("polling entry, tid:%d\n", thread_seq);
+ return APP_STATE_GIVEME;
+}
+
+
+
+int CHAR_INIT()
+{
+ //test_sapp_get_device_opt("ens33");
+
+ int demo_plugid = 51;
+
+// ����ʵ���Զ���
+// ֻҪ��������ֵΪ���ID��
+
+ //stream_register_arp((SAPP_PKT_CB_FUN_T)arp_plug_entry);
+
+ return demo_plugid;
+}
+
+void CHAR_DESTROY(void)
+{
+
+}
+
+void test_funstat(unsigned long long protflag)
+{
+ ;
+}
+
+long long test_flag_change(char* flag_str)
+{
+ return 0xFFFF;
+}
+
+void test_get_plugid(unsigned short plugid)
+{
+ return;
+}
+
+
+void test_destroy(void)
+{
+ ;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+