#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int g_deliver_version_VERSION_20180718; unsigned char* g_deliver_sendbuf[MAX_THREAD_NUM]; struct deliver_comm_info g_deliver_comminfo; struct deliver_sendpkt_info g_deliver_sendinfo; struct deliver_fs2_info g_deliver_fs2info; const char *g_deliver_fs2_name[FS2_COLUMN_NUM] ={"RECV_PKTS","RECV_BYTES","SEND_PKTS","SEND_BYTES","ERROR_PKTS"}; int deliver_set_filestate2(int thread_seq,int colum_index,int value) { if(thread_seq>=g_deliver_comminfo.threadnum) { MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,"deliver_set_filestate2","thread_seq:%d,thread_num:%d",thread_seq,g_deliver_comminfo.threadnum); } g_deliver_fs2info.column_value[thread_seq][colum_index]+=value; return 0; } int deliver_filestate2_init(char* filepath) { int i=0; int trans_switch=0; int value=1; unsigned int fs2_sport; char fs2_filename[DELIVER_CONF_MAXLEN]={0}; char fs2_sip[DELIVER_CONF_MAXLEN]={0}; MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_filename",fs2_filename,DELIVER_CONF_MAXLEN,(char*)"./log/deliver_fs2.log"); MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sip",fs2_sip,DELIVER_CONF_MAXLEN,(char*)"192.168.11.241"); MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,8125); MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_trans_switch",(unsigned int*)&trans_switch,0); g_deliver_fs2info.handler=FS_create_handle(); FS_set_para(g_deliver_fs2info.handler, OUTPUT_DEVICE,fs2_filename, strlen(fs2_filename)+1); FS_set_para(g_deliver_fs2info.handler, PRINT_MODE, &value, sizeof(value)); FS_set_para(g_deliver_fs2info.handler, STAT_CYCLE, &value, sizeof(value)); FS_set_para(g_deliver_fs2info.handler, CREATE_THREAD, &value, sizeof(value)); FS_set_para(g_deliver_fs2info.handler, APP_NAME, FS2_APPNAME, strlen(FS2_APPNAME)+1); if(trans_switch==1) { FS_set_para(g_deliver_fs2info.handler, STATS_SERVER_IP, fs2_sip, strlen(fs2_sip)+1); FS_set_para(g_deliver_fs2info.handler, STATS_SERVER_PORT,&fs2_sport,sizeof(int)); } for(i=0;isession_info); struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info); struct sockaddr_in6* client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client); struct sockaddr_in6* server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server); char saddr_v6[INET6_ADDRSTRLEN ]={0}; char daddr_v6[INET6_ADDRSTRLEN ]={0}; unsigned short sport=ntohs(client_addr->sin6_port); unsigned short dport=ntohs(server_addr->sin6_port); inet_ntop(AF_INET6, (void *)&(client_addr->sin6_addr), saddr_v6, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, (void *)&(server_addr->sin6_addr), daddr_v6, INET6_ADDRSTRLEN); switch(flag) { case DELIVER_FLAG_SENDPKT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d", saddr_v6,sport,daddr_v6,dport,pkt_info->len,pkt_info->dir, pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag); break; case DELIVER_FLAG_RECVPKT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d", saddr_v6,sport,daddr_v6,dport,pkt_info->dir,recv_len); break; case DELIVER_FLAG_ENT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld", saddr_v6,sport,daddr_v6,dport,session_info->recv_pkt,session_info->recv_byte, session_info->send_pkt,session_info->recv_byte); break; } return 0; } int deliver_debug_log_v4(int level,char* module,struct deliver_pme_info* pmeinfo,int flag,int recv_len) { struct deliver_session_info* session_info=&(pmeinfo->session_info); struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info); struct sockaddr_in* client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client); struct sockaddr_in* server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server); char saddr_v4[INET_ADDRSTRLEN]={0}; char daddr_v4[INET_ADDRSTRLEN]={0}; unsigned short sport=ntohs(client_addr->sin_port); unsigned short dport=ntohs(server_addr->sin_port); inet_ntop(AF_INET, (void *)&(client_addr->sin_addr.s_addr), saddr_v4, INET_ADDRSTRLEN); inet_ntop(AF_INET, (void *)&(server_addr->sin_addr.s_addr), daddr_v4, INET_ADDRSTRLEN); switch(flag) { case DELIVER_FLAG_SENDPKT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d", saddr_v4,sport,daddr_v4,dport,pkt_info->len,pkt_info->dir, pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag); break; case DELIVER_FLAG_RECVPKT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d", saddr_v4,sport,daddr_v4,dport,pkt_info->dir,recv_len); break; case DELIVER_FLAG_ENT: MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld", saddr_v4,sport,daddr_v4,dport,session_info->recv_pkt,session_info->recv_byte, session_info->send_pkt,session_info->recv_byte); break; } return 0; } int deliver_sendpkt_ether(int thread_seq,int buflen,unsigned char* buf,unsigned char* dmac) { int ret=0; if(-1==ioctl(g_deliver_sendinfo.send_socket[thread_seq],SIOCGIFINDEX,&(g_deliver_sendinfo.ifr))) { MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"get if index error:%d,%s,name:%d",errno,strerror(errno),g_deliver_sendinfo.senddevice); return -1; } // struct sockaddr_ll addr={0}; struct sockaddr_ll addr; addr.sll_family=AF_PACKET; addr.sll_halen=ETHER_ADDR_LEN; addr.sll_ifindex=g_deliver_sendinfo.ifr.ifr_ifindex; addr.sll_protocol=htons(ETH_P_IP); memcpy(addr.sll_addr,dmac,ETHER_ADDR_LEN); if(ioctl(g_deliver_sendinfo.send_socket[thread_seq],SIOCGIFHWADDR,&(g_deliver_sendinfo.ifr))==-1) { return -1; } ret=sendto(g_deliver_sendinfo.send_socket[thread_seq],buf,buflen,0,(struct sockaddr*)&addr,sizeof(addr)); if(ret<0) { deliver_set_filestate2(thread_seq,FS2_COLUME_ERROR,1); MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_SENDPKT,"sendto() error,errno:%d,msg:%s!",errno,strerror(errno)); return ret; } deliver_set_filestate2(thread_seq,FS2_COLUME_SENDPKT,1); deliver_set_filestate2(thread_seq,FS2_COLUME_SENDBYTE,buflen-14-20-20); return ret; } int deliver_init_pmeinfo(struct origin_stream_addr* addr,void** pme) { //TODO:choose dst mac int i=deliver_rand()%(g_deliver_sendinfo.receiver_num); struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)malloc(sizeof(struct deliver_pme_info)); memset(pmeinfo,0,sizeof(struct deliver_pme_info)); memcpy((void*)&pmeinfo->addr_info,(void*)addr,sizeof(struct origin_stream_addr)); memcpy(pmeinfo->dst_macaddr,g_deliver_sendinfo.receiver_info[i].dst_macaddr,DELIVER_MACADDR_LEN); *pme=pmeinfo; return 0; } int deliver_send_v6(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,char* payload) { int offset = 0; unsigned short eth_type=0x0800; struct sockaddr_in6* client_addr=NULL; struct sockaddr_in6* server_addr=NULL; int cur_dir=pmeinfo->pkt_info.dir; struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info); if(cur_dir==DELIVER_DIR_C2S) { client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client); server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server); } else { client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server); server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client); } offset = sizeof(struct mesa_ethernet_hdr); deliver_build_tcp(ntohs(client_addr->sin6_port), ntohs(server_addr->sin6_port), curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, payload,payload_len, g_deliver_sendbuf[thread_seq]+offset+sizeof(struct mesa_ip6_hdr)); deliver_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, curpkt_info->ttl, &(client_addr->sin6_addr),&(server_addr->sin6_addr),NULL, 0, g_deliver_sendbuf[thread_seq]+offset); deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H); deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_sendinfo.src_macaddr), eth_type,NULL,0,(unsigned char*)g_deliver_sendbuf[thread_seq]); deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len, g_deliver_sendbuf[thread_seq],pmeinfo->dst_macaddr); pmeinfo->session_info.send_pkt++; pmeinfo->session_info.send_byte+=payload_len; deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0); return 0; } int deliver_send_v4(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,char* payload) { int offset = 0; unsigned short eth_type=0x0800; struct sockaddr_in* client_addr=NULL; struct sockaddr_in* server_addr=NULL; int cur_dir=pmeinfo->pkt_info.dir; struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info); if(cur_dir==DELIVER_DIR_C2S) { client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client); server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server); } else { client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server); server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client); } offset = sizeof(struct mesa_ethernet_hdr); deliver_build_tcp(ntohs(client_addr->sin_port), ntohs(server_addr->sin_port), curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0, payload,payload_len, g_deliver_sendbuf[thread_seq]+offset+sizeof(struct mesa_ip4_hdr)); deliver_build_ipv4(SENDPACKET_TCP_H+payload_len, 0, curpkt_info->ipid, 0, 64, IPPROTO_TCP, client_addr->sin_addr.s_addr,server_addr->sin_addr.s_addr, NULL, 0, g_deliver_sendbuf[thread_seq]+offset); deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H); deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_sendinfo.src_macaddr), eth_type,NULL,0,(unsigned char*)g_deliver_sendbuf[thread_seq]); deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len, g_deliver_sendbuf[thread_seq],pmeinfo->dst_macaddr); pmeinfo->session_info.send_pkt++; pmeinfo->session_info.send_byte+=payload_len; deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0); return 0; } int deliver_send_syn(int thread_seq,struct deliver_pme_info* pmeinfo) { pmeinfo->pkt_info.dir=DELIVER_DIR_C2S; pmeinfo->pkt_info.len=0; pmeinfo->pkt_info.seq= deliver_rand(); pmeinfo->pkt_info.ack=0; pmeinfo->pkt_info.flag=TH_SYN; pmeinfo->pkt_info.win = deliver_rand_range(1460, 65500); pmeinfo->pkt_info.ipid = deliver_rand() % 65535; pmeinfo->pkt_info.ttl=deliver_rand_range(32,65); if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,0,NULL); deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0); } else { deliver_send_v6(thread_seq,pmeinfo,0,NULL); deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0); } return 0; } int deliver_send_syn_ack(int thread_seq,struct deliver_pme_info* pmeinfo) { pmeinfo->pkt_info.dir=DELIVER_DIR_S2C; pmeinfo->pkt_info.len=0; pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1; pmeinfo->pkt_info.seq= deliver_rand(); pmeinfo->pkt_info.flag=TH_SYN|TH_ACK; if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,0,NULL); } else { deliver_send_v6(thread_seq,pmeinfo,0,NULL); } return 0; } int deliver_send_ack(int thread_seq,struct deliver_pme_info* pmeinfo) { unsigned int ack_tmp=pmeinfo->pkt_info.ack; pmeinfo->pkt_info.dir=DELIVER_DIR_C2S; pmeinfo->pkt_info.len=0; pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1; pmeinfo->pkt_info.seq= ack_tmp; pmeinfo->pkt_info.flag=TH_ACK; if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,0,NULL); } else { deliver_send_v6(thread_seq,pmeinfo,0,NULL); } return 0; } int deliver_set_pktinfo(struct deliver_pme_info* pmeinfo,int flag,enum tfe_conn_dir cur_dir,int payload_len) { struct deliver_pkt_info last_pkt_info; memcpy((void*)&last_pkt_info,(void*)&(pmeinfo->pkt_info),sizeof(struct deliver_pkt_info)); pmeinfo->pkt_info.dir=cur_dir; pmeinfo->pkt_info.len=payload_len; pmeinfo->pkt_info.flag=flag; if(cur_dir==last_pkt_info.dir) { pmeinfo->pkt_info.seq=last_pkt_info.seq+last_pkt_info.len; pmeinfo->pkt_info.ack=last_pkt_info.ack; } else { pmeinfo->pkt_info.seq=last_pkt_info.ack; pmeinfo->pkt_info.ack=last_pkt_info.seq+last_pkt_info.len; } return 0; } int deliver_send_rst(int thread_seq,struct deliver_pme_info* pmeinfo) { deliver_set_pktinfo(pmeinfo,TH_RST,DELIVER_DIR_C2S,0); if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,0,NULL); } else { deliver_send_v6(thread_seq,pmeinfo,0,NULL); } deliver_set_pktinfo(pmeinfo,TH_RST,DELIVER_DIR_S2C,0); if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,0,NULL); deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0); } else { deliver_send_v6(thread_seq,pmeinfo,0,NULL); deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0); } return 0; } int mirror_stream_open(int thread_seq,struct origin_stream_addr* addr,void** pme) { struct deliver_pme_info* pmeinfo=NULL; deliver_init_pmeinfo(addr,pme); pmeinfo=(struct deliver_pme_info*)*pme; deliver_send_syn(thread_seq,pmeinfo); deliver_send_syn_ack(thread_seq,pmeinfo); deliver_send_ack(thread_seq,pmeinfo); return 0; } int mirror_stream_write(enum tfe_conn_dir cur_dir,const unsigned char * data, size_t len, void** pme,int thread_seq) { int i=0; char* payload=data; int payload_len=0; int remain_len=len; int pkt_num=(len/(g_deliver_sendinfo.mtu))+1; struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme; deliver_set_filestate2(thread_seq,FS2_COLUME_RECVPKT,1); deliver_set_filestate2(thread_seq,FS2_COLUME_RECVBYTE,len); pmeinfo->session_info.recv_pkt++; pmeinfo->session_info.recv_byte+=len; if(pmeinfo->addr_info.client.sa_family==AF_INET) { deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,len); } else { deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,len); } for(i=0;iaddr_info.client.sa_family==AF_INET) { deliver_send_v4(thread_seq,pmeinfo,payload_len,payload); } else { deliver_send_v6(thread_seq,pmeinfo,payload_len,payload); } } return 0; } void mirror_stream_close(void** pme, int thread_id) { struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme; deliver_send_rst(thread_id,pmeinfo); if(*pme!=NULL) { free(*pme); *pme=NULL; } return; } int deliver_device_init() { char* if_name=g_deliver_sendinfo.senddevice; //init socket size_t ifname_len=strlen(if_name); if(ifname_len