EDN Admin
Well-known member
Hi there!<br/>
I thought Id give networkprogramming a shot again.<br/>
So I took trying to program a SOCKSv4 client.
Despite some servers which return no Value at all regarding the CD-value (listed here http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol, I couldnt find an RCF on SOCKS4), it works greate.
Problem is, when my program, requests a webpage, I get an ERROR 405 webpage and I dont know why.<br/>
Can someone help me out here?
<div style="color:black; background-color:white
<pre>#ifndef UNICODE
#define UNICODE
#endif
#include<iostream>
#include<string>
#include<WinSock2.h>
#include<Windows.h>
#pragma comment(lib,<span style="color:#a31515 "Ws2_32.lib")
<span style="color:blue struct SOCKS4CONNECT{
<span style="color:blue char VN;<span style="color:green //Version of Socket
<span style="color:blue char CD;<span style="color:green //uponConnect is to be set to one
<span style="color:blue short DSTPORT;<span style="color:green //targetport of server to reach
<span style="color:blue int DSTIP;<span style="color:green //IP of server to reach
<span style="color:blue char USERID;<span style="color:green //if no userid it still has to be null terminanted,in this case it is null to simplyfy things,
<span style="color:green //TODO: change USERID to std::string
};
<span style="color:blue struct SOCKS4RESPONSE{
<span style="color:blue char VN;<span style="color:green //Version of replycode, shoud be 0
<span style="color:blue char CD;<span style="color:green //ConditionCOde
<span style="color:green /* possible values:
* 90: request granted
* 91: request rejected or failed
* 92: request rejected becasue SOCKS server cannot connect to
* identd on the client
* 93: request rejected because the client program and identd
* report different user-ids
*/
<span style="color:blue short DSTPORT;<span style="color:green //is ignored
<span style="color:blue int DSTIP;<span style="color:green //is ignored
};
<span style="color:blue int main(<span style="color:blue int argc,<span style="color:blue char** argv){
<span style="color:blue int retval = 0;
DWORD numberBytesSent = 0;
sockaddr_in param;
WSAData wsaparam;
DWORD flag = 0;
SOCKS4CONNECT connectstruct = {0x04,<span style="color:green //version 4
0x01,<span style="color:green //we request a connect
htons(80),<span style="color:green //we want to connect to port 80
inet_addr(<span style="color:#a31515 "173.194.69.94"),<span style="color:green
};
SOCKS4RESPONSE responsestruct = {0,0,0,0};
<span style="color:green //preparation for using socks-proxy
WSABUF SOCKS4connectrequest,SOCKS4response;<span style="color:green //will hold the data to pass upon connectionestablishment
SOCKS4connectrequest.buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(&connectstruct);
SOCKS4connectrequest.len = <span style="color:blue sizeof(connectstruct);
SOCKS4response.buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(&responsestruct);
SOCKS4response.len = <span style="color:blue sizeof(responsestruct);
<span style="color:green //if the following string has the wrong format it leads to a timeout-error or no answer at all request ends with 2 rn
<span style="color:blue char content[] = <span style="color:#a31515 "GET / HTTP/1.1 rnHost: 173.194.69.94rnrn";
retval = WSAStartup(MAKEWORD(2,2),&wsaparam);
<span style="color:blue if(retval != 0)
<span style="color:blue return -1;
<span style="color:green //regular syntax of Berklysockets are supportes as well so you could use socket(af,type,protocoll) as well
SOCKET sock = WSASocket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,0,0);<span style="color:green //later on add WSA_FLAG_OVERLAPPED instead of the last 0 and change the behaviour of WSASend to gain more performance
<span style="color:blue if(sock == INVALID_SOCKET)
<span style="color:blue return -1;
param.sin_family = AF_INET;
param.sin_port = htons(1080);
<span style="color:green //param.sin_addr.S_un.S_addr = inet_addr(inet_ntoa(*(in_addr*)gethostbyname("www.google.com")->h_addr_list[0]));
param.sin_addr.S_un.S_addr = inet_addr(<span style="color:#a31515 "92.114.207.203");<span style="color:green //address of socks4proxy
retval = WSAConnect(sock,(sockaddr*)¶m,<span style="color:blue sizeof(param),NULL,NULL,NULL,NULL);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
WSABUF sendarray[1],recvarray[1];
sendarray[0].buf = content;
sendarray[0].len = <span style="color:blue sizeof(content);
retval = WSASend(sock,&SOCKS4connectrequest,1,&numberBytesSent,0,0,0);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
<span style="color:blue else{
retval = WSARecv(sock,&SOCKS4response,1,&numberBytesSent,&flag,NULL,NULL);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
}
<span style="color:blue if(<span style="color:blue reinterpret_cast<SOCKS4RESPONSE*>(SOCKS4response.buf)->CD != 90)
<span style="color:blue return -1;
retval = WSASend(sock,sendarray,1,&numberBytesSent,0,0,0);
<span style="color:blue if(retval != 0)
<span style="color:blue return -1;
recvarray[0].buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(malloc(<span style="color:blue sizeof(<span style="color:blue char) * 1024));
recvarray[0].len =_msize(recvarray[0].buf);
memset(<span style="color:blue reinterpret_cast<<span style="color:blue void*>(recvarray[0].buf),0,recvarray[0].len);
retval = WSARecv(sock,recvarray,1,&numberBytesSent,&flag,NULL,NULL);<span style="color:green /*this time #Bytes received*/
<span style="color:blue if(retval != 0)
retval = WSAGetLastError();
<span style="color:blue if(retval == WSAEFAULT){
<span style="color:blue return -1;
}
std::cout<<<span style="color:#a31515 "here is the output"<<std::endl<<recvarray[0].buf<<std::endl;
std::cin.get();
free(<span style="color:blue reinterpret_cast<<span style="color:blue void*>(recvarray[0].buf));
closesocket(sock);
WSACleanup();
<span style="color:blue return 0;
}
[/code]
<br/>
Thanks.
Sincerely
<br/>
View the full article
I thought Id give networkprogramming a shot again.<br/>
So I took trying to program a SOCKSv4 client.
Despite some servers which return no Value at all regarding the CD-value (listed here http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol, I couldnt find an RCF on SOCKS4), it works greate.
Problem is, when my program, requests a webpage, I get an ERROR 405 webpage and I dont know why.<br/>
Can someone help me out here?
<div style="color:black; background-color:white
<pre>#ifndef UNICODE
#define UNICODE
#endif
#include<iostream>
#include<string>
#include<WinSock2.h>
#include<Windows.h>
#pragma comment(lib,<span style="color:#a31515 "Ws2_32.lib")
<span style="color:blue struct SOCKS4CONNECT{
<span style="color:blue char VN;<span style="color:green //Version of Socket
<span style="color:blue char CD;<span style="color:green //uponConnect is to be set to one
<span style="color:blue short DSTPORT;<span style="color:green //targetport of server to reach
<span style="color:blue int DSTIP;<span style="color:green //IP of server to reach
<span style="color:blue char USERID;<span style="color:green //if no userid it still has to be null terminanted,in this case it is null to simplyfy things,
<span style="color:green //TODO: change USERID to std::string
};
<span style="color:blue struct SOCKS4RESPONSE{
<span style="color:blue char VN;<span style="color:green //Version of replycode, shoud be 0
<span style="color:blue char CD;<span style="color:green //ConditionCOde
<span style="color:green /* possible values:
* 90: request granted
* 91: request rejected or failed
* 92: request rejected becasue SOCKS server cannot connect to
* identd on the client
* 93: request rejected because the client program and identd
* report different user-ids
*/
<span style="color:blue short DSTPORT;<span style="color:green //is ignored
<span style="color:blue int DSTIP;<span style="color:green //is ignored
};
<span style="color:blue int main(<span style="color:blue int argc,<span style="color:blue char** argv){
<span style="color:blue int retval = 0;
DWORD numberBytesSent = 0;
sockaddr_in param;
WSAData wsaparam;
DWORD flag = 0;
SOCKS4CONNECT connectstruct = {0x04,<span style="color:green //version 4
0x01,<span style="color:green //we request a connect
htons(80),<span style="color:green //we want to connect to port 80
inet_addr(<span style="color:#a31515 "173.194.69.94"),<span style="color:green
};
SOCKS4RESPONSE responsestruct = {0,0,0,0};
<span style="color:green //preparation for using socks-proxy
WSABUF SOCKS4connectrequest,SOCKS4response;<span style="color:green //will hold the data to pass upon connectionestablishment
SOCKS4connectrequest.buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(&connectstruct);
SOCKS4connectrequest.len = <span style="color:blue sizeof(connectstruct);
SOCKS4response.buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(&responsestruct);
SOCKS4response.len = <span style="color:blue sizeof(responsestruct);
<span style="color:green //if the following string has the wrong format it leads to a timeout-error or no answer at all request ends with 2 rn
<span style="color:blue char content[] = <span style="color:#a31515 "GET / HTTP/1.1 rnHost: 173.194.69.94rnrn";
retval = WSAStartup(MAKEWORD(2,2),&wsaparam);
<span style="color:blue if(retval != 0)
<span style="color:blue return -1;
<span style="color:green //regular syntax of Berklysockets are supportes as well so you could use socket(af,type,protocoll) as well
SOCKET sock = WSASocket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,0,0);<span style="color:green //later on add WSA_FLAG_OVERLAPPED instead of the last 0 and change the behaviour of WSASend to gain more performance
<span style="color:blue if(sock == INVALID_SOCKET)
<span style="color:blue return -1;
param.sin_family = AF_INET;
param.sin_port = htons(1080);
<span style="color:green //param.sin_addr.S_un.S_addr = inet_addr(inet_ntoa(*(in_addr*)gethostbyname("www.google.com")->h_addr_list[0]));
param.sin_addr.S_un.S_addr = inet_addr(<span style="color:#a31515 "92.114.207.203");<span style="color:green //address of socks4proxy
retval = WSAConnect(sock,(sockaddr*)¶m,<span style="color:blue sizeof(param),NULL,NULL,NULL,NULL);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
WSABUF sendarray[1],recvarray[1];
sendarray[0].buf = content;
sendarray[0].len = <span style="color:blue sizeof(content);
retval = WSASend(sock,&SOCKS4connectrequest,1,&numberBytesSent,0,0,0);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
<span style="color:blue else{
retval = WSARecv(sock,&SOCKS4response,1,&numberBytesSent,&flag,NULL,NULL);
<span style="color:blue if(retval != 0){
retval = WSAGetLastError();
<span style="color:blue return -1;
}
}
<span style="color:blue if(<span style="color:blue reinterpret_cast<SOCKS4RESPONSE*>(SOCKS4response.buf)->CD != 90)
<span style="color:blue return -1;
retval = WSASend(sock,sendarray,1,&numberBytesSent,0,0,0);
<span style="color:blue if(retval != 0)
<span style="color:blue return -1;
recvarray[0].buf = <span style="color:blue reinterpret_cast<<span style="color:blue char*>(malloc(<span style="color:blue sizeof(<span style="color:blue char) * 1024));
recvarray[0].len =_msize(recvarray[0].buf);
memset(<span style="color:blue reinterpret_cast<<span style="color:blue void*>(recvarray[0].buf),0,recvarray[0].len);
retval = WSARecv(sock,recvarray,1,&numberBytesSent,&flag,NULL,NULL);<span style="color:green /*this time #Bytes received*/
<span style="color:blue if(retval != 0)
retval = WSAGetLastError();
<span style="color:blue if(retval == WSAEFAULT){
<span style="color:blue return -1;
}
std::cout<<<span style="color:#a31515 "here is the output"<<std::endl<<recvarray[0].buf<<std::endl;
std::cin.get();
free(<span style="color:blue reinterpret_cast<<span style="color:blue void*>(recvarray[0].buf));
closesocket(sock);
WSACleanup();
<span style="color:blue return 0;
}
[/code]
<br/>
Thanks.
Sincerely
<br/>
View the full article