повторно отправлять пакеты через сокеты RAW в Linux

Это необходимо для чтения необработанных данных с одного интерфейса и отправки их через другой.

open&&config(то же самое для sock_raw_outer):

sock_raw_inner = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
setsockopt(sock_raw_inner, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 4);
struct ifreq if_idx1;
memset(&if_idx1, 0, sizeof(struct ifreq));
strncpy(if_idx1.ifr_name, opt, strlen(opt));
ioctl(sock_raw_inner, SIOCGIFINDEX, &if_idx1);

затем в цикле:

data_size = recvfrom(sock_raw_inner, buffer, 65536, MSG_DONTWAIT, NULL, NULL);
    if (data_size > 0) {
        struct sockaddr_ll socket_address;
        socket_address.sll_ifindex = if_idx2.ifr_ifindex;
        socket_address.sll_halen = ETH_ALEN;
        //copy dest
        socket_address.sll_addr[0] = buffer[0];
        socket_address.sll_addr[1] = buffer[1];
        socket_address.sll_addr[2] = buffer[2];
        socket_address.sll_addr[3] = buffer[3];
        socket_address.sll_addr[4] = buffer[4];
        socket_address.sll_addr[5] = buffer[5];
        sendto(sock_raw_outer, buffer, size, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll))
    }

затем, если я ловлю на sock_raw_inner какой-либо пакет (например, запрос arp), он снова и снова отправляется на sock_raw_inner с помощью sendto. Что случилось? Спасибо.


person M. Artem    schedule 04.05.2016    source источник


Ответы (1)


Ваш sock_raw_inner все еще прослушивает каждый интерфейс, потому что привязка к eth0, которую вы пытаетесь выполнить, не поддерживается. Таким образом, пакет, отправленный на другой интерфейс, действительно затем принимается вашим sock_raw_inner.

Выдержка из сокета man (7) (выделено жирным шрифтом)

SO_BINDTODEVICE Привязать этот сокет к определенному устройству, такому как «eth0», как указано в переданном имени интерфейса. Если имя представляет собой пустую строку или длина параметра равна нулю, привязка устройства сокета удаляется. Передаваемый параметр представляет собой строку имени интерфейса переменной длины, оканчивающуюся нулем, с максимальным размером IFNAMSIZ. Если сокет привязан к интерфейсу, сокетом обрабатываются только пакеты, полученные от этого конкретного интерфейса. Обратите внимание, что это работает только для некоторых типов сокетов, особенно для сокетов AF_INET. Не поддерживается для пакетных сокетов (используйте там обычную привязку(8)).

person Tezirg    schedule 04.05.2016
comment
моя ошибка :( Спасибо! - person M. Artem; 04.05.2016