Сокеты Linux AF_PACKET: фильтрация для определенного протокола Ethertype работает только на интерфейсе обратной связи.Linux

Ответить
Anonymous
 Сокеты Linux AF_PACKET: фильтрация для определенного протокола Ethertype работает только на интерфейсе обратной связи.

Сообщение Anonymous »


Я пытаюсь написать приложение, способное отправлять/получать необработанные кадры Ethernet на конкретное сетевое устройство. Дело в том, что я хочу иметь возможность произвольно изменять исходный MAC-адрес и EtherType.

Я знаю, что в Linux можно получить доступ к необработанным данным уровня 2 с помощью сокетов AF_PACKET. В качестве минимального примера я написал серверное приложение, отправляющее необработанные кадры, и клиентское приложение, получающее кадры, используя это руководство в качестве справочного материала. Мой сервер выглядит так:

#include #include #include #include #include #include [*] #include #include #include #include #include #include #include uint8_t src_mac[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; #define DEFAULT_IF "eno1" // #define DEFAULT_IF "ло" #define BUF_SIZ 1024 #define ETHER_TYPE ETH_P_802_EX1 // #define ETHER_TYPE ETH_P_ALL int main(int argc, char *argv[]) { ИНТ Sockfd; структура ifreq if_idx; структура ifreq if_mac; интервал tx_len = 0; символ sendbuf[BUF_SIZ]; struct ether_header *eh = (struct ether_header *) sendbuf; struct sockaddr_ll сокет_адрес = {0}; символ ifName[IFNAMSIZ]; strncpy(ifName, DEFAULT_IF, IFNAMSIZ-1); /* Открыть сокет RAW для отправки */ if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { ошибка("сокет"); } /* Получаем индекс интерфейса для отправки */ memset(&if_idx, 0, sizeof(struct ifreq)); strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1); if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { ошибка("SIOCGIFINDEX"); } /* Получаем MAC-адрес интерфейса для отправки */ memset(&if_mac, 0, sizeof(struct ifreq)); strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1); if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) { ошибка("SIOCGIFHWADDR"); } /* Создаем заголовок Ethernet */ memset (sendbuf, 0, BUF_SIZ); memcpy(dst_mac, if_mac.ifr_ifru.ifru_hwaddr.sa_data, 6); memcpy(eh->ether_dhost, dst_mac, 6); memcpy(eh->ether_shost, src_mac, 6); /* Поле Ethertype */ eh->ether_type = htons(ETHER_TYPE); tx_len += sizeof (struct ether_header); /* Устанавливаем данные, необходимые для отправки */ сокет_адрес.sll_family = AF_PACKET; сокет_адрес.sll_ifindex = if_idx.ifr_ifindex; сокет_адрес.sll_halen = ETH_ALEN; сокет_адрес.sll_protocol = htons(ETHER_TYPE); memcpy(socket_address.sll_addr, dst_mac, ETH_ALEN); /* Заполняем фиктивными данными */ for(int i=0; i
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»