荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: kid (晤), 信区: Program
标  题: 如何突破网关的种种限制与外界自由通讯(4)
发信站: 荔园晨风BBS站 (Sun Mar 31 09:39:35 2002), 转信

发信人: XSL (eXtentedStyleLanguage), 信区: XML
标  题: 如何突破网关的种种限制与外界自由通讯(续)
发信站: 逸仙时空 Yat-sen (Fri Oct 19 13:16:17 2001) , 站内信件

Module:SuperAgent.c
Author:ey4s<ey4s@21cn.com>
WEB:http://eyas.3322.net
Date:2001/6/6
用途:<1>在网关封闭了所有UDP数据包的情况下,通过TCP socket来转发数据,可
以用

来上QQ
<2>在网关封闭了所有TCP数据包的情况下,通过UDP socket来转发数据,可以用
来上IRC
<3>在防火墙禁止了TCP往外的连接的情况下,通过UDP socket来转发数据,可以
绕过FW
这个版本只能供单用户使用,稍微修改就可以供多用户同时使用,我偷懒:)))有兴

趣的
人自己去修改吧,呵呵。BTW:不高兴去设置发送,接收,连接等的超时了,反正
自己
测试用还行,hoho~_*
************************************************************************
****
**
/
#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib")
#define BuffSize 20*1024 //缓冲区大小20k
////////////////////////////////////////////////////////////////////////
////
//
/////////
/*如果模式为t,那么此地址结构是UDP Client的地址,此地址在接收到UDP
Client数据



如果模式为u,那么此地址结构为Target的地址*/
struct sockaddr_in UDPRecv;
BOOL bUDPRecvOK=FALSE;//上面的数据填充与否的标志
////////////////////////////////////////////////////////////////////////
////
//
/////////
//显示错误信息函数
void ShowError(char *);
//从TCP socket接收数据,通过UDP socket发送出去
DWORD WINAPI T2URedird(LPVOID);
//从UDP socket接收数据,通过TCP socket发送出去
DWORD WINAPI U2TRedird(LPVOID);
//帮助信息函数
void usage(char *);
////////////////////////////////////////////////////////////////////////
////
//
/////////
int main(int argc,char **argv)
{
int iRet;
BOOL bT;//此值为TRUE表示工作在t模式,为FALSE表示工作在u模式
char szTargetIP[40]={0};
int iLocalTCPPort,iLocalUDPPort,iTargetPort;
struct sockaddr_in UDPLocal,TCPLocal,Target;
SOCKET sListen,s[2];//s[0]=>UDP socket s[1]=>TCP socket
HANDLE hThread[2]={NULL,NULL};
DWORD dwThreadID,dwRet;
WSADATA wsd;

//判断参数个数
if((argc<5) || (argc>6))
{
usage(argv[0]);
return 1;
}

/*取得参数*/
//目标ip
strncpy(szTargetIP,argv[2],sizeof(szTargetIP)-1);
//目标端口,模式为t为tcp port,模式为u则为udp port
iTargetPort=atoi(argv[3]);
//本地监听的udp port
iLocalUDPPort=atoi(argv[4]);
//判断模式
if(strcmp(argv[1],"-t")==0) bT=TRUE;
else if(strcmp(argv[1],"-u")==0)
{
bT=FALSE;
//本地监听的TCP port
iLocalTCPPort=atoi(argv[5]);
}
else
{
printf("\nmode error.");
usage(argv[0]);
return 1;
}
printf("\nOK!Work mode is [%c].",argv[1][1]);

//load winsock library
if(WSAStartup(MAKEWORD(1,1),&wsd)!=0)
{
ShowError("WSAStartup");
return 1;
}
//监听本地UDP port的地址结构
UDPLocal.sin_family=AF_INET;
UDPLocal.sin_addr.s_addr=INADDR_ANY;
UDPLocal.sin_port=htons(iLocalUDPPort);
//目标地址结构
Target.sin_family=AF_INET;
Target.sin_addr.s_addr=inet_addr(szTargetIP);
Target.sin_port=htons(iTargetPort);
//如果工作在u模式的话,监听一个TCP port等待客户连接
if(bT==FALSE)
{
//创建一个TCP socket
sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sListen==INVALID_SOCKET)
{
ShowError("\nCreate TCP socket");
WSACleanup();
return 1;
}
//监听本地TCP port的地址结构
TCPLocal.sin_family=AF_INET;
TCPLocal.sin_port=htons(iLocalTCPPort);
TCPLocal.sin_addr.s_addr=htonl(INADDR_ANY);
//bind socket
iRet=bind(sListen,(SOCKADDR *)&TCPLocal,sizeof(TCPLocal));
if(iRet!=0)
{
ShowError("bind TCP port");
closesocket(sListen);
WSACleanup();
return 1;
}
//listen socket
if(listen(sListen,1)==SOCKET_ERROR)
{
ShowError("listen");
closesocket(sListen);
WSACleanup();
return 1;
}
UDPRecv.sin_family=Target.sin_family;
UDPRecv.sin_addr=Target.sin_addr;
UDPRecv.sin_port=Target.sin_port;
bUDPRecvOK=TRUE;
printf("\nListen TCP 127.0.0.1:%d ok!",iLocalTCPPort);
}
//开始循环
while(1)
{
__try
{
printf("\n\n************OK!SuperAgent working now**************\n\n");
//如果工作模式是U的话,accept阻塞直到有客户连接
if(bT==FALSE)
{
struct sockaddr_in addr;
int iSize=sizeof(addr);
//阻塞到客户连接
printf("\nWait for ey4s connect to me......:)");
s[1]=accept(sListen,(struct sockaddr *)&addr,&iSize);
if(s[1]==INVALID_SOCKET)
{
ShowError("accept");
__leave;
}
printf("\nAccept ey4s %s:%d connect to
me.",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
}
//创建一个UDP socket
s[0]=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(s[0]==INVALID_SOCKET)
{
ShowError("\nCreate UDP socket");
__leave;
}
//bind UDP socket
iRet=bind(s[0],(struct sockaddr *)&UDPLocal,sizeof(UDPLocal));
if(iRet==SOCKET_ERROR)
{
printf("\nBind UDP port %d failed.",iLocalUDPPort);
__leave;
}
else
printf("\nBind UDP port %d ok.",iLocalUDPPort);
//如果工作模式是T的话,用select阻塞直到UDP socket有数据可读
//然后才TCP connect到Target监听的TCP Port
if(bT==TRUE)
{
fd_set fdRead;
int ret=-1;
printf("\nWait for UDP socket have data to be recv.");
FD_ZERO(&fdRead);
FD_SET(s[0],&fdRead);
if((ret=select(0,&fdRead,NULL,NULL,NULL))==SOCKET_ERROR)
{
ShowError("select");
__leave;
}
if((ret<=0) || (!FD_ISSET(s[0],&fdRead)))
{
ShowError("select");
__leave;
}
printf("\nOK!UDP socket active now.");
//创建一个TCP socket
s[1]=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(s[1]==INVALID_SOCKET)
{
ShowError("\nCreate TCP socket");
__leave;
}
//connect to Target
while(1)
{
iRet=connect(s[1],(SOCKADDR *)&Target,sizeof(Target));
if(iRet!=0)
{
printf("\nConnect to Target TCP %s:%d failed.Wait for try
again.",szTargetIP,iTargetPort);
Sleep(1000);
}
else
{
printf("\nConnent to Target TCP %s:%d
ok.",szTargetIP,iTargetPort);
break;
}
}
}
//创建两个线程进行数据转发,双工
hThread[0]=CreateThread(NULL,0,T2URedird,(LPVOID)s,0,&dwThreadID);
if(hThread[0]==NULL)
{
ShowError("create thread 1");
__leave;
}
hThread[1]=CreateThread(NULL,0,U2TRedird,(LPVOID)s,0,&dwThreadID);
if(hThread[1]==NULL)
{
ShowError("create thread 2");
__leave;
}
//等待两个线程中的其中一个结束,一个线程结束后立即中断另一个线程
dwRet=WaitForMultipleObjects(2,hThread,FALSE,INFINITE);
if(dwRet==WAIT_FAILED)
{
ShowError("WaitForMultipleObjects");
__leave;
}
if((dwRet-WAIT_OBJECT_0)==0)
TerminateThread(hThread[1],1);
else
TerminateThread(hThread[0],1);
}//end of try
__finally
{
if(s[0]!=INVALID_SOCKET) closesocket(s[0]);
if(s[1]!=INVALID_SOCKET) closesocket(s[1]);
if(hThread[0]!=NULL) CloseHandle(hThread[0]);
if(hThread[1]!=NULL) CloseHandle(hThread[1]);
}//end of finally
printf("\n\n**************OK!SuperAgent shutdown
now******************\n\n");
Sleep(1);
}//end of while
if(sListen!=INVALID_SOCKET) closesocket(sListen);
WSACleanup();
return 0;
}
////////////////////////////////////////////////////////////////////////
////
//
/////////
void usage(char *name)
{
printf("\nSuperAgent use for TCP and UDP socket data redird"
"\nPower by ey4s<ey4s@21cn.com>"
"\nhttp://eyas.3322.net
"\n2001/6/7"
"\n\nusage: %s <mode>"
"\n[mode]"
"\n\t-t <TargetIP> <TargetTCPPort> <LocalUDPPort>"
"\n\t-u <TargetIP> <TargetUDPPort> <LocalUDPPort> <LocalTCPPort>\n",
name);
}
////////////////////////////////////////////////////////////////////////
////
//
/////////
void ShowError(char *msg)
{
printf("\n%s failed:%d",msg,GetLastError());
}
////////////////////////////////////////////////////////////////////////
////
//
/////////
//
//从sock[1]=>TCP socket读
//往sock[0]=>UDP socket写
//
DWORD WINAPI T2URedird(SOCKET *sock)
{
int iRet,
ret=-1,//select 返回值
iLeft,
idx,
iUDPRepeat=3,//UDP发送失败后重复的次数
iSTBCS=0;//STBCS=SendToBuffCurrentSize
char szSendTo[BuffSize]={0},
szRecvFrom[BuffSize]={0};
fd_set fdread,fdwrite;
DWORD dwThreadID=GetCurrentThreadId();

//开始一个循环来转发数据
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[1],&fdread);
FD_SET(sock[0],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
ShowError("select");
break;
}
if(ret>0)
{
//sock[1]可读
if(FD_ISSET(sock[1],&fdread))
{
//接收sock[1]发送来的数据
iRet=recv(sock[1],szRecvFrom,BuffSize,0);
if(iRet==SOCKET_ERROR)
{

//开始一个循环来转发数据
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[1],&fdread);
FD_SET(sock[0],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
ShowError("select");
break;
}
if(ret>0)
{
//sock[1]可读
if(FD_ISSET(sock[1],&fdread))
{
//接收sock[1]发送来的数据
iRet=recv(sock[1],szRecvFrom,BuffSize,0);
if(iRet==SOCKET_ERROR)
{
if(iRet==SOCKET_ERROR)
{
ShowError("sendto");
//重复发送次数自减一
if((iUDPRepeat--)==0)
break;
printf("\nTry %d times to send.",iUDPRepeat);
continue;
}
printf("\nUDP Thread %d sendto %s:%d %d bytes.",

dwThreadID,inet_ntoa(UDPRecv.sin_addr),ntohs(UDPRecv.sin_port),iRet);
iLeft-=iRet;
idx+=iRet;
}
if(iLeft==0)
{
//清空缓冲区
memset(szSendTo,0,BuffSize);
//重置发往target的数据缓冲区当前buff大小
iSTBCS=0;
}
}
}//end of select
Sleep(1);
}//end of while
return 0;
}
////////////////////////////////////////////////////////////////////////
////
//
/////////
//
//往sock[1],TCP socket写
//从sock[0],UDP socket读
//
DWORD WINAPI U2TRedird(SOCKET *sock)
{
int iRet,
ret=-1,//select 返回值
iLeft,
idx,
iSTBCS=0;//STBCS=SendToBuffCurrentSize
char szSendTo[BuffSize]={0},
szRecvFrom[BuffSize]={0};
fd_set fdread,fdwrite;
DWORD dwThreadID=GetCurrentThreadId();
struct sockaddr_in from;
DWORD dwSize=sizeof(from);

//开始一个循环来转发数据
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0],&fdread);
FD_SET(sock[1],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
ShowError("select");
break;
}
if(ret>0)
{
//sock[0]可读
if(FD_ISSET(sock[0],&fdread))
{
//接收sock[0]发送来的数据
iRet=recvfrom(sock[0],szRecvFrom,BuffSize,0,(SOCKADDR
*)&from,&dwSize);
if(iRet==SOCKET_ERROR)
{
ShowError("recvfrom");
break;
}
else if(iRet==0)
break;
if(bUDPRecvOK!=TRUE)
{
UDPRecv.sin_family=AF_INET;
UDPRecv.sin_addr=from.sin_addr;
UDPRecv.sin_port=from.sin_port;
bUDPRecvOK=TRUE;
}
printf("\nUDP Thread %d recvfrom %s:%d %d bytes.",
dwThreadID,inet_ntoa(from.sin_addr),ntohs(from.sin_port),iRet);
//把从sock[0]接收到的数据存添加到sock[1]的缓冲区
memcpy(szSendTo+iSTBCS,szRecvFrom,iRet);
//刷新sock[1]的数据缓冲区当前buff大小
iSTBCS+=iRet;
//清空接收sock[0]数据的缓冲区
memset(szRecvFrom,0,BuffSize);
}
//sock[1]可写,把从sock[0]接收到的数据发送到sock[1]
if(FD_ISSET(sock[1],&fdwrite))
{
iLeft=iSTBCS;
idx=0;
while(iLeft>0)
{
iRet=send(sock[1],&szSendTo[idx],iLeft,0);
if(iRet==SOCKET_ERROR)
{
ShowError("send");
break;
}
printf("\nTCP Thread %d send %d bytes.",dwThreadID,iRet);
iLeft-=iRet;
idx+=iRet;
}
//清空缓冲区
memset(szSendTo,0,BuffSize);
//重置发往target的数据缓冲区当前buff大小
iSTBCS=0;
}
}//end of select
Sleep(1);
}//end of while
return 0;
}
////////////////////////////////////////////////////////////////////////
////
//
//////////////////
程序在VC++6.0,Windows2k上编译通过,编译好的版本在http://eyas.3322.net有
下载


好了,废话说了一大堆,终于写完了,各位骂我可以,但请别拿西红柿,臭鸡蛋之
类的


砸偶才是,呵呵:)))



好了,废话说了一大堆,终于写完了,各位骂我可以,但请别拿西红柿,臭鸡蛋之
类的


砸偶才是,呵呵:)))



--
※ 来源:.逸仙时空 Yat-senWWW bbs.zsu.edu.cn. [FROM: 192.168.45.225]

--
          ╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳
            ︳╳  ︳轻  ︳易  ︳就  ︳把  ︳我  ︳╳  ︳
          ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳
          ╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳
          ︳困  ︳在  ︳了  ︳网  ︳的  ︳中  ︳央  ︳
          ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.32.62]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店