From ab2f1bfa932f655e57032a4e7556db55e38bfda9 Mon Sep 17 00:00:00 2001 From: wangyu Date: Tue, 11 Jul 2017 18:01:11 +0800 Subject: [PATCH] 7.11 commit --- LICENSE.md | 21 ++ main.cpp | 940 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 961 insertions(+) create mode 100644 LICENSE.md create mode 100644 main.cpp diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6e53158 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Yu Wang (wangyucn at gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..103afc2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,940 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include"aes.h" + +#include +#include + +#include +#include +#include + + +#include //for socket ofcourse +#include +#include //for exit(0); +#include //For errno - the error number +#include //Provides declarations for tcp header +#include //Provides declarations for ip header +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; + +char local_address[100], remote_address[100],source_address[100]; +int local_port = -1, remote_port = -1,source_port; + +const int buf_len = 20480; + +const int server_mode=2; +const int client_mode=1; +int prog_mode=0; //0 unset; 1client 2server +const int RETRY_TIME=3; + +void handler(int num) { + int status; + int pid; + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + if (WIFEXITED(status)) { + //printf("The child exit with code %d",WEXITSTATUS(status)); + } + } +} + +void setnonblocking(int sock) { + int opts; + opts = fcntl(sock, F_GETFL); + + if (opts < 0) { + perror("fcntl(sock,GETFL)"); + exit(1); + } + opts = opts | O_NONBLOCK; + if (fcntl(sock, F_SETFL, opts) < 0) { + perror("fcntl(sock,SETFL,opts)"); + exit(1); + } + +} + +int udp_fd; +int raw_recv_fd; +int raw_send_fd; +int init_raw_socket() +{ + raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); + if(raw_send_fd == -1) { + perror("Failed to create raw_send_fd"); + exit(1); + } + //raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); + + raw_recv_fd= socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); + //raw_fd=socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP)); + // packet_recv_sd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); + if(raw_recv_fd == -1) { + //socket creation failed, may be because of non-root privileges + perror("Failed to create raw_recv_fd"); + exit(1); + } + + //IP_HDRINCL to tell the kernel that headers are included in the packet + + int one = 1; + const int *val = &one; + if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { + perror("Error setting IP_HDRINCL"); + exit(2); + } + return 0; +} +char buf[buf_len]; +char buf2[buf_len]; +char raw_send_buf[buf_len]; +char raw_send_buf2[buf_len]; +struct sock_filter code[] = { + { 0x28, 0, 0, 0x0000000c },//0 + { 0x15, 0, 10, 0x00000800 },//1 + { 0x30, 0, 0, 0x00000017 },//2 + { 0x15, 0, 8, 0x00000006 },//3 + { 0x28, 0, 0, 0x00000014 },//4 + { 0x45, 6, 0, 0x00001fff },//5 + { 0xb1, 0, 0, 0x0000000e },//6 + { 0x48, 0, 0, 0x0000000e },//7 + { 0x15, 2, 0, 0x0000ef32 },//8 + { 0x48, 0, 0, 0x00000010 },//9 + { 0x15, 0, 1, 0x0000ef32 },//10 + { 0x6, 0, 0, 0x0000ffff },//11 + { 0x6, 0, 0, 0x00000000 },//12 +}; +sock_fprog bpf; +long long get_current_time() +{ + timespec tmp_time; + clock_gettime(CLOCK_MONOTONIC, &tmp_time); + return tmp_time.tv_sec*1000+tmp_time.tv_nsec/(1000*1000ll); +} +void init_filter(int port) +{ + code[8].k=code[10].k=port; + bpf.len = sizeof(code)/sizeof(code[0]); + bpf.filter = code; + //printf("<%d>\n",bpf.len); + int ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); + memset(code,0,sizeof(code)); + if (ret != 0) + { + printf("error set fiter\n"); + exit(-1); + } +} +void process_arg(int argc, char *argv[]) +{ + int i,j,k,opt; + static struct option long_options[] = + { + /* These options set a flag. */ + {"source", required_argument, 0, 1}, + }; + int option_index = 0; + printf("argc=%d ", argc); + for (i = 0; i < argc; i++) + printf("%s ", argv[i]); + printf("\n"); + + if (argc == 1) + { + printf( + "proc -l [adress:]port -r [adress:]port [-a passwd] [-b passwd]\n"); + exit(-1); + } + + int no_l = 1, no_r = 1; + while ((opt = getopt_long(argc, argv, "l:r:sch",long_options,&option_index)) != -1) { + //string opt_key; + //opt_key+=opt; + switch (opt) { + case 'l': + no_l = 0; + if (strchr(optarg, ':') != 0) { + sscanf(optarg, "%[^:]:%d", local_address, &local_port); + } else { + strcpy(local_address, "127.0.0.1"); + sscanf(optarg, "%d", &local_port); + } + break; + case 'r': + no_r = 0; + if (strchr(optarg, ':') != 0) { + sscanf(optarg, "%[^:]:%d", remote_address, &remote_port); + } else { + strcpy(remote_address, "127.0.0.1"); + sscanf(optarg, "%d", &remote_port); + } + break; + case 's': + if(prog_mode==0) + { + prog_mode=server_mode; + } + else + { + printf("-s /-c has already been set,-s option conflict"); + exit(-1); + } + break; + case 'c': + if(prog_mode==0) + { + prog_mode=client_mode; + } + else + { + printf("-s /-c has already been set,-c option conflict"); + exit(-1); + } + break; + case 'h': + break; + case 1: + if (strchr(optarg, ':') != 0) { + sscanf(optarg, "%[^:]:%d", source_address, &source_port); + printf("source: %s:%d",source_address,&source_port); + } else { + printf("format --source ip:adress"); + exit(-1); + } + break; + + default: + printf("ignore unknown <%s>", optopt); + } + } + + if (no_l) + printf("error: -i not found\n"); + if (no_r) + printf("error: -o not found\n"); + if(prog_mode==0) + printf("error: -s /-r hasnt been set\n"); + if (no_l || no_r||prog_mode==0) + { + exit(-1); + } +} + +int recv_raw() +{ +} +struct packet_info_t +{ + //ip_part: + uint32_t src_ip; + uint16_t src_port; + uint32_t dst_ip; + uint16_t dst_port; + + //tcp_part: + bool syn,ack,psh; + uint32_t seq,ack_seq; + + +}g_packet_info; + +struct pseudo_header { + u_int32_t source_address; + u_int32_t dest_address; + u_int8_t placeholder; + u_int8_t protocol; + u_int16_t tcp_length; +}; +/* + Generic checksum calculation function +*/ +unsigned short csum(unsigned short *ptr,int nbytes) { + register long sum; + unsigned short oddbyte; + register short answer; + + sum=0; + while(nbytes>1) { + sum+=*ptr++; + nbytes-=2; + } + if(nbytes==1) { + oddbyte=0; + *((u_char*)&oddbyte)=*(u_char*)ptr; + sum+=oddbyte; + } + + sum = (sum>>16)+(sum & 0xffff); + sum = sum + (sum>>16); + answer=(short)~sum; + + return(answer); +} + +int send_raw(packet_info_t &info,char * payload,int payloadlen) +{ + char *data; + + memset(raw_send_buf,0,payloadlen+100); + + struct iphdr *iph = (struct iphdr *) raw_send_buf; + + //TCP header + struct tcphdr *tcph = (struct tcphdr *) (raw_send_buf + sizeof (struct ip)); + struct sockaddr_in sin; + struct pseudo_header psh; + + //Data part + data = raw_send_buf + sizeof(struct iphdr) + sizeof(struct tcphdr); + + memcpy(data , payload, payloadlen); + + //some address resolution + sin.sin_family = AF_INET; + sin.sin_port = htons(info.dst_port); + sin.sin_addr.s_addr = info.dst_ip; + + //Fill in the IP Header + iph->ihl = 5; + iph->version = 4; + iph->tos = 0; + iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + payloadlen; + iph->id = htonl (54321); //Id of this packet + iph->frag_off = 0; + iph->ttl = 255; + iph->protocol = IPPROTO_TCP; + iph->check = 0; //Set to 0 before calculating checksum + iph->saddr = info.src_ip; //Spoof the source ip address + iph->daddr = info.dst_ip; + + //TCP Header + tcph->source = htons(info.src_port); + tcph->dest = htons(info.dst_port); + + tcph->seq =htonl(info.seq); + tcph->ack_seq = htonl(info.ack); + + tcph->doff = 5; //tcp header size + tcph->fin=0; + tcph->syn=info.syn; + tcph->rst=0; + tcph->psh=info.psh; + tcph->ack=info.ack; + + tcph->urg=0; + tcph->window = htons((uint16_t)129600); + tcph->check = 0; //leave checksum 0 now, filled later by pseudo header + tcph->urg_ptr = 0; + + psh.source_address = info.src_ip; + psh.dest_address = sin.sin_addr.s_addr; + psh.placeholder = 0; + psh.protocol = IPPROTO_TCP; + psh.tcp_length = htons(sizeof(struct tcphdr) + payloadlen ); + + int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + payloadlen; + + memcpy(raw_send_buf2 , (char*) &psh , sizeof (struct pseudo_header)); + memcpy(raw_send_buf2 + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + payloadlen); + + tcph->check = csum( (unsigned short*) raw_send_buf2, psize); + + //Ip checksum + iph->check = csum ((unsigned short *) raw_send_buf, iph->tot_len); + + int ret = sendto(raw_send_fd, raw_send_buf, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin)); + printf("\n",ret); + if(ret<0) + { + + perror("raw send error"); + //printf("send error\n"); + } + return 0; +} +int send_sync() +{ + g_packet_info.seq=0; + g_packet_info.ack=0; + g_packet_info.syn=1; + g_packet_info.ack_seq=0; + g_packet_info.psh=0; + send_raw(g_packet_info,0,0); + return 0; +} +const int client_nothing=0; +const int client_syn_sent=1; +const int client_ack_sent=2; +const int client_ready=3; +int client_current_state=client_nothing; +int retry_counter; + +long long last_state_time; +uint32_t session_id; + +uint32_t get_true_random_number() +{ + uint32_t ret; + int fd=open("/dev/urandom",O_RDONLY); + read(fd,&ret,sizeof(ret)); + return htonl(ret); +} +const int server_nothing=0; +const int server_syn_ack_sent=1; +const int server_heartbeat_sent=2; +const int server_ready=3; +int server_current_state=server_nothing; +long long last_hb_recv_time; +int fake_tcp_keep_connection_client() //for client +{ + //printf("timer!"); + //fflush(stdout); + begin: + if(client_current_state==client_nothing) + { + send_sync(/*sync*/);//send sync + client_current_state=client_syn_sent; + last_state_time=get_current_time(); + printf("state changed from nothing to syn_sent\n"); + retry_counter=RETRY_TIME; + + } + if(client_current_state==client_syn_sent &&get_current_time()-last_state_time>1000ll) + { + if(retry_counter==0) + { + client_current_state=client_nothing; + goto begin; + } + else + { + retry_counter--; + printf("retry send sync\n"); + send_sync(/*sync*/);//send sync again + last_state_time=get_current_time(); + } + } + if(client_current_state==client_ack_sent &&get_current_time()-last_state_time>1000) + { + printf("!!!!!\n"); + fflush(stdout); + if(retry_counter==0) + { + client_current_state=client_nothing; + goto begin; + } + else + { + retry_counter--; + send_raw(g_packet_info,0,0); + last_state_time=get_current_time(); + printf("retry send ack counter left:%d\n",retry_counter); + fflush(stdout); + } + } + + if(client_current_state==client_ready) + { + printf("time %lld %lld\n",get_current_time(),last_state_time); + if(get_current_time()-last_hb_recv_time>5*1000ll) + { + client_current_state=client_nothing; + return 0; + } + g_packet_info.syn=0; + g_packet_info.ack=1; + printf("heartbeat sent\n"); + send_raw(g_packet_info,"hb",strlen("hb")); + //last_time=get_current_time(); + } + +} + +int fake_tcp_keep_connection_server() +{ + //begin: + printf("timerxxxx!\n"); + fflush(stdout); + if(server_current_state==server_nothing) + { + return 0; + } + if(server_current_state==server_syn_ack_sent &&get_current_time()-last_state_time>1000ll ) + { + if(retry_counter==0) + { + server_current_state=server_nothing; + //send_raw(g_packet_info,0,0); + } + else + { + retry_counter--; + send_raw(g_packet_info,0,0); + last_state_time=get_current_time(); + printf("resend syn ack\n"); + } + //send_raw(/*syn ack*/); + } + if(server_current_state==server_heartbeat_sent||server_current_state==server_ready) + { + if(get_current_time()-last_hb_recv_time>5*1000ll) + { + printf("%lld %lld",get_current_time(),last_state_time); + server_current_state=server_nothing; + printf("changed state to server_nothing111\n"); + return 0; + } + + g_packet_info.syn=0; + g_packet_info.ack=1; + g_packet_info.psh=1; + send_raw(g_packet_info,"hb",strlen("hb")); + //last_time=get_current_time(); + printf("heart beat sent,fffff\n"); + fflush(stdout); + } + +} +struct sockaddr_in udp_old_addr_in; + + + +int set_timer(int epollfd,int &timer_fd) +{ + int ret; + epoll_event ev; + + itimerspec its; + memset(&its,0,sizeof(its)); + + if((timer_fd=timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK)) < 0) + { + printf("timer_fd create error"); + exit(1); + } + its.it_interval.tv_sec=1; + its.it_value.tv_sec=1; + timerfd_settime(timer_fd,0,&its,0); + + + ev.events = EPOLLIN; + ev.data.fd = timer_fd; + + epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev); + if (ret < 0) { + printf("epoll_ctl return %d\n", ret); + exit(-1); + } +} + +const int MTU=1440; +int client_recv(iphdr * iph,tcphdr *tcph,char * data,int data_len) +{ + + if(client_current_state==client_syn_sent ) + { + if (!(tcph->syn==1&&tcph->ack==1)) return 0; + if(iph->saddr!=g_packet_info.dst_ip||ntohs(tcph->source)!=g_packet_info.dst_port) + { + printf("unexpected adress %d %d %d %d\n",iph->saddr,g_packet_info.dst_ip,ntohl(tcph->source),g_packet_info.dst_port); + return 0; + } + + g_packet_info.ack_seq=ntohl(tcph->ack_seq)+1; + g_packet_info.psh=0; + g_packet_info.syn=0; + g_packet_info.ack=1; + g_packet_info.seq+=1; + + printf("sent ack back\n"); + fflush(stdout); + send_raw(g_packet_info,0,0); + client_current_state=client_ack_sent; + printf("changed state to client_ack_sent\n"); + last_state_time=get_current_time(); + retry_counter=RETRY_TIME; + } + if(client_current_state==client_ack_sent ) + { + //printf(" i m here\n"); + //fflush(stdout); + if( tcph->syn==1||tcph->ack!=1 ) + { + printf("unexpected syn ack"); + return 0; + } + if(iph->saddr!=g_packet_info.dst_ip||ntohs(tcph->source)!=g_packet_info.dst_port) + { + printf("unexpected adress\n"); + return 0; + } + client_current_state=client_ready; + printf("changed state to client_ready\n"); + //send_raw(g_packet_info,"hb",strlen("hb")); + } + if(client_current_state==client_ready ) + { + printf("heart beat received\n"); + last_hb_recv_time=get_current_time(); + } +} +int send_heart_beat(packet_info_t &info) +{ + +} +int server_recv(iphdr * iph,tcphdr *tcph,char * data,int data_len) +{ + if(server_current_state==server_nothing) + { + if(!( tcph->syn==1&&tcph->ack==0 )) return 0; + + g_packet_info.dst_port=ntohs(tcph->source); + g_packet_info.dst_ip=iph->saddr; + + g_packet_info.ack_seq=ntohl(tcph->ack_seq)+1; + g_packet_info.psh=0; + g_packet_info.syn=1; + g_packet_info.ack=1; + g_packet_info.seq;//dont need to set + printf("sent syn ack\n"); + fflush(stdout); + send_raw(g_packet_info,0,0); + server_current_state=server_syn_ack_sent; + printf("changed state to server_syn_ack_sent\n"); + retry_counter=RETRY_TIME; + last_state_time=get_current_time(); + } + else if(server_current_state==server_syn_ack_sent) + { + if(!( tcph->syn==0&&tcph->ack==1 )) return 0; + + + server_current_state=server_heartbeat_sent; + g_packet_info.syn=0; + g_packet_info.ack=1; + + send_raw(g_packet_info,"hb",strlen("hb")); + printf("changed state to server_heartbeat_sent\n"); + + last_hb_recv_time=get_current_time(); //this ack is counted as hearbeat + last_state_time=get_current_time(); + } + else if(server_current_state==server_heartbeat_sent)//heart beat received + { + if( tcph->syn==1||tcph->ack!=1 ) return 0; + if(iph->saddr!=g_packet_info.dst_ip||ntohs(tcph->source)!=g_packet_info.dst_port) + { + printf("unexpected adress\n"); + return 0; + } + server_current_state=server_ready; + last_state_time=get_current_time(); + last_hb_recv_time=get_current_time(); + printf("changed state to server_ready\n"); + + } + else if(server_current_state==server_ready) + { + if( tcph->syn==1||tcph->ack!=1 ) return 0; + if(iph->saddr!=g_packet_info.dst_ip||ntohs(tcph->source)!=g_packet_info.dst_port) + { + printf("unexpected adress\n"); + return 0; + } + printf("heart beat received\n"); + last_hb_recv_time=get_current_time(); + } +} + + +int on_raw_recv() +{ + int size; + struct sockaddr saddr; + socklen_t saddr_size; + saddr_size = sizeof(saddr); + + printf("raw!\n"); + fflush(stdout); + + size = recvfrom(raw_recv_fd, buf, buf_len, 0 ,&saddr , &saddr_size); + + char *ip_data=buf+14; + + struct iphdr *iph = (struct iphdr *) (ip_data); + + + if (!(iph->ihl > 0 && iph->ihl < (MTU)/4)) { + printf("iph ihl error"); + fflush(stdout); + return 0; + } + + if (iph->protocol != IPPROTO_TCP) { + printf("iph protocal != tcp\n"); + fflush(stdout); + return 0; + } + + + int ip_len=ntohs(iph->tot_len); + + unsigned short iphdrlen =iph->ihl*4; + struct tcphdr *tcph=(struct tcphdr*)(ip_data+ iphdrlen); + unsigned short tcphdrlen = tcph->doff*4; + + if (!(tcph->doff > 0 && tcph->doff < (MTU - iphdrlen)/4)) { + printf("tcph error"); + fflush(stdout); + return 0; + } + + int data_len = ip_len-tcphdrlen-iphdrlen; + + char *data=ip_data+tcphdrlen+iphdrlen; + + //printf("%d\n",ip_len); + /* + for(int i=0;i",(unsigned char)buf[i]); + + } + printf("\n"); + + for(int i=0;i",(unsigned char)data[i]); + }*/ + + printf("\n"); + printf("<%u,%u,%u,%u,%d>\n",(unsigned int)iphdrlen,(unsigned int)tcphdrlen,(unsigned int)tcph->syn,(unsigned int)tcph->ack,data_len); + fflush(stdout); + + if(prog_mode==server_mode) + { + server_recv(iph,tcph,data,data_len); + } + else + { + client_recv(iph,tcph,data,data_len); + } + return 0; +} +int client() +{ + int i, j, k;int ret; + init_raw_socket(); + session_id=get_true_random_number(); + + init_filter(source_port); + g_packet_info.dst_ip=inet_addr(remote_address); + g_packet_info.dst_port=remote_port; + + g_packet_info.src_ip=inet_addr(source_address); + g_packet_info.src_port=source_port; + + int udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + int yes = 1; + //setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); + + struct sockaddr_in local_me; + + socklen_t slen = sizeof(sockaddr_in); + memset(&local_me, 0, sizeof(local_me)); + local_me.sin_family = AF_INET; + local_me.sin_port = htons(local_port); + local_me.sin_addr.s_addr = inet_addr(local_address); + if (bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) { + perror("socket bind error"); + exit(1); + } + setnonblocking(udp_fd); + int epollfd = epoll_create1(0); + const int max_events = 4096; + struct epoll_event ev, events[max_events]; + if (epollfd < 0) { + printf("epoll return %d\n", epollfd); + exit(-1); + } + ev.events = EPOLLIN; + ev.data.fd = udp_fd; + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, udp_fd, &ev); + if (ret!=0) { + printf("add udp_listen_fd error\n"); + exit(-1); + } + ev.events = EPOLLIN; + ev.data.fd = raw_recv_fd; + + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); + if (ret!= 0) { + printf("add raw_fd error\n"); + exit(-1); + } + + ////add_timer for fake_tcp_keep_connection_client + + //sleep(10); + + memset(&udp_old_addr_in,0,sizeof(sockaddr_in)); + int unbind=1; + int timer_fd; + + set_timer(epollfd,timer_fd); + while(1)//////////////////////// + { + int nfds = epoll_wait(epollfd, events, max_events, 180 * 1000); + if (nfds < 0) { //allow zero + printf("epoll_wait return %d\n", nfds); + exit(-1); + } + int n; + for (n = 0; n < nfds; ++n) { + if (events[n].data.fd == raw_recv_fd) + { + on_raw_recv(); + /*if(is_sync_ack) + { + + } + else if(is heart_beat) + { + + } + else if(is_data) + { + sendto(); + }*/ + } + if(events[n].data.fd ==timer_fd) + { + //printf("timer!\n"); + //fflush(stdout); + uint64_t value; + read(timer_fd, &value, 8); + fake_tcp_keep_connection_client(); + } + if (events[n].data.fd == udp_fd) + { + socklen_t recv_len; + struct sockaddr_in udp_new_addr_in; + if ((recv_len = recvfrom(udp_fd, buf, buf_len, 0, + (struct sockaddr *) &udp_new_addr_in, &slen)) == -1) { + printf("recv_from error"); + exit(1); + } + printf("Received packet from %s:%d\n", inet_ntoa(udp_new_addr_in.sin_addr), + ntohs(udp_new_addr_in.sin_port)); + fflush(stdout); + if(udp_old_addr_in.sin_addr.s_addr==0&&udp_old_addr_in.sin_port==0) + { + memcpy(&udp_old_addr_in,&udp_new_addr_in,sizeof(udp_new_addr_in)); + } + else if(udp_new_addr_in.sin_addr.s_addr!=udp_old_addr_in.sin_addr.s_addr + ||udp_new_addr_in.sin_port!=udp_old_addr_in.sin_port) + { + printf("new connected in,ignore\n"); + fflush(stdout); + continue; + } + ////send_data_raw(buf,recv_len); + } + } + } + return 0; +} +int server() +{ + int i, j, k;int ret; + init_raw_socket(); + init_filter(local_port); + int epollfd = epoll_create1(0); + const int max_events = 4096; + + g_packet_info.src_ip=inet_addr(local_address); + g_packet_info.src_port=local_port; + + struct epoll_event ev, events[max_events]; + if (epollfd < 0) { + printf("epoll return %d\n", epollfd); + exit(-1); + } + + ev.events = EPOLLIN; + ev.data.fd = raw_recv_fd; + + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); + if (ret!= 0) { + printf("add raw_fd error\n"); + exit(-1); + } + int timer_fd; + set_timer(epollfd,timer_fd); + while(1)//////////////////////// + { + int nfds = epoll_wait(epollfd, events, max_events, 180 * 1000); + if (nfds < 0) { //allow zero + printf("epoll_wait return %d\n", nfds); + exit(-1); + } + int n; + const int MTU=1440; + for (n = 0; n < nfds; ++n) + { + printf("%d %d %d %d\n",timer_fd,raw_recv_fd,raw_send_fd,n); + if (events[n].data.fd == timer_fd) + { + uint64_t value; + read(timer_fd, &value, 8); + fake_tcp_keep_connection_server(); + } + if (events[n].data.fd == raw_recv_fd) + { + on_raw_recv(); + } + } + } + return 0; +} +int main(int argc, char *argv[]) +{ + int i, j, k; + + signal(SIGCHLD, handler); + process_arg(argc,argv); + + if(prog_mode==client_mode) + { + client(); + } + else + { + server(); + } + + return 0; +}