lcx源码分析


闲着没事,看到网上找了份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");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值