为什么我的程序不发送ARP请求(c ++)?

时间:2012-08-24 15:41:28

标签: c++ linux arp raw-sockets

我正在学习使用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);

2 个答案:

答案 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_addrt_in_addr

编辑:Alan Curry指出您要从4个字节长的对象复制6个字节。

但是,动态分配看起来似乎没有任何好处,您应该在堆栈中创建s_in_addrt_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")