荔园在线

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

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


发信人: michaelx (好好学习), 信区: Program
标  题: 為你的QQ造一個SOCKS5 PROXY(Gcc篇)之三
发信站: 荔园晨风BBS站 (Fri Mar 28 19:00:03 2003), 站内信件



一、SOCKS5 UDP封包結構
===========================
順序為:
2 Bytes 保留字,一定要為0x0
1 Bytes Current fragment number
1 Bytes 地址類型
X Bytes 目的地地址
2 Bytes 目的地端口號
N Bytes 數據


二、源代碼
===========================

void Launch_UDP( int udp_proxy_port, const char *udp_proxy_ip, int
clt_udp_port )
{
        //port is NOT network orders

        //記錄本機,客戶端,遠端服務器和封包來源地址
        struct sockaddr_in servaddr,clientaddr,remoteaddr,inaddr;
        int inlen;
        int listenfd;
        int n;
        fd_set set;
        //把接收來的數據寫在緩衝區第11個Byte之後,前10 Bytes用來存放Header
        char *thisbuf = &buf[10];
        int thissize = BUFSZ - 10;

        printf("< UDP Session - START >\n\n");

        //建立一個UDP SOCKET,注意UDP協議不需要listen, accept和conenct
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons( udp_proxy_port );
        servaddr.sin_addr.s_addr = htonl( INADDR_ANY );

        memset(&remoteaddr, 0, sizeof(remoteaddr));
        remoteaddr.sin_family = AF_INET;

        listenfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(listenfd < 0) {
                p_error("socket error");
                exit(-1);
        }

        if( bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) <
0 ) {
                p_error("bind error");
                exit(-1);
        }

        //使用select來監控Socket是否有資料可讀
        FD_ZERO(&set);
        FD_SET(listenfd, &set);

        while( 1 ) {

                if( select( listenfd+1, &set, NULL, NULL, NULL) < 0 ) {
                        p_error("select error");
                        exit(-1);
                }

                if( FD_ISSET( listenfd, &set ) ) {
                        //UDP協議可使用recvfrom()來接收數據,並獲得來源地地址
                        n = recvfrom( listenfd, thisbuf, thissize, 0, (struct
sockaddr
*)&inaddr, &inlen );

                        if( n >=0 ) {

                                debug_showip( &inaddr, "Received From", "\n" );

                                //資料來自客戶端
                                if(     (thisbuf[0]==0x0) && (thisbuf[1]==0x0)
&&
                                        (htons(inaddr.sin_port)==clt_udp_port) )
                                {
                                        //保存客戶端的地址
                                        memcpy( &clientaddr, &inaddr,
sizeof(clientaddr) );

                                        if( thisbuf[3] != 0x1 ) {
                                                //如果目的地地址類型為域名,先進
行解析獲得IP再發送
                                                struct hostent *h;
                                                char tmp[256];
                                                int seg;

                                                strncpy( tmp, &thisbuf[5],
thisbuf[4] );
                                                tmp[ thisbuf[4] ] = 0;

                                                h = gethostbyname ( tmp );
//<netdb.h>

                                                if( h == NULL )
                                                        p_error("unknown domain
name\n");
                                                else
                                                {

remoteaddr.sin_addr.s_addr = (*(struct in_addr*)h->h_addr).
s_addr;

                                                        seg = thisbuf[4]+1;
                                                        memcpy(
&remoteaddr.sin_port, &thisbuf[4+seg], 2 );

                                                        debug_showbin( thisbuf,
4+seg+2, "RECV CLIENT [ Header ]","\n");

                                                        debug_showbin(
&thisbuf[4+seg+2], n-(4+seg+2), "RECV CLIENT [
Data ]","\n");
                                                        debug_showip(
&remoteaddr, "Send to DOMAIN", "\n\n");

                                                        sendto( listenfd,
&thisbuf[4+seg+2], n-(4+seg+2), 0, (struct
sockaddr*)&remoteaddr,sizeof(remoteaddr));
                                                }
                                        } else {
                                                //目的地地址為IPv4,直接把資料發
送過去
                                                memcpy( &remoteaddr.sin_port,
&thisbuf[8], 2 );
                                                memcpy(
&remoteaddr.sin_addr.s_addr, &thisbuf[4], 4 );

                                                debug_showbin( thisbuf, 10,
"RECV CLIENT [ Header ]","\n");
                                                debug_showbin( &thisbuf[10],
n-10, "RECV CLIENT [  Data  ]",
"\n");
                                                debug_showip( &remoteaddr,
"Send to IP", "\n\n");

                                                sendto( listenfd, &thisbuf[10],
n-10, 0, (struct
sockaddr*)&remoteaddr,sizeof(remoteaddr));
                                        }
                                }
                                else
                                {       //資料來自遠端服務器
                                        debug_showbin(thisbuf, n, "RECV REMOTE",
"\n");
                                        debug_showip(&clientaddr, "Send to CLT",
"\n\n");

                                        //編寫Header

                                        buf[0] = 0x0;
                                        buf[1] = 0x0;
                                        buf[2] = 0x0;
                                        buf[3] = 0x1;
                                        memcpy( &buf[4], &udp_proxy_ip, 4 );
                                        memcpy( &buf[8], &udp_proxy_port, 2 );

                                        //發送到客戶端
                                        sendto( listenfd, buf, n+10, 0, (struct
sockaddr*)&clientaddr,
sizeof(clientaddr));
                }       }       }
        }

        close(listenfd);

        printf("< UDP Session - END >\n\n");
}



三、測試
===================
到目前為止,整個PROXY已經完成,可以用QQ來測試一下,連接後QQ與遠端服務器之間
傳輸的資料都會顯示在屏幕上,我們還可以對數據進行截留,從而把煩人的廣告全去
掉:)

--

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


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

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