UDP穿透Socks5代理

UDP穿透Socks5代理

    SOCKS5 代理协议是他人定的,要编写程序首先必须了解其协议规则。所以先必须仔细地阅读rfc1928。这样对能够编写socket程序员来讲是易如反掌。本文是专门面对SOCKS5 UDP(无验证方式)

/*
Test Socks5 UDP proxy
Write by nenlong
http://newnan.8u8.com
mail:[email protected]
At Yanji 2004.2.26
send 5 0
recv 5 0

send 5 3 0 1 IP(4) Port(2)
recv 5 0 0 1 IP(4) Port(2)

data 0 0 0 1 IP(4) Port(2) DATA

UDP ASSOCIATE
The UDP ASSOCIATE request is used to establish an association within
the UDP relay process to handle UDP datagrams. The DST.ADDR and
DST.PORT fields contain the address and port that the client expects
to use to send UDP datagrams on for the association. The server MAY
use this information to limit access to the association. If the
client is not in possesion of the information at the time of the UDP
ASSOCIATE, the client MUST use a port number and address of all zeros.

If the reply code (REP value of X'00') indicates a success, and the
request was either a BIND or a CONNECT, the client may now start
passing data.

*/
#include "StdAfx.h"
#include "winsock2.h"
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
void closesocks(SOCKET s);
int senddata(char *data,int isize,sockaddr_in sa);//UDP
#pragma comment (lib,"ws2_32.lib")
char szMyIP[20];
char szProxyIP[20];
char szMsg[50];
int isc;
void main(void)
{
// 开始使用ws2_32.dll
sprintf(szProxyIP,"192.168.0.1");

WSADATA wsaData;
int iRetVal,i;
iRetVal = WSAStartup ( MAKEWORD ( 1,1 ), &wsaData );
if ( 0 != iRetVal)
{
printf("WSAStartup %d", iRetVal );
return;
}
printf("WSAStartup [OK]\n");


//取得主机名称
char szhostname[128];
if(SOCKET_ERROR ==gethostname(szhostname,128))
{
printf("gethostname %X\n",WSAGetLastError());
return;
}
printf("hostname %s[OK]\n",szhostname);

struct hostent FAR * lps;
lps=gethostbyname(szhostname);
if(lps==NULL)
{
printf("gethostbyname error\n");
}
else
{
IN_ADDR ia;
memcpy(&ia,lps->h_addr_list[0],4);
sprintf(szMyIP,"%s",inet_ntoa (ia));
printf(" addr:%s\n",szMyIP);
}

//建立socket
//AF_INET ---->to AF_INET for IPv4 addressing
//SOCK_STREAM --->TCP
SOCKET s;
s=socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET)
{
printf("socket %X\r",WSAGetLastError());
closesocket(s);
return;
}
printf("socket TCP [OK]\n");
sockaddr_in sa;
sa.sin_family=AF_INET;
sa.sin_port=htons(1080); //Port
sa.sin_addr.s_addr= inet_addr(szProxyIP); //IP

//建立连接 到代理服务器
iRetVal=connect (s,(SOCKADDR*)&sa,sizeof(sockaddr_in));
if(iRetVal==SOCKET_ERROR)
{
printf ("connect %X\n",WSAGetLastError());
closesocket(s);
return;
}
printf("connect %s %d[OK]\n",szProxyIP,1080);
//请求无验证
char buff[255];
buff[0]=5;buff[1]=0;
iRetVal=send(s,buff,2,0);
if(iRetVal==SOCKET_ERROR)
{
printf ("send 50 %X\n",WSAGetLastError());
closesocket(s);
return;
}
printf("Send 5 0 [OK]\n");
memset(buff,0,4);
printf("Recv ");
iRetVal=recv(s,buff,4,0);
printf("%02X %02X %02X %02X [OK]\n",buff[0],buff[1],buff[2],buff[3]);

//返回 5 0 请求成功
if(buff[0]!=5 || buff[1]!=0)
{
printf ("not proxy service\n");
closesocket(s);
return;
}

