闲着没事,看到网上找了份lcx的源码看了下。在此简单的分析下。
首先指明下 lcx 核心代码用的网络模型是select选择模型。
这里仅分析了常用的功能代码
-listen port1 port2
-slave ip port1 127.0.0.1 3389
经过分析 ,画出程序大致流程如下。
(图中的buf是共用一片缓冲区,每个机器有两个共用的buf)
主函数mian中通过argc,argv控制程序的参数,以及调用的函数
当参数为-listen时,调用函数bind2bind函数,进行端口监听。
参数为-slave时,进行端口连接。
线程函数transsmitdata是程序的核心代码,进行数据的交换转发。
程序执行过程大致如下:
1)、 1中本地执行命令-listen 511234,在端口51和1234端口监听
2)、 2中机器执行命令-slave ip 51127.0.0.1 3389连接远程机器,此时仅去连接51端口
(3389暂时还没有去连接,程序中是等51连接有回包才开始进行连接3389)
3)、 1中机器运行远程登录窗口登录127.0.0.1234,然后1234收到连接,并收到远程登录窗口发送的登录数据包,将数据包存储到buf中(待51连接使用)
4)、 1中51连接检测到buf中有数据,将数据发送给2(transsmitdata中执行的发包程序)
5)、 2中51收到数据,并将数据存储到buf中,
6)、 2中检测到51连接有回报,开始连接3389端口,并将5)步骤收到的数据包发送给3389端口(此时1中的3389登录数据包就到2中了)(conn2conn中完成)
7)、 2中3389收到登录包后,回包,2中127.0.0.1:3389收到3389端口的回包,存储到buf中,51连接将数据发送回去,依此进行(在函数transsmitdata中进行,完成数据包的转发)
以上过程具体请参照lcx源码中函数bind2bind, conn2conn, transsmitdata 代码
(PS:如有错误,欢迎批评指正)
附:
网上源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winsock2.h>
#include <io.h>
#include <signal.h>
#pragma comment(lib, "ws2_32.lib")
#define VERSION "1.01"
#define TIMEOUT 310
#define MAX_SIZE 20480
#define LENTH 40
#define CONN 6
// define 2 socket struct
struct transsocket
{
SOCKET fd1;
SOCKET fd2;
};
// define function
void ver();
void usage(char *prog);
void transsmitdata(LPVOID data);
void getctrlc(int j);
void closeallfd();
void makelog(char *buffer, int length);
void proxy(int port);
void bind2bind(int port1, int port2);
void bind2conn(int port1, char *host, int port2);
void conn2conn(char *host1, int port1, char *host2, int port2);
int testifisvalue(char *str);
int create_socket();
int create_server(int sockfd, int port);
int client_connect(int sockfd, char* server, int port);
// define GLOBAL variable here
extern int errno;
FILE *fp;
int method=0;
//int CONN=0;
//************************************************************************************
//
// function main
//
//************************************************************************************
int main(int argc, char* argv[])
{
for( int lv=0;lv<=100;lv++){ lv+=3; }
char **p;
char s_ConnectHost[LENTH], s_transsmitHost[LENTH];
int iConnectPort=0, itranssmitPort=0;
char *logfile=NULL;
memset(s_ConnectHost, 0, LENTH);
memset(s_transsmitHost, 0, LENTH);
p=argv;
while(*p)
{
if(stricmp(*p, "-log") == 0)
{
if(testifisvalue(*(p+1)))
{
logfile = *(++p);
}
else
{
printf("[-] ERROR: Must supply logfile name.\r\n");
return 0;
}
p++;
continue;
}
p++;
}
if(logfile !=NULL)
{
fp=fopen(logfile,"a");
if(fp == NULL )
{
printf("[-] ERROR: open logfile");
return 1;
}
makelog("====== Start ======\r\n", 22);
}
// Win Start Winsock.
WSADATA wsadata;
WSAStartup(MAKEWORD(1, 1), &wsadata);
//捕捉ctrl+c 信号
signal(SIGINT, &getctrlc);
if(argc > 2)
{
if(stricmp(argv[1], "-listenning") == 0 && argc >= 4)
{
iConnectPort = atoi(argv[2]);
itranssmitPort = atoi(argv[3]);
method = 1;
}
else
if(stricmp(argv[1], "-trans") == 0 && argc >= 5)
{
iConnectPort = atoi(argv[2]);
strncpy(s_transsmitHost, argv[3], LENTH);
itranssmitPort = atoi(argv[4]);
method = 2;
}
else
if(stricmp(argv[1], "-slav") == 0 && argc >= 6)
{
strncpy(s_ConnectHost, argv[2], LENTH);
iConnectPort = atoi(argv[3]);
strncpy(s_transsmitHost, argv[4], LENTH);
itranssmitPort = atoi(argv[5]);
method = 3;
}
if(stricmp(argv[1], "-h") == 0 && argc >= 6)
{
strncpy(s_ConnectHost, argv[2], LENTH);
iConnectPort = atoi(argv[3]);
strncpy(s_transsmitHost, argv[4], LENTH);
itranssmitPort = atoi(argv[5]);
method = 4;
}
}
switch(method)
{
case 1:
bind2bind(iConnectPort, itranssmitPort);
break;
case 2:
bind2conn(iConnectPort, s_transsmitHost, itranssmitPort);
break;
case 3:
conn2conn(s_ConnectHost, iConnectPort, s_transsmitHost, itranssmitPort);
break;
case 4:
usage(argv[0]);
break;
default:
usage(argv[0]);
break;
}
if(method)
{
closeallfd();
}
WSACleanup();
return 1;
}
//************************************************************************************
//
// print usage message
//
//************************************************************************************
VOID usage(char* prog)
{
printf("[Usage of Packet transsmit:]\r\n");
printf(" %s -<listenning|trans|slav> <option> [-log logfile]\n\n", prog);
printf("[option:]\n");
printf(" -listenning <ConnectPort> <transsmitPort>\n");
printf(" -trans <ConnectPort> <transsmitHost> <transsmitPort>\n");
printf(" -slav <ConnectHost> <ConnectPort> <transsmitHost> <transsmitPort>\n\n");
return;
}
//************************************************************************************
//
// test if is value
//
//************************************************************************************
int testifisvalue(char *str)
{
if(str == NULL ) return(0);
if(str[0]=='-') return(0);
return(1);
}
//************************************************************************************
//
// LocalHost:ConnectPort transsmit to LocalHost:transsmitPort
//
//************************************************************************************
void bind2bind(int port1, int port2)
{
SOCKET fd1,fd2, sockfd1, sockfd2;
struct sockaddr_in client1,client2;
int size1,size2;
HANDLE hThread=NULL;
transsocket sock;
DWORD dwThreadID;
if((fd1=create_socket())==0) return;
if((fd2=create_socket())==0) return;
printf("[+] listenninging port %d ......\r\n",port1);
fflush(stdout);
if(create_server(fd1, port1)==0)
{
closesocket(fd1);
return;
}
printf("[+] listenning OK!\r\n");
printf("[+] listenninging port %d ......\r\n",port2);
fflush(stdout);
if(create_server(fd2, port2)==0)
{
closesocket(fd2);
return;
}
printf("[+] listenning OK!\r\n");
size1=size2=sizeof(struct sockaddr);
while(1)
{
printf("[+] Waiting for Client on port:%d ......\r\n",port1);
if((sockfd1 = accept(fd1,(struct sockaddr *)&client1,&size1))<0)
{
printf("[-] Accept1 error.\r\n");
continue;
}
printf("[+] Accept a Client on port %d from %s ......\r\n", port1, inet_ntoa(client1.sin_addr));
printf("[+] Waiting another Client on port:%d....\r\n", port2);
if((sockfd2 = accept(fd2, (struct sockaddr *)&client2, &size2))<0)
{
printf("[-] Accept2 error.\r\n");
closesocket(sockfd1);
continue;
}
printf("[+] Accept a Client on port %d from %s\r\n",port2, inet_ntoa(client2.sin_addr));
printf("[+] Accept Connect OK!\r\n");
sock.fd1 = sockfd1;
sock.fd2 = sockfd2;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transsmitdata, (LPVOID)&sock, 0, &dwThreadID);
if(hThread == NULL)
{
TerminateThread(hThread, 0);
return;
}
Sleep(1000);
printf("[+] CreateThread OK!\r\n\n");
}
}
//************************************************************************************
//
// LocalHost:ConnectPort transsmit to transsmitHost:transsmitPort
//
//************************************************************************************
void bind2conn(int port1, char *host, int port2)
{
SOCKET sockfd,sockfd1,sockfd2;
struct sockaddr_in remote;
int size;
char buffer[1024];
HANDLE hThread=NULL;
transsocket sock;
DWORD dwThreadID;
if (port1 > 65535 || port1 < 1)
{
printf("[-] ConnectPort invalid.\r\n");
return;
}
if (port2 > 65535 || port2 < 1)
{
printf("[-] transsmitPort invalid.\r\n");
return;
}
memset(buffer,0,1024);
if((sockfd=create_socket()) == INVALID_SOCKET) return;
if(create_server(sockfd, port1) == 0)
{
closesocket(sockfd);
return;
}
size=sizeof(struct sockaddr);
while(1)
{
printf("[+] Waiting for Client ......\r\n");
if((sockfd1=accept(sockfd,(struct sockaddr *)&remote,&size))<0)
{
printf("[-] Accept error.\r\n");
continue;
}
printf("[+] Accept a Client from %s:%d ......\r\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
if((sockfd2=create_socket())==0)
{
closesocket(sockfd1);
continue;
}
printf("[+] Make a Connection to %s:%d ......\r\n",host,port2);
fflush(stdout);
if(client_connect(sockfd2,host,port2)==0)
{
closesocket(sockfd2);
sprintf(buffer,"[SERVER]connection to %s:%d error\r\n", host, port2);
send(sockfd1,buffer,strlen(buffer),0);
memset(buffer, 0, 1024);
closesocket(sockfd1);
continue;
}
printf("[+] Connect OK!\r\n");
sock.fd1 = sockfd1;
sock.fd2 = sockfd2;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transsmitdata, (LPVOID)&sock, 0, &dwThreadID);
if(hThread == NULL)
{
TerminateThread(hThread, 0);
return;
}
Sleep(1000);
printf("[+] CreateThread OK!\r\n\n");
}
}
//************************************************************************************
//
// ConnectHost:ConnectPort transsmit to transsmitHost:transsmitPort
//
//************************************************************************************
void conn2conn(char *host1,int port1,char *host2,int port2)
{
SOCKET sockfd1,sockfd2;
HANDLE hThread=NULL;
transsocket sock;
DWORD dwThreadID;
fd_set fds;
int l;
char buffer[MAX_SIZE];
while(1)
{
/*
while(CONN)
{
if(CONN < CONN)
{
Sleep(10000);
break;
}
else
{
Sleep(TIMEOUT*1000);
continue;
}
}
*/
if((sockfd1=create_socket())==0) return;
if((sockfd2=create_socket())==0) return;
printf("[+] Make a Connection to %s:%d....\r\n",host1,port1);
fflush(stdout);
if(client_connect(sockfd1,host1,port1)==0)
{
closesocket(sockfd1);
closesocket(sockfd2);
continue;
}
// fix by bkbll
// if host1:port1 recved data, than connect to host2,port2
l=0;
memset(buffer,0,MAX_SIZE);
while(1)
{
FD_ZERO(&fds);
FD_SET(sockfd1, &fds);
if (select(sockfd1+1, &fds, NULL, NULL, NULL) == SOCKET_ERROR)
{
if (errno == WSAEINTR) continue;
break;
}
if (FD_ISSET(sockfd1, &fds))
{
l=recv(sockfd1, buffer, MAX_SIZE, 0);
break;
}
Sleep(5);
}
if(l<=0)
{
printf("[-] There is a error...Create a new connection.\r\n");
continue;
}
while(1)
{
printf("[+] Connect OK!\r\n");
printf("[+] Make a Connection to %s:%d....\r\n", host2,port2);
fflush(stdout);
if(client_connect(sockfd2,host2,port2)==0)
{
closesocket(sockfd1);
closesocket(sockfd2);
continue;
}
if(send(sockfd2,buffer,l,0)==SOCKET_ERROR)
{
printf("[-] Send failed.\r\n");
continue;
}
l=0;
memset(buffer,0,MAX_SIZE);
break;
}
printf("[+] All Connect OK!\r\n");
sock.fd1 = sockfd1;
sock.fd2 = sockfd2;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transsmitdata, (LPVOID)&sock, 0, &dwThreadID);
if(hThread == NULL)
{
TerminateThread(hThread, 0);
return;
}
// CONN++;
Sleep(1000);
printf("[+] CreateThread OK!\r\n\n");
}
}
//************************************************************************************
//
// Socket transsmit to Socket
//
//************************************************************************************
void transsmitdata(LPVOID data)
{
SOCKET fd1, fd2;
transsocket *sock;
struct timeval timeset;
fd_set readfd,writefd;
int result,i=0;
char read_in1[MAX_SIZE],send_out1[MAX_SIZE];
char read_in2[MAX_SIZE],send_out2[MAX_SIZE];
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 tmpbuf[100];
sock = (transsocket *)data;
fd1 = sock->fd1;
fd2 = sock->fd2;
memset(host1,0,20);
memset(host2,0,20);
memset(tmpbuf,0,100);
structsize1=sizeof(struct sockaddr);
structsize2=sizeof(struct sockaddr);
//发生错误
if(getpeername(fd1,(struct sockaddr *)&client1,&structsize1)<0)
{
strcpy(host1, "fd1");
}
else
{
// printf("[+]got, ip:%s, port:%d\r\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,&structsize2)<0)
{
strcpy(host2,"fd2");
}
else
{
// printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client2.sin_addr),ntohs(client2.sin_port));
strcpy(host2, inet_ntoa(client2.sin_addr));
port2=ntohs(client2.sin_port);
}
printf("[+] Start transsmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, host2, port2);
maxfd=max(fd1,fd2)+1;
memset(read_in1,0,MAX_SIZE);
memset(read_in2,0,MAX_SIZE);
memset(send_out1,0,MAX_SIZE);
memset(send_out2,0,MAX_SIZE);
timeset.tv_sec=TIMEOUT;
timeset.tv_usec=0;
while(1)
{
FD_ZERO(&readfd);
FD_ZERO(&writefd);
FD_SET((UINT)fd1, &readfd);
FD_SET((UINT)fd1, &writefd);
FD_SET((UINT)fd2, &writefd);
FD_SET((UINT)fd2, &readfd);
result=select(maxfd,&readfd,&writefd,NULL,×et);
if((result<0) && (errno!=EINTR))
{
printf("[-] Select error.\r\n");
break;
}
else if(result==0)
{
printf("[-] Socket time out.\r\n");
break;
}
if(FD_ISSET(fd1, &readfd))
{
/* must < MAX_SIZE-totalread1, otherwise send_out1 will flow */
if(totalread1<MAX_SIZE)
{
read1=recv(fd1, read_in1, MAX_SIZE-totalread1, 0);
if((read1==SOCKET_ERROR) || (read1==0))
{
printf("[-] Read fd1 data error,maybe close?\r\n");
break;
}
//将从服务端接受的数据,存放到send_out1中,
memcpy(send_out1+totalread1,read_in1,read1);
sprintf(tmpbuf,"\r\nRecv %5d bytes from %s:%d\r\n", read1, host1, port1);
printf(" Recv %5d bytes %16s:%d\r\n", read1, host1, port1);
makelog(tmpbuf,strlen(tmpbuf));
makelog(read_in1,read1);
totalread1+=read1;
memset(read_in1,0,MAX_SIZE);
}
}
if(FD_ISSET(fd2, &writefd))
{
int err=0;
sendcount1=0;
while(totalread1>0)
{
//接受服务端的数据在send_out1中,将缓冲区的内容发给本地登录的远程连接即可
send1=send(fd2, send_out1+sendcount1, totalread1, 0);
if(send1==0)break;
if((send1<0) && (errno!=EINTR))
{
printf("[-] Send to fd2 unknow error.\r\n");
err=1;
break;
}
if((send1<0) && (errno==ENOSPC)) break;
sendcount1+=send1;
totalread1-=send1;
printf(" Send %5d bytes %16s:%d\r\n", send1, host2, port2);
}
if(err==1) break;
if((totalread1>0) && (sendcount1>0))
{
/* move not sended data to start addr */
memcpy(send_out1,send_out1+sendcount1,totalread1);
memset(send_out1+totalread1,0,MAX_SIZE-totalread1);
}
else
memset(send_out1,0,MAX_SIZE);
}
if(FD_ISSET(fd2, &readfd))
{
if(totalread2<MAX_SIZE)
{
read2=recv(fd2,read_in2,MAX_SIZE-totalread2, 0);
if(read2==0)break;
if((read2<0) && (errno!=EINTR))
{
printf("[-] Read fd2 data error,maybe close?\r\n\r\n");
break;
}
memcpy(send_out2+totalread2,read_in2,read2);
sprintf(tmpbuf, "\r\nRecv %5d bytes from %s:%d\r\n", read2, host2, port2);
printf(" Recv %5d bytes %16s:%d\r\n", read2, host2, port2);
makelog(tmpbuf,strlen(tmpbuf));
makelog(read_in2,read2);
totalread2+=read2;
memset(read_in2,0,MAX_SIZE);
}
}
if(FD_ISSET(fd1, &writefd))
{
int err2=0;
sendcount2=0;
while(totalread2>0)
{
send2=send(fd1, send_out2+sendcount2, totalread2, 0);
if(send2==0)break;
if((send2<0) && (errno!=EINTR))
{
printf("[-] Send to fd1 unknow error.\r\n");
err2=1;
break;
}
if((send2<0) && (errno==ENOSPC)) break;
sendcount2+=send2;
totalread2-=send2;
printf(" Send %5d bytes %16s:%d\r\n", send2, host1, port1);
}
if(err2==1) break;
if((totalread2>0) && (sendcount2 > 0))
{
/* move not sended data to start addr */
memcpy(send_out2, send_out2+sendcount2, totalread2);
memset(send_out2+totalread2, 0, MAX_SIZE-totalread2);
}
else
memset(send_out2,0,MAX_SIZE);
}
Sleep(5);
}
closesocket(fd1);
closesocket(fd2);
// if(method == 3)
// CONN --;
printf("\r\n[+] OK! I Closed The Two Socket.\r\n");
}
void getctrlc(int j)
{
printf("\r\n[-] Received Ctrl+C\r\n");
closeallfd();
exit(0);
}
void closeallfd()
{
int i;
printf("[+] Let me exit ......\r\n");
fflush(stdout);
for(i=3; i<256; i++)
{
closesocket(i);
}
if(fp != NULL)
{
fprintf(fp,"\r\n====== Exit ======\r\n");
fclose(fp);
}
printf("[+] All Right!\r\n");
}
int create_socket()
{
int sockfd;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
printf("[-] Create socket error.\r\n");
return(0);
}
return(sockfd);
}
int create_server(int sockfd,int port)
{
struct sockaddr_in srvaddr;
int on=1;
memset(&srvaddr, 0, 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, (char*)&on,sizeof(on)); //so I can rebind the port
if(bind(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))<0)
{
printf("[-] Socket bind error.\r\n");
return(0);
}
if(listen(sockfd,CONN)<0)
{
printf("[-] Socket listenning error.\r\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("[-] Gethostbyname(%s) error:%s\n",server,strerror(errno));
return(0);
}
memset(&cliaddr, 0, 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)
{
printf("[-] Connect error.\r\n");
return(0);
}
return(1);
}
void makelog(char *buffer,int length)
{
if(fp !=NULL)
{
// fprintf(fp, "%s", buffer);
// printf("%s",buffer);
write(fileno(fp),buffer,length);
// fflush(fp);
}
}
然后自己又把分析的代码拉出来,单独写了一遍(原来基本相同)
#include <stdio.h>
#include <WinSock2.h>
#include <signal.h>
# include <errno.h>
#pragma comment(lib,"WS2_32")
#define PORT 1234
#define LENGTH 40
#define CONNUM 5
#define MAX_SIZE 20480
#define TIMEOUT 310
typedef struct _MySocket
{
SOCKET sListenSocket1;
SOCKET sListenSocket2;
}MySocket,*pMySocket;
//
int method = 0;
void TransmitData(LPVOID data);
int CreateServer(int *socketsListen,int port);
int ClientConnect(int *socketCon, char* serverhost, int port);
void getctrlc(int);
void usage(char nameStr[]);
void bind2bind(int port1,int port2);
void conn2conn(char host1Addr[],int port1,char host2Addr[],int port2);
int main(int argc, char* argv[])
{
char connectHost[LENGTH],transmitHost[LENGTH];
int ConnectPort = 0, TransmitPort = 0;
memset(connectHost,0,LENGTH);
memset(transmitHost,0,LENGTH);
//初始化ws2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2,2);
if(WSAStartup(sockVersion,&wsaData) != 0)
{
exit(0);
}
//捕捉ctrl+c信号
signal(SIGINT,&getctrlc);
//
//处理输入的参数
if(argc > 2)
{
if(strcmp(argv[1],"-listen") == 0 && argc >= 4)
{
ConnectPort = atoi(argv[2]);
TransmitPort = atoi(argv[3]);
method = 1;
}
else if(strcmp(argv[1],"-slave") == 0 && argc >= 6)
{
strncpy(connectHost,argv[2],LENGTH);
ConnectPort = atoi(argv[3]);
strncpy(transmitHost,argv[4],LENGTH);
TransmitPort = atoi(argv[5]);
method = 2;
}
else if(strcmp(argv[1],"-h") == 0)
{
method = 3;
}
}
switch(method)
{
case 1:
bind2bind(ConnectPort,TransmitPort);
break;
case 2:
conn2conn(connectHost,ConnectPort,transmitHost,TransmitPort);
break;
case 3:
usage(argv[0]);
break;
default:
usage(argv[0]);
}
//最后处理
WSACleanup();
return 1;
}
//************************************************************************************
//
// print usage message
//
//************************************************************************************
VOID usage(char* prog)
{
printf("[Usage of Packet transmit:]\r\n");
printf(" %s -<listen|slave> <option> \n\n", prog);
printf("[option:]\n");
printf(" -listen <ConnectPort> <transmitPort>\n");
printf(" -slave <ConnectHost> <ConnectPort> <transmitHost> <transmitPort>\n\n");
return;
}
int CreateServer(int *socketsListen,int port)
{
sockaddr_in srvaddr;
int on = 1;
//创建套接字
*socketsListen = socket(AF_INET, SOCK_STREAM, 0);
if(*socketsListen < 0)
{
printf("[-] Create socket error .\r\n");
return 0;
}
//监听套接字
memset(&srvaddr, 0, sizeof(sockaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(port);
srvaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
//端口服用设置
if(setsockopt(*socketsListen,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)) == SOCKET_ERROR)
{
printf("setsockopt error.\r\n errornum = %d\r\n",GetLastError());
return 0;
}
if(bind(*socketsListen,(sockaddr*)&srvaddr,sizeof(sockaddr)) < 0)
{
printf("[-] socket bind error .\r\nerrornum= %d\r\n",GetLastError());
return 0;
}
//监听套接字
if(listen(*socketsListen,CONNUM) < 0)
{
printf("[-] socket listen error .\r\n");
return 0;
}
return 1;
}
//连接函数
int ClientConnect(int *socketCon, char* serverhost, int port)
{
sockaddr_in clientaddr;
HOSTENT *host;
//创建套接字
*socketCon = socket(AF_INET, SOCK_STREAM, 0);
if(*socketCon < 0)
{
printf("[-] Create socket error .\r\n");
return 0;
}
//获取服务器信息
if(!(host = gethostbyname(serverhost)))
{
printf("[-] GetHostByName (%s) error :%s\n",serverhost,strerror(errno));
return 0;
}
memset(&clientaddr,0, sizeof(sockaddr));
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(port);
clientaddr.sin_addr = *(in_addr*)host->h_addr;
//连接服务端
if(connect(*socketCon,(sockaddr*)&clientaddr,sizeof(sockaddr))<0)
{
printf("[-] Connect error.\r\n");
return 0;
}
return 1;
}
//捕捉ctrl+c信号处理函数
void getctrlc(int i)
{
printf("\r\n[-] Received Ctrl + C\r\n");
exit(0);
}
void bind2bind(int port1,int port2)
{
SOCKET sListenSocket1,sListenSocket2,sAcceptSocket1,sAccpetSocket2;
sockaddr_in client1,client2;
int size1,size2;
DWORD dwThreadId;
HANDLE hThread = NULL;
MySocket ThreadSocket;
//在sListenSocket1 port1上进行监听
printf("[+] listening port %d ......\r\n",port1);
fflush(stdout);
if(CreateServer((int*)&sListenSocket1,port1) == 0)
{
if(sListenSocket1 != NULL)
closesocket(sListenSocket1);
return;
}
printf("[+] listening OK!\r\n");
//在sListenSocket2 port2上进行监听
printf("[+] listening port %d ......\r\n",port2);
fflush(stdout);
if(CreateServer((int*)&sListenSocket2,port2) == 0)
{
if(sListenSocket2 != NULL)
closesocket(sListenSocket2);
return;
}
printf("listening OK !\r\n");
//接收连接
size1 = size2 = sizeof(sockaddr);
while(1)
{
//在port1上接收连接
printf("[+] Waiting for Client on port: %d ......\r\n",port1);
if((sAcceptSocket1 = accept(sListenSocket1,(sockaddr*)&client1,&size1)) < 0)
{
printf("[-] Accept1 error.\r\n");
continue;
}
printf("[+] Accept a Client on port %d from %s .......\r\n",port1,inet_ntoa(client1.sin_addr));
printf("[+] Waiting another Client on port: %d ......\r\n",port2);
if((sAccpetSocket2 = accept(sListenSocket2,(sockaddr*)&client2,&size2)) < 0)
{
printf("[-] Accept2 error.\r\n");
continue;
}
printf("[+] Accept a Client on port %d from %s \r\n",port2,inet_ntoa(client2.sin_addr));
printf("[+] Accept connect Ok!\r\n");
//常见线程,处理数据(所有关于套接字的处理,使用接收连接后的套接字)
ThreadSocket.sListenSocket1 = sAcceptSocket1;
ThreadSocket.sListenSocket2 = sAccpetSocket2;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TransmitData, (LPVOID)&ThreadSocket, 0, &dwThreadId);
if(hThread == NULL)
{
TerminateThread(hThread,0);
return;
}
Sleep(1000);
printf("[+] CreateThread Ok !\r\n");
}
}
//conn2conn函数实现
void conn2conn(char host1Addr[],int port1,char host2Addr[],int port2)
{
SOCKET socketConn1,socketConn2;
HANDLE hThread = NULL;
MySocket hThreadSock;
DWORD dwThreadId;
fd_set fds;
char buffer[MAX_SIZE];
int flag;
//连接服务端
while(1)
{
//连接第一个服务端
printf("[+] Make a Connection to %s : %d...\r\n",host1Addr,port1);
fflush(stdout);
if(ClientConnect((int*)&socketConn1,host1Addr,port1) != 1)
{
if(socketConn1 != NULL)
closesocket(socketConn1);
continue;
}
//如果host1addr port1 有数据,连接host2addr port2
flag = 0;
memset(buffer,0,MAX_SIZE);
while(1)
{
FD_ZERO(&fds);
FD_SET(socketConn1,&fds);
if(select(0,&fds,NULL,NULL,NULL) == SOCKET_ERROR)
{
if(errno == WSAEINTR) continue;
break;
}
if(FD_ISSET(socketConn1,&fds))
{
flag = recv(socketConn1,buffer,MAX_SIZE,0);
break;
}
Sleep(5);
}
if(flag <= 0)
{
printf("[-] There is a error ....Create a new connection.\r\n");
continue;
}
//第二个连接
while(1)
{
printf("[+] Coonnect OK !\r\n");
printf("[+] Make a Connect to %s : %d \n",host2Addr,port2);
fflush(stdout);
if(ClientConnect((int*)&socketConn2,host2Addr,port2) == 0)
{
if(socketConn2 != NULL)
closesocket(socketConn2);
continue;
}
if(send(socketConn2,buffer,flag,0) == SOCKET_ERROR)
{
printf("[-] Send failed.\r\n");
continue;
}
flag = 0;
memset(buffer,0,MAX_SIZE);
break;
}
printf("[+] All Connect Ok!\r\n");
//创建线程
hThreadSock.sListenSocket1 = socketConn1;
hThreadSock.sListenSocket2 = socketConn2;
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransmitData,(LPVOID)&hThreadSock,0,&dwThreadId);
if(hThread == NULL)
{
TerminateThread(hThread,0);
return;
}
Sleep(1000);
printf("[+] CreateThread Ok!\r\n");
}
}
//数据传输实现
void TransmitData(LPVOID data)
{
SOCKET fd1,fd2;
pMySocket sock;
int result,i=0;
timeval timeset;
fd_set readfd,writefd;
char readin1[MAX_SIZE],sendout1[MAX_SIZE];
char readin2[MAX_SIZE],sendout2[MAX_SIZE];
int read1=0,totalread1=0,send1=0;
int read2=0,totalread2=0,send2=0;
int sendcount1,sendcount2;
sockaddr_in client1,client2;
int structsize1,structsize2;
char host1[20],host2[20];
int port1,port2;
char tempbuf[100];
sock = (pMySocket)data;
fd1 = sock->sListenSocket1;
fd2 = sock->sListenSocket2;
//初始化一些缓冲区
memset(host1,0,20);
memset(host2,0,20);
memset(tempbuf,0,100);
structsize1 = sizeof(sockaddr);
structsize2 = sizeof(sockaddr);
//获取链接一的信息
if(getpeername(fd1,(sockaddr*)&client1,&structsize1) < 0)
{
strcpy(host1,"fd1");
}
else
{
strcpy(host1,inet_ntoa(client1.sin_addr));
port1 = ntohs(client1.sin_port);
}
//获取连接2的信息
if(getpeername(fd2,(sockaddr*)&client2,&structsize2) < 0)
{
strcpy(host2,"fd2");
}
else
{
strcpy(host2,inet_ntoa(client2.sin_addr));
port2 = ntohs(client2.sin_port);
}
printf("[+] Start transmit %s:%d <-> %s:%d.....\r\n",host1,port1,host2,port2);
memset(readin1,0,MAX_SIZE);
memset(readin2,0,MAX_SIZE);
memset(sendout1,0,MAX_SIZE);
memset(sendout2,0,MAX_SIZE);
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,&readfd);
FD_SET(fd2,&writefd);
//选择模型处理套接字数据
result = select(0,&readfd,&writefd,NULL,×et);
if(result<=0)
{
printf("[-] Select error.\r\n");
break;
}
if(FD_ISSET(fd1,&readfd))
{
//fd1有数据可读可接受
if(totalread1 < MAX_SIZE)
{
read1 = recv(fd1,readin1,MAX_SIZE-totalread1,0);
if(read1 == SOCKET_ERROR || read1 == 0)
{
printf("[-] read fd1 data error,maybe close?\r\n");
printf("[-] error num : %d\r\n",GetLastError());
break;
}
//将读到的数据存放到sendout1中
memcpy(sendout1 + totalread1,readin1,read1);
printf("Recv %5d bytes from %s:%d\r\n",read1,host1,port1);
totalread1 += read1;
memset(readin1,0,MAX_SIZE);
}
}
if(FD_ISSET(fd2,&writefd))
{
int err = 0;
sendcount1 = 0;
//有数据时才进行发送
while(totalread1 >0)
{
//将fd1中接受来自服务端的数据(存储到sendout1)发送给本地远程登录程序
send1 = send(fd2,sendout1+sendcount1,totalread1,0);
if(send1 <= 0)
{
printf("[-] Send to fd2 unkown error .\r\n");
err = 1;
break;
}
sendcount1 += send1;
totalread1 -= send1;
printf("send %5d bytes %16s :%d\r\n",send1,host2,port2);
}
if(err == 1) break;
if(totalread1 >0 && sendcount1>0)
{
//将未发送的数据移到数组开始位置
memcpy(sendout1,sendout1+sendcount1,totalread1);
memset(sendout1+sendcount1,0,MAX_SIZE-totalread1);
}
else
memset(sendout1,0,MAX_SIZE);
}
if(FD_ISSET(fd2,&readfd))
{
if(totalread2 < MAX_SIZE)
{
read2 = recv(fd2,readin2,MAX_SIZE-totalread2,0);
if(read2 == 0) break;
if(read2 < 0 && errno != EINTR)
{
printf("[-] Read fd2 data error,maybe close? \r\n\r\n");
printf("[-] error num :%d\r\n",GetLastError());
break;
}
memcpy(sendout2+totalread2,readin2,read2);
printf("Recv %5d bytes %16s:%5d\r\n",read2,host2,port2);
totalread2 += read2;
memset(readin2,0,MAX_SIZE);
}
}
if(FD_ISSET(fd1,&writefd))
{
int err2 = 0;
sendcount2 = 0;
while(totalread2 > 0)
{
send2 = send(fd1,sendout2+sendcount2,totalread2,0);
if(send2 <= 0)
{
printf("[-] send to fd1 unkwon error.\r\n");
err2 = 1;
break;
}
sendcount2 += send2;
totalread2 -= send2;
printf("send %5d bytes %16s:%d\r\n",send2,host1,port1);
}
if (err2 ==1) break;
if(totalread2 >0 && sendcount2 > 0)
{
memcpy(sendout2,sendout2+sendcount2,totalread2);
memset(sendout2+totalread2,0,MAX_SIZE-totalread2);
}
else
memset(sendout2,0,MAX_SIZE);
}
Sleep(5);
}
closesocket(fd1);
closesocket(fd2);
printf("\r\n[+] OK! close two socket.sListenSocket1\r\n");
}