尝试从recv()char数组中解析十进制dstAddr.sin_addr.s_addr

时间:2011-08-25 20:03:43

标签: c sockets

我正在尝试编写一个小袜子代理作为练习。

我正在尝试从传入连接解析SOCKS连接请求。 socks协议指定所需的目标地址是字节4,5,6,7,所需的端口是字节2,3(字节0和1是协议命令)。所以我想解析这些信息,以便从代理设置传出连接,然后在套接字之间来回传递数据。我对C来说相当新,但我认为我从一些让我感兴趣的东西开始,所以如果有可怕的新手错误,请耐心等待:))

IP-Adress和端口的边界值计算不正确,通常通常为254短。它必须是一个相当明显的东西我想念但我还没有得到它: - )

这是我目前的代码:

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(dstSocket, (struct sockaddr *) &dstAddr, sizeof(dstAddr)) < 0 )
     perror("connect() failed");
while (recvMsgSize > 0) 
  { stuff }
close(rcvSocket);
close(dstSocket);
}

2 个答案:

答案 0 :(得分:1)

您的问题毫无疑问,但假设您希望我们帮助调试代码。 直接跳出的问题是:

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

大多数编译器将char视为已签名,这意味着它可能是否定的。上面的补充假设它是未签名的。你应该改变它。

但是,你可以投它。

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

现在dstIP将是正确的并且已经处于网络字节顺序,因此不需要htonl:

dstAddr.sin_addr = *dstIP;

与端口相同,类型为in_port_t

答案 1 :(得分:0)

您只需使用memcpy()将地址和端口直接复制到struct sockaddr_in

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