Last active
December 9, 2015 11:41
-
-
Save wrfly/a55b11926e230e05a9a6 to your computer and use it in GitHub Desktop.
linux lcx version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/time.h> | |
#include <signal.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <netdb.h> | |
#define VERSION "2.3" | |
#define TIMEOUT 300 | |
#define max(a,b) (a)>(b)?(a):(b) | |
#define MAXSIZE 10240 | |
#define HOSTLEN 40 | |
#define CONNECT_NUMBER 5 | |
/* define function here */ | |
void usage(char *s); | |
void transdata(int fd1,int fd2); | |
void closeallfd(int); | |
void makelog(char *buffer,int length); | |
int testifisvalue(char *str); | |
int bind2conn(int port1,char *host,int port2); | |
int bind2bind(int port1,int port2); | |
int conn2conn(char *host1,int port1,char *host2,int port2); | |
int create_socket(); | |
int create_serv(int sockfd,int port); | |
int client_connect(int sockfd,char* server,int port); | |
/* define GLOBAL varible here */ | |
extern int errno; | |
FILE *fp; | |
int main(int argc,char **argv) | |
{ | |
char **p; | |
char host1[HOSTLEN],host2[HOSTLEN]; | |
int port1=0,port2=0,method=0; | |
int length; | |
char *logfile=NULL; | |
p=argv; | |
memset(host1,0,HOSTLEN); | |
memset(host2,0,HOSTLEN); | |
while(*p) | |
{ | |
if(strcmp(*p,"-v")==0) | |
{ | |
printf("Socket data transport tool.\nVersion:%s\n",VERSION); | |
p++; | |
continue; | |
} | |
if(strcmp(*p,"-m1")==0) | |
{ | |
method=1; | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//host2 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
printf("as\n"); | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host2,*(++p),length); | |
} | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
p++; | |
continue; | |
} | |
if(strcmp(*p,"-m2")==0) | |
{ | |
method=2; | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
p++; | |
continue; | |
} | |
if(strcmp(*p,"-m3")==0) | |
{ | |
method=3; | |
//host1 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host1,*(++p),length); | |
} | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//host2 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host2,*(++p),length); | |
} | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
p++; | |
continue; | |
} | |
if(strcmp(*p,"-m")==0) | |
{ | |
if(testifisvalue(*(p+1))==1) | |
method=atoi(*(++p)); | |
switch(method){ | |
case 1: | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//host2 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host2,*(++p),length); | |
} | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
break; | |
case 2: | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
break; | |
case 3: | |
//host1 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host1,*(++p),length); | |
} | |
//port1 | |
if(testifisvalue(*(p+1))==1) | |
port1=atoi(*(++p)); | |
//host2 | |
if(testifisvalue(*(p+1))==1) | |
{ | |
length=(strlen(*(p+1))>HOSTLEN-1)?HOSTLEN-1:strlen(*(p+1)); | |
strncpy(host2,*(++p),length); | |
} | |
//port2 | |
if(testifisvalue(*(p+1))==1) | |
port2=atoi(*(++p)); | |
p++; | |
break; | |
default: | |
printf("[ERROR]: Method not allowed.\n"); | |
return 0; | |
} | |
continue; | |
} | |
if(strcmp(*p,"-log")==0) | |
{ | |
if(testifisvalue(*(p+1))==1) | |
logfile=*(++p); | |
else | |
{ | |
printf("[ERROR] Must supply logfile name\n"); | |
exit(0); | |
} | |
p++; | |
continue; | |
} | |
p++; | |
} | |
signal(SIGCLD,SIG_IGN); | |
signal(SIGINT,&closeallfd); | |
if(logfile !=NULL) | |
{ | |
fp=fopen(logfile,"a"); | |
if(fp == NULL ) | |
{ | |
perror("Open logfile"); | |
exit(0); | |
} | |
} | |
makelog("############### Log Starting ###############\n",49); | |
switch(method) | |
{ | |
case 0: | |
usage(argv[0]); | |
break; | |
case 1: | |
if((port1==0) || (port2==0) || (strlen(host2)==0)) | |
{ | |
printf("[ERROR]: lcx -m1 PORT1 HOST2 PORT2.\n"); | |
break; | |
} | |
bind2conn(port1,host2,port2); | |
break; | |
case 2: | |
if((port1==0) || (port2==0)) | |
{ | |
printf("[ERROR]:lcx -m2 PORT1 PORT2.\n"); | |
break; | |
} | |
bind2bind(port1,port2); | |
break; | |
case 3: | |
if((port1==0) || (port2==0) || (strlen(host1)==0) || (strlen(host2)==0)) | |
{ | |
printf("[ERROR]:lcx -m3 HOST1 PORT1 HOST2 PORT2.\n"); | |
break; | |
} | |
conn2conn(host1,port1,host2,port2); | |
break; | |
default: | |
usage(argv[0]); | |
} | |
closeallfd(0); | |
} | |
int testifisvalue(char *str) | |
{ | |
if(str == NULL ) return(0); | |
if(str[0]=='-') return(0); | |
return(1); | |
} | |
void usage(char *s) | |
{ | |
// printf("Socket data transport tool\n"); | |
// printf("Created by bkbll([email protected])\n"); | |
// printf("Modified by wrfly([email protected])\n\n"); | |
printf("Usage:%s -m method [host1] port1 [host2] port2 [-v] [-log filename]\n",s); | |
printf(" -v: version\n"); | |
printf(" -m1: PORT1 HOST2 PORT2\n"); | |
printf(" -m2: PORT1 PORT2\n"); | |
printf(" -m3: HOST1 PORT1 HOST2 PORT2\n"); | |
printf(" -log: log the data\n"); | |
printf("For methods:\n"); | |
printf(" -m1: listen on PORT1 and connect to HOST2:PORT2\n"); | |
printf(" -m2: listen on PORT1 and PORT2\n"); | |
printf(" -m3: connect to HOST1:PORT1 and HOST2:PORT2\n"); | |
closeallfd(0); | |
} | |
int bind2conn(int port1,char *host,int port2) | |
{ | |
int sockfd,sockfd1,sockfd2; | |
struct sockaddr_in remote; | |
int size; | |
int pid; | |
char buffer[1024]; | |
memset(buffer,0,1024); | |
if((sockfd=create_socket())==0) exit(0); | |
if(create_serv(sockfd,port1)==0) | |
{ | |
close(sockfd1); | |
exit(0); | |
} | |
size=sizeof(struct sockaddr); | |
while(1) | |
{ | |
printf("[+] Waiting for a response...\n"); | |
if((sockfd1=accept(sockfd,(struct sockaddr *)&remote,(socklen_t *)&size))<0) | |
{ | |
perror("[-] Accept error\n"); | |
continue; | |
} | |
printf("[-] Accept a client from %s:%d\n",inet_ntoa(remote.sin_addr),ntohs(remote.sin_port)); | |
if((sockfd2=create_socket())==0) | |
{ | |
close(sockfd1); | |
continue; | |
} | |
printf("[+] Making a connection to %s:%d...",host,port2); | |
fflush(stdout); | |
if(client_connect(sockfd2,host,port2)==0) | |
{ | |
close(sockfd2); | |
sprintf(buffer,"[SERVER] Connection to %s:%d error\n",host,port2); | |
write(sockfd1,buffer,strlen(buffer)); | |
memset(buffer,0,1024); | |
close(sockfd1); | |
continue; | |
} | |
printf("ok\n"); | |
pid=fork(); | |
if(pid==0) transdata(sockfd1,sockfd2); | |
// sleep(2); | |
close(sockfd1); | |
close(sockfd2); | |
} | |
} | |
int bind2bind(int port1,int port2) | |
{ | |
int fd1,fd2,sockfd1,sockfd2; | |
struct sockaddr_in client1,client2; | |
int size1,size2; | |
int pid; | |
if((fd1=create_socket())==0) exit(0); | |
if((fd2=create_socket())==0) exit(0); | |
printf("[+] Listening port %d...\n",port1); | |
fflush(stdout); | |
if(create_serv(fd1,port1)==0) | |
{ | |
close(fd1); | |
exit(0); | |
} | |
printf("[+] Listen OK!\n"); | |
printf("[+] Listening port %d...\n",port2); | |
fflush(stdout); | |
if(create_serv(fd2,port2)==0) | |
{ | |
close(fd2); | |
exit(0); | |
} | |
printf("[+] Listen OK!\n"); | |
size1=size2=sizeof(struct sockaddr); | |
while(1) | |
{ | |
printf("[+] Waiting for Client on port:%d...\n",port1); | |
if((sockfd1=accept(fd1,(struct sockaddr *)&client1,(socklen_t *)&size1))<0) | |
{ | |
perror("[-] Accept1 error."); | |
continue; | |
} | |
printf("[+] Accept a Client on port %d from %s,\n[+] Waiting another Client on port:%d...\n",port1,inet_ntoa(client1.sin_addr),port2); | |
if((sockfd2=accept(fd2,(struct sockaddr *)&client2,(socklen_t *)&size2))<0) | |
{ | |
perror("[-] Accept2 error.\n"); | |
close(sockfd1); | |
continue; | |
} | |
printf("[+] Accept a client on port %d from %s\n",port2,inet_ntoa(client2.sin_addr)); | |
pid=fork(); | |
if(pid==0) transdata(sockfd1,sockfd2); | |
//sleep(2); | |
close(sockfd1); | |
close(sockfd2); | |
} | |
} | |
int conn2conn(char *host1,int port1,char *host2,int port2) | |
{ | |
int sockfd1,sockfd2; | |
int pid; | |
fd_set fds; | |
int l; | |
int result; | |
char buffer[MAXSIZE]; | |
while(1) | |
{ | |
if((sockfd1=create_socket())==0) exit(0); | |
if((sockfd2=create_socket())==0) exit(0); | |
printf("[+] Making a connection to %s:%d...\n",host1,port1); | |
fflush(stdout); | |
if(client_connect(sockfd1,host1,port1)==0) | |
{ | |
printf("[-] Connect to HOST1 failed\n"); | |
close(sockfd1); | |
close(sockfd2); | |
continue; | |
} | |
printf("[+] HOST1 connected\n"); | |
l=0; | |
memset(buffer,0,MAXSIZE); | |
//fixed by Twi1ight 2012.09.12 | |
while(1) | |
{ | |
FD_ZERO(&fds); | |
FD_SET(sockfd1, &fds); | |
if (select(sockfd1+1, &fds, NULL, NULL, NULL) < 0 ) | |
{ | |
if (errno == EINTR) continue; | |
break; | |
} | |
if (FD_ISSET(sockfd1, &fds)) | |
{ | |
l=read(sockfd1, buffer, MAXSIZE); | |
break; | |
} | |
sleep(5); | |
} | |
if(l<=0) | |
{ | |
printf("[-] There is an error... Now creating a new connection.\n"); | |
continue; | |
} | |
while(1) | |
{ | |
printf("[+] Making a connection to %s:%d...\n",host2,port2); | |
fflush(stdout); | |
if(client_connect(sockfd2,host2,port2)==0) | |
{ | |
printf("[-] Connect to host2 failed\n"); | |
close(sockfd1); | |
close(sockfd2); | |
continue; | |
} | |
if(write(sockfd2,buffer,l) < 0) | |
{ | |
printf("[-] Sending failed.\n"); | |
continue; | |
} | |
l=0; | |
memset(buffer,0,MAXSIZE); | |
break; | |
} | |
printf("[+] All hosts connected!\n"); | |
pid=fork(); | |
if(pid==0) transdata(sockfd1,sockfd2); | |
//sleep(2); | |
close(sockfd1); | |
close(sockfd2); | |
} | |
} | |
void transdata(int fd1,int fd2) | |
{ | |
struct timeval timeset; | |
fd_set readfd,writefd; | |
int result,i=0; | |
char read_in1[MAXSIZE],send_out1[MAXSIZE]; | |
char read_in2[MAXSIZE],send_out2[MAXSIZE]; | |
int read1=0,totalread1=0,send1=0; | |
int read2=0,totalread2=0,send2=0; | |
int sendcount1,sendcount2; | |
int maxfd; | |
struct sockaddr_in client1,client2; | |
int structsize1,structsize2; | |
char host1[20],host2[20]; | |
int port1=0,port2=0; | |
char tmpbuf1[100],tmpbuf2[100]; | |
memset(host1,0,20); | |
memset(host2,0,20); | |
memset(tmpbuf1,0,100); | |
memset(tmpbuf2,0,100); | |
if(fp!=NULL) | |
{ | |
structsize1=sizeof(struct sockaddr); | |
structsize2=sizeof(struct sockaddr); | |
if(getpeername(fd1,(struct sockaddr *)&client1,(socklen_t *)&structsize1)<0) | |
{ | |
strcpy(host1,"fd1"); | |
} | |
else | |
{ | |
printf("[+] Got,ip:%s,port:%d\n",inet_ntoa(client1.sin_addr),ntohs(client1.sin_port)); | |
strcpy(host1,inet_ntoa(client1.sin_addr)); | |
port1=ntohs(client1.sin_port); | |
} | |
if(getpeername(fd2,(struct sockaddr *)&client2,(socklen_t *)&structsize2)<0) | |
{ | |
strcpy(host2,"fd2"); | |
} | |
else | |
{ | |
printf("[+] Got,ip:%s,port:%d\n",inet_ntoa(client2.sin_addr),ntohs(client2.sin_port)); | |
strcpy(host2,inet_ntoa(client2.sin_addr)); | |
port2=ntohs(client2.sin_port); | |
} | |
sprintf(tmpbuf1,"\n########### Read from %s:%d ####################\n",host1,port1); | |
sprintf(tmpbuf2,"\n########### Reply from %s:%d ####################\n",host2,port2); | |
} | |
maxfd=max(fd1,fd2)+1; | |
memset(read_in1,0,MAXSIZE); | |
memset(read_in2,0,MAXSIZE); | |
memset(send_out1,0,MAXSIZE); | |
memset(send_out2,0,MAXSIZE); | |
timeset.tv_sec=TIMEOUT; | |
timeset.tv_usec=0; | |
while(1) | |
{ | |
FD_ZERO(&readfd); | |
FD_ZERO(&writefd); | |
FD_SET(fd1,&readfd); | |
FD_SET(fd1,&writefd); | |
FD_SET(fd2,&writefd); | |
FD_SET(fd2,&readfd); | |
result=select(maxfd,&readfd,&writefd,NULL,×et); | |
if((result<0) && (errno!=EINTR)) | |
{ | |
perror("[-] Select error.\n"); | |
break; | |
} | |
else if(result==0) | |
{ | |
printf("[-] Time out.\n"); | |
break; | |
} | |
if(FD_ISSET(fd1,&readfd)) | |
{ | |
/* 不能超过MAXSIZE-totalread1,不然send_out1会溢出 */ | |
if(totalread1<MAXSIZE) | |
{ | |
read1=read(fd1,read_in1,MAXSIZE-totalread1); | |
if(read1==0) break; | |
if((read1<0) && (errno!=EINTR)) | |
{ | |
perror("[-] Read data error\n"); | |
break; | |
} | |
memcpy(send_out1+totalread1,read_in1,read1); | |
makelog(tmpbuf1,strlen(tmpbuf1)); | |
makelog(read_in1,read1); | |
totalread1+=read1; | |
memset(read_in1,0,MAXSIZE); | |
} | |
} | |
if(FD_ISSET(fd2,&writefd)) | |
{ | |
int err=0; | |
sendcount1=0; | |
while(totalread1>0) | |
{ | |
send1=write(fd2,send_out1+sendcount1,totalread1); | |
if(send1==0)break; | |
if((send1<0) && (errno!=EINTR)) | |
{ | |
perror("[-] Unknow error.\n"); | |
err=1; | |
break; | |
} | |
if((send1<0) && (errno==ENOSPC)) break; | |
sendcount1+=send1; | |
totalread1-=send1; | |
} | |
if(err==1) break; | |
if((totalread1>0) && (sendcount1>0)) | |
{ | |
/* 移动未发送完的数据到开始 */ | |
memcpy(send_out1,send_out1+sendcount1,totalread1); | |
memset(send_out1+totalread1,0,MAXSIZE-totalread1); | |
} | |
else | |
memset(send_out1,0,MAXSIZE); | |
} | |
if(FD_ISSET(fd2,&readfd)) | |
{ | |
if(totalread2<MAXSIZE) | |
{ | |
read2=read(fd2,read_in2,MAXSIZE-totalread2); | |
if(read2==0)break; | |
if((read2<0) && (errno!=EINTR)) | |
{ | |
perror("[-] Read data error.\n"); | |
break; | |
} | |
memcpy(send_out2+totalread2,read_in2,read2); | |
makelog(tmpbuf2,strlen(tmpbuf2)); | |
makelog(read_in2,read2); | |
totalread2+=read2; | |
memset(read_in2,0,MAXSIZE); | |
} | |
} | |
if(FD_ISSET(fd1,&writefd)) | |
{ | |
int err2=0; | |
sendcount2=0; | |
while(totalread2>0) | |
{ | |
send2=write(fd1,send_out2+sendcount2,totalread2); | |
if(send2==0)break; | |
if((send2<0) && (errno!=EINTR)) | |
{ | |
perror("[-] Unknow error"); | |
err2=1; | |
break; | |
} | |
if((send2<0) && (errno==ENOSPC)) break; | |
sendcount2+=send2; | |
totalread2-=send2; | |
} | |
if(err2==1) break; | |
if((totalread2>0) && (sendcount2 > 0)) | |
{ | |
/* 移动未发送完的数据到开始 */ | |
memcpy(send_out2,send_out2+sendcount2,totalread2); | |
memset(send_out2+totalread2,0,MAXSIZE-totalread2); | |
} | |
else | |
memset(send_out2,0,MAXSIZE); | |
} | |
} | |
close(fd1); | |
close(fd2); | |
printf("[+] Connection closed.\n"); | |
//exit(0); | |
} | |
void closeallfd(int n) | |
{ | |
int i; | |
// printf("[=] Bye.\n"); | |
fflush(stdout); | |
for(i=3;i<256;i++) | |
{ | |
close(i); | |
} | |
if(fp != NULL) | |
{ | |
// fprintf(fp,"[+] Bye.\n"); | |
fclose(fp); | |
} | |
// printf("[+] Done.\n"); | |
exit(0); | |
} | |
void makelog(char *buffer,int length) | |
{ | |
if(fp !=NULL) | |
{ | |
//fprintf(fp,"%s",buffer); | |
write(fileno(fp),buffer,length); | |
fflush(fp); | |
} | |
} | |
int create_socket() | |
{ | |
int sockfd; | |
sockfd=socket(AF_INET,SOCK_STREAM,0); | |
if(sockfd<0) | |
{ | |
perror("[-] Creating socket error\n"); | |
return(0); | |
} | |
return(sockfd); | |
} | |
int create_serv(int sockfd,int port) | |
{ | |
struct sockaddr_in srvaddr; | |
int on=1; | |
bzero(&srvaddr,sizeof(struct sockaddr)); | |
srvaddr.sin_port=htons(port); | |
srvaddr.sin_family=AF_INET; | |
srvaddr.sin_addr.s_addr=htonl(INADDR_ANY); | |
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); //so I can rebind the port | |
if(bind(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))<0) | |
{ | |
perror("[-] Error..\n"); | |
return(0); | |
} | |
if(listen(sockfd,CONNECT_NUMBER)<0) | |
{ | |
perror("[-] Listening error\n"); | |
return(0); | |
} | |
return(1); | |
} | |
int client_connect(int sockfd,char* server,int port) | |
{ | |
struct sockaddr_in cliaddr; | |
struct hostent *host; | |
if(!(host=gethostbyname(server))) | |
{ | |
printf("[+] Got host by name(%s) error:%s\n",server,strerror(errno)); | |
return(0); | |
} | |
bzero(&cliaddr,sizeof(struct sockaddr)); | |
cliaddr.sin_family=AF_INET; | |
cliaddr.sin_port=htons(port); | |
cliaddr.sin_addr=*((struct in_addr *)host->h_addr); | |
if(connect(sockfd,(struct sockaddr *)&cliaddr,sizeof(struct sockaddr))<0) | |
{ | |
perror("[-] Error.\n"); | |
return(0); | |
} | |
return(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment