我正在Macbook主机上使用Ubuntu 16.04在虚拟机上 (使用virtualbox)工作。
在虚拟机中,我有4个网络接口:
-NAT接口(默认接口)
- 仅限主机的界面
- 桥接接口
- 环回接口
他们都处于混杂模式。
我需要使用原始套接字来发送和接收数据。
我像这样设置原始套接字:(从输入中读取接口名称)
#define ETH_TYPE 0x4148
unsigned char* interface = "..."; /* INTERFACE NAME FROM INPUT */
int raw_socket = 0; // Socket descriptor
struct sockaddr_ll socket_address;
struct ifreq ifr;
int ifindex = 0; /*Ethernet Interface index*/
/*Broadcast address - all 1's*/
unsigned char bcast_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
/* Open socket */
raw_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_TYPE));
if (raw_socket == -1)
{
perror("socket():");
exit(1);
}
/*Get ethernet interface index*/
strncpy(ifr.ifr_name, (const char*) interface, IFNAMSIZ);
if (ioctl(raw_socket, SIOCGIFINDEX, &ifr) == -1)
{
perror("SIOCGIFINDEX");
exit(1);
}
ifindex = ifr.ifr_ifindex;
/*retrieve corresponding MAC*/
if (ioctl(raw_socket, SIOCGIFHWADDR, &ifr) == -1)
{
perror("SIOCGIFINDEX");
exit(1);
}
/*prepare sockaddr_ll*/
socket_address.sll_family = PF_INET;
socket_address.sll_protocol = htons(ETH_TYPE);
socket_address.sll_ifindex = ifindex;
socket_address.sll_pkttype = PACKET_BROADCAST;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_addr[0] = bcast_mac[0];
socket_address.sll_addr[1] = bcast_mac[1];
socket_address.sll_addr[2] = bcast_mac[2];
socket_address.sll_addr[3] = bcast_mac[3];
socket_address.sll_addr[4] = bcast_mac[4];
socket_address.sll_addr[5] = bcast_mac[5];
socket_address.sll_addr[6] = 0x00;
socket_address.sll_addr[7] = 0x00;
我发送 :
void socketSend(string network_string)
{
sendto(raw_socket, network_string.data(), network_string.length(), 0, (struct sockaddr*) &socket_address, sizeof (socket_address));
}
并收到 :
unsigned char* buffer_incoming = new unsigned char[ETHER_MAX_LEN];
recvfrom(raw_socket, buffer_incoming, ETHER_MAX_LEN, 0, NULL, NULL);
问题是仅在使用环回接口时才收到。
如果我使用其他3个接口中的任何一个作为接口,则可以发送但不接收。
我知道它发送,因为使用tcpdump可以看到来自指定接口的流量。
有没有办法可以使用其他接口之一?
因为我需要将流量从一台机器发送到另一台机器,所以我认为环回接口对我来说毫无用处。