我在VirtualBox上安装的Ubuntu 17.04上运行http://hacked10bits.blogspot.co.uk/2011/12/sending-raw-ethernet-frames-in-6-easy.html上的ethersend.c程序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h> /* Must precede if*.h */
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
union ethframe
{
struct
{
struct ethhdr header;
unsigned char data[ETH_DATA_LEN];
} field;
unsigned char buffer[ETH_FRAME_LEN];
};
int main(int argc, char **argv) {
char *iface = "enp0s3";
unsigned char dest[ETH_ALEN]
= { 0x08, 0x00, 0x27, 0x1e, 0x7f, 0x5c };
unsigned short proto = 0x1234;
unsigned char *data = "hi";
unsigned short data_len = strlen(data);
int s;
if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
printf("Error: could not open socket\n");
return -1;
}
struct ifreq buffer;
int ifindex;
memset(&buffer, 0x00, sizeof(buffer));
strncpy(buffer.ifr_name, iface, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
printf("Error: could not get interface index\n");
close(s);
return -1;
}
ifindex = buffer.ifr_ifindex;
unsigned char source[ETH_ALEN];
if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
printf("Error: could not get interface address\n");
close(s);
return -1;
}
memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
ETH_ALEN);
union ethframe frame;
memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
memcpy(frame.field.header.h_source, source, ETH_ALEN);
frame.field.header.h_proto = htons(proto);
memcpy(frame.field.data, data, data_len);
unsigned int frame_len = data_len + ETH_HLEN;
struct sockaddr_ll saddrll;
memset((void*)&saddrll, 0, sizeof(saddrll));
saddrll.sll_family = PF_PACKET;
saddrll.sll_ifindex = ifindex;
saddrll.sll_halen = ETH_ALEN;
memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
if (sendto(s, frame.buffer, frame_len, 0,
(struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
printf("Success!\n");
else
printf("Error, could not send\n");
close(s);
return 0;
}
VM有两个MAC地址接口,如下所述:
enp0s3 08:00:27:1f:fc:2b
enp0s8 08:00:27:1e:7f:5c
我将帧从enp0s3发送到目的地08:00:27:1e:7f:5c,即发送到enp0s8。
当我使用tcpdump监听enp0s3时,我可以看到数据包:
sam@sam:~$ sudo tcpdump -A -i enp0s3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
16:04:55.868207 08:00:27:1f:fc:2b (oui Unknown) > 08:00:27:1e:7f:5c (oui
Unknown), ethertype Unknown (0x1234), length 16:
0x0000: 6869 hi
hi
然而,当我使用tcpdump(数据包应该到达)监听enp0s8时,我在tcpdump中看不到输出。
为什么数据包没有到达enp0s8?
编辑: enp0s3是NAT适配器,enp0s8是仅限主机的适配器。可能是导致问题的原因。现在我添加了另一个名为enp0s9的仅限主机的适配器,现在通信间歇性地工作。为什么它总是不起作用?