开发者

Trying to parse decimal dstAddr.sin_addr.s_addr from recv() char array

i am trying to write a small socks proxy as an excercise.

I am trying to parse a SOCKS Connection request from an incoming connection. The socks protocol specifies that the desired destination adress be byte 4,5,6,7 and the desired port be byte 2,3 (byte 0 and 1 are protocol commands). So i want to parse this information to set up an outgoing connection from the proxy and then to pass back and forth the data between the sockets. I am fairly new to C, but i figured i start with something that keeps me interested so bear with me if theres are horrible newbie mistakes :)

The IP-Adress and the Port get calculated incorrectly for border values, typically it is often 254 short. It must be something fairly obvious i am missing but i just don't get it yet :-)

This is the code i currently have:

enter code here

void ProxyData(int rcvSocket)
{
char rcvBuffer[RCVBUFSIZE];        
int recvMsgSize;                   
char Socks4Response[] = "\x00\x5a\x00\x00\x00\x00\x00\x00";

int dstSocket;
int dstIP;
struct sockaddr_in dstAddr;
int dstPort;

if ((recvMsgSize = recv(rcvSocket, rcvBuffer, RCVBUFSIZE, 0)) < 0)
     perror("recv() failed");
dstIP = (rcvBuffer[4]*16777216)+(rcvBuffer[5]*65536)+(rcvBuffer[6]*256)+rcvBuffer[7];
dstPort = rcvBuffer[2]*256+rcvBuffer[3];
if ((rcvBuffer[0] == 0x04))
     send(rcvSocket, Socks4Response, 9, 0);
if((dstSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
     perror("socket() failed"); 

memset(&dstAddr, 0, sizeof(dstAddr));
dstAddr.sin_family           = AF_INET;
dstAddr.sin_addr.s_addr      = htonl(dstIP);
dstAddr.sin_port             = htons(dstPort);

if (connect(dstS开发者_运维技巧ocket, (struct sockaddr *) &dstAddr, sizeof(dstAddr)) < 0 )
     perror("connect() failed");
while (recvMsgSize > 0) 
  { stuff }
close(rcvSocket);
close(dstSocket);
}


There's no question in your questions, but assuming you want us to help debug the code. An issue that jumps out directly is this:

char rcvBuffer[RCVBUFSIZE];
...
dstIP = (rcvBuffer[4]*16777216)+(rcvBuffer[5]*65536)+(rcvBuffer[6]*256)+rcvBuffer[7];

Most compilers treat char as signed, which means it can be negative. the addition above assumes it's unsigned. You should change it thus.

However, you could just cast it.

struct in_addr *dstIP = (struct in_addr*)(rcvBuffer + 4);

Now dstIP will be correct and already in network byte order, so no need for htonl:

dstAddr.sin_addr = *dstIP;

Same with the port, the type is in_port_t.


You can simply use memcpy() to copy the address and port directly into the struct sockaddr_in:

dstAddr.sin_family = AF_INET;
memcpy(&dstAddr.sin_addr.s_addr, &rcvBuffer[4], 4);
memcpy(&dstAddr.sin_port, &rcvBuffer[2], 2);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