通过原始套接字发送源MAC和IP

时间:2015-10-30 20:40:33

标签: c++ sockets network-programming

我对原始套接字有点兴趣,我正在尝试关注this教程。 我可以看到使用wireshark传输的数据包很棒。

但是,该教程中的源MAC和源IP缺失并解释为herehere

问题是当我尝试将源MAC复制到已知结构时:

ioctl(fd,SIOCGIFINDEX,&ifr)   // `fd` and `ifr` already defined
ioctl(fd,SIOCGIFHWADDR,&ifr)

const unsigned char* mac = (unsigned char*)ifr.ifr_hwaddr.sa_data;

printf("my MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",   // prints my mac- works fine
    mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

memcpy(&req.arp_sha, mac, sizeof(req.arp_sha));  // `req` is already defined

当我调试代码时,mac包含真实的MAC地址,req.arp_sha包含其他内容。

我也尝试过这种方式复制:

req.arp_sha[0] = mac[0];
req.arp_sha[1] = mac[1];

修改 我期待的MAC是:08:00:27:E7:56:0B 我获得的MAC是:00:00:0a:00:02:0f

当我对IP地址做同样的事情时,效果很好,我可以在wireshark上看到它。

这是IP代码:

ioctl(fd,SIOCGIFADDR,&ifr);

struct sockaddr_in* ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
const char * myIp = inet_ntoa(ipaddr->sin_addr);
printf("my IP address: %s\n", myIp);

memcpy(&req.arp_spa,&ipaddr->sin_addr,sizeof(req.arp_spa));

我不明白我在这里做错了什么,我很乐意提供指导。

感谢。

1 个答案:

答案 0 :(得分:1)

Is req this type?

struct ether_arp {
    struct   arphdr ea_hdr;         /* fixed-size header */
    u_int8_t arp_sha[ETHER_ADDR_LEN];   /* sender hardware address */
    u_int8_t arp_spa[4];            /* sender protocol address */
    u_int8_t arp_tha[ETHER_ADDR_LEN];   /* target hardware address */
    u_int8_t arp_tpa[4];            /* target protocol address */
};

You are not showing the whole code, are you?

In the first snippet that you say doesn't work, are you calling memcpy immediately after the printf? The only possibility it doesn't work is that mac is a pointer to ifr.ifr_hwaddr.sa_data . Probably the content of sa_data was overwritten when you call

memcpy(&req.arp_sha, mac, sizeof(req.arp_sha));

Try defining mac as an array and copy the content from ifr.ifr_hwaddr.sa_data to mac.

In the second snippet, it should not work well, even though you say it works. This is not OK:

memcpy(&req.arp_spa,&ipaddr->sin_addr,sizeof(req.arp_spa));

sin_addr is an unsigned long, which is little endian while req.arp_spa should be big endian. Are you sure it looks correctly in wireshark? Can you print it?