我正在学习使用c ++的低级套接字。我做了一个简单的程序,它将发送一个ARP请求。套接字似乎发送数据包但我无法用Wireshark捕获它。我有另一个小程序也发送ARP数据包,这些数据包由Wireshark捕获(我的程序受到该程序的启发)。
我做错了吗?
删除了代码
修改
删除了代码
编辑2
看来我还需要在数据包中包含以太网头数据,所以我现在制作一个包含以太网头和ARP头数据的数据包。现在数据包消失了,并被Wireshark捕获。但Wireshark说它是无偿的。如您所见,发送方和接收方的IP或MAC地址似乎也未正确设置。
36 13.318179 Cimsys_33:44:55 Broadcast ARP 42 Gratuitous ARP for <No address> (Request)
编辑3
/*Fill arp header data*/
p.arp.ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
p.arp.ea_hdr.ar_pro = htons(ETH_P_IP);
p.arp.ea_hdr.ar_hln = ETH_ALEN; // Must be pure INTEGER, not called with htons(), as I did
p.arp.ea_hdr.ar_pln = 4; // Must be pure INTEGER, not called with htons(), as I did
p.arp.ea_hdr.ar_op = htons(ETH_P_ARP);
答案 0 :(得分:3)
此代码看起来不太正确:
struct in_addr *s_in_addr = (in_addr*)malloc(sizeof(struct in_addr));
struct in_addr *t_in_addr = (in_addr*)malloc(sizeof(struct in_addr));
s_in_addr->s_addr = inet_addr("192.168.1.5"); // source ip
t_in_addr->s_addr = inet_addr("192.168.1.6"); // target ip
memcpy(arp->arp_spa, &s_in_addr, 6);
memcpy(arp->arp_tpa, &t_in_addr, 6);
在memcpy
您关心复制6个字节。但是,您将获取指针类型的地址,这使其成为指针类型的指针。我想你只想传递s_in_addr
和t_in_addr
。
编辑:Alan Curry指出您要从4个字节长的对象复制6个字节。
但是,动态分配看起来似乎没有任何好处,您应该在堆栈中创建s_in_addr
和t_in_addr
变量。不,您不需要更改memcpy
代码。
struct in_addr s_in_addr;
struct in_addr t_in_addr;
s_in_addr.s_addr = inet_addr("192.168.1.5"); // source ip
t_in_addr.s_addr = inet_addr("192.168.1.6"); // target ip
memcpy(arp->arp_spa, &s_in_addr, sizeof(arg->arp_spa));
memcpy(arp->arp_tpa, &t_in_addr, sizeof(arg->arg_tpa));
您的arp
数据包本身存在类似问题。所以你应该把它从堆栈中分配出来。为了防止自己进行大量的代码更改,我将稍微区别地说明一下:
struct ether_arp arp_packet;
struct ether_arp *arp = &arp_packet;
//...
for(int i = 0; i < 10; i++) {
if (sendto(sock, arp, sizeof(arp_packet), 0,
(struct sockaddr *)&sending_socket,
sizeof(sending_socket)) < 0) {
std::cout << "Could not send!" << std::endl;
}
}
答案 1 :(得分:1)
@ user315052说你应该使用memcpy(arp->arp_spa, &s_in_addr, sizeof(arg->arp_spa));
,但是这段代码只是将s_in_addr
的前4个字节复制到arp->arp_spa
,绝对什么都不做!
所以试试这个:
* (int32_t*) arp->arp_spa = inet_addr("192.168.1.1")
* (int32_t*) arp->arp_tpa = inet_addr("192.168.1.2")