printf("find proxy server[OK]\n");

//报文10字节

buff[0]=5; //Ver
buff[1]=3; //UDP
buff[2]=0;
buff[3]=1; //IP V4 address
buff[4]=(unsigned char)0;
buff[5]=(unsigned char)0;
buff[6]=(unsigned char)0;
buff[7]=(unsigned char)0;
buff[8]=(unsigned char)0;
buff[9]=(unsigned char)0;

//发送报文
iRetVal=send(s,buff,10,0);
if(iRetVal==SOCKET_ERROR)
{
printf ("send 530100001388 %X\n",WSAGetLastError());
closesocket(s);
return;
}
printf("Send 05 03 00 01 00 00 00 00 00 00 [OK]\n");
memset(buff,0,10);
iRetVal=recv(s,buff,10,0);
if(iRetVal==SOCKET_ERROR)
{
printf ("recv %X\n",WSAGetLastError());
closesocket(s);
return;
}
printf("Recv ");
for(i=0;i<10;i++)
printf ("%02X ",(unsigned char)buff[i]);
printf("[OK]\n");
if(buff[0]!=5 || buff[1]!=0)
{
printf ("not UDP proxy service\n");
closesocket(s);
return;
}

char szIP[20];
sprintf(szIP,"%d.%d.%d.%d",
(unsigned char)buff[4],
(unsigned char)buff[5],
(unsigned char)buff[6],
(unsigned char)buff[7]);
int port;
port=(buff[8]<<8)+buff[9];
Sleep(500);
printf("UDP Proxy Add:%s Port:%d\nPress any key Send ...\n",szIP,port);
getch();
isc=0;
int ikey;
while((ikey=getch())!=0x1b)
{
//send data
sockaddr_in sato;
sato.sin_family=AF_INET;
sato.sin_port=htons(port);
sato.sin_addr.s_addr= inet_addr(szIP);

buff[0]=0; //RSV
buff[1]=0; //RSV
buff[2]=0; //FRAG
buff[3]=1; //IPV4
buff[4]=(unsigned char)192;
buff[5]=(unsigned char)168;
buff[6]=(unsigned char)0;
buff[7]=(unsigned char)1;
buff[8]=(unsigned char)0x13;
buff[9]=(unsigned char)0x88;//5000
isc++;
if(isc>50)isc=0;
if(ikey==17) //ctrl+Q
sprintf(szMsg,"Q");
else
sprintf(szMsg,"Hello SOCKS5 (UDP) %d ",isc);

for(i=0;i<(int)strlen(szMsg);i++)
{
buff[10+i]=szMsg[i];
}
buff[10+i]=0;

senddata(buff,10+strlen(szMsg)+1,sato);

if(iRetVal==SOCKET_ERROR)
{
printf ("send data %X\n",WSAGetLastError());
closesocket(s);
return;
}
printf("Press ESC key to exit Ctrl+Q Close RECV5000 Windows\n");
}
closesocket(s);
return;
}

void closesocks(SOCKET s)
{
closesocket(s);
WSACleanup();
}

int senddata(char *data,int isize,sockaddr_in sa)
{
int ret,i;
SOCKET s;
s=socket(AF_INET,SOCK_DGRAM,0);
ret=connect(s,(SOCKADDR*)&sa,sizeof(sockaddr_in));
if(ret==SOCKET_ERROR)
{
printf("UDP connect %X\n",ret);
closesocket(s);
return ret;
}
printf("UDP Send IP:%s Port:%d\nSend ",inet_ntoa (sa.sin_addr),ntohs (sa.sin_port));
for(i=0;i<isize;i++)
printf("%02X ",(unsigned char)data[i]);
printf("\n\n");
ret=send(s,data,isize,0);
closesocket(s);
return ret;
}


  以上即关于UDP穿透Socks5代理(无验证)的一点心得,希望能够得到大家的指正。

你可能感兴趣的:(UDP穿透Socks5代理)