Используя сырые сокеты, я получаю только если я использую петлевой интерфейс - PullRequest
0 голосов
/ 26 сентября 2019

Я работаю на виртуальной машине (с использованием virtualbox) с Ubuntu 16.04 на хосте Macbook.

В виртуальной машине у меня есть 4 сетевых интерфейса:
- интерфейс NAT (по умолчанию)
- Только для хоста interface
- Bridged interface
- loopback interface
и все они в беспорядочном режиме.

Мне нужно использовать необработанные сокеты для отправки и получения данных.

I setup необработанный сокет, подобный следующему: (имя интерфейса читается из ввода)

#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);

Проблема являетсячто я получаю, только если я использую интерфейс loopback .
Если я использую в качестве интерфейса любой из трех других, он может отправлять, но не получает.
Я знаю, что отправляет, потому что с tcpdump Я вижу, что есть трафик с указанного интерфейса.

Можно ли использовать один из других интерфейсов?
Поскольку мне нужно отправлять трафик с одногомашина к другому, так что я думаю, что петлевой интерфейс для меня бесполезен.

...