我正在尝试编写一个小袜子代理作为练习。
我正在尝试从传入连接解析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);
}
答案 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);