我使用原始套接字将TCP数据包从计算机B发送到计算机A.
首先,我创建一个套接字
int s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
告诉内核不要为我填充ip header,因为我的数据包括ip header和tcp header
int optval = 1;
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval));
并设置目的地地址
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(33333);
addr.sin_addr.s_addr = inet_addr("192.168.200.135");
并发送数据
sendto(s, data, len, 0, (struct sockaddr*)&addr, sizeof(addr));
我的网络环境如下图所示
在案例A中,两台计算机通过交换机连接。在案例B中,计算机B连接到路由器,路由器连接到交换机。
我的程序在案例A中工作正常。我可以使用原始套接字在计算机A上接收数据包,并且可以使用wireshark来捕获该数据包。
在案例B中,我可以从计算机B ping到计算机A,从B到S从s.S和我可以在计算机A上使用原始套接字和wireshark来捕获在B和A之间发送的一些TCP数据包。但是,我的原始套接字在计算机B上发送的数据包无法在A上捕获。似乎路由器不转发我的数据包。我的包裹有什么问题吗?
我的分组数据发送程序如下:
//data to send
char data[48] =
{
//iphdr:
0x45, 0x00, 0x00, 0x30, //version:4 header_length:5 TOS:0 length:0x30
0x00, 0x01, 0x00, 0x00, //identification:1 flags:0 fragment_offset:0
0x40, 0x06, 0x2f, 0x47, //TTL:0x40 protocol:6(TCP) header_checksum:0x2f47
0xc0, 0xa8, 0x01, 0xa8, //source_IP:192.168.1.168
0xc0, 0xa8, 0xc8, 0x87, //destination_IP:192.168.200.135
//tcphdr:
0x56, 0xce, 0x82, 0x35, //source_port:22222 destination_port:33333
0x00, 0x00, 0x00, 0x00, //sequence_number:0
0x00, 0x00, 0x00, 0x00, //ack_number:0
0x50, 0x00, 0xaa, 0xaa, //header_length:5 window_size:0xaaaa
0xeb, 0xbd, 0x00, 0x00, //checksum:0xebbd urgent_pointer:0
//tcp content:
0x7a, 0x68, 0x73, 0x00,
0x39, 0x30, 0xce, 0x56,
};
int len = 48;
//open the socket
int s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
//don't fill header
int optval = 1;
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval));
//destination addr
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("192.168.200.135");
//send
sendto(s, data, len, 0, (struct sockaddr*)&addr, sizeof(addr));
答案 0 :(得分:0)
答案 1 :(得分:0)
您的TCP标头错误,因为它错过了标记。对于您的测试,您至少应该设置SYN标志。标题可能还有其他不正确之处。
因此,如果路由器实际上正在检查TCP标头,它可能会丢弃您的数据包。如果您的路由器实际上没有路由但使用NAT进行数据包转发,或者如果有防火墙检查端口或连接状态,则会检查TCP标头。