2017-01-31 17 views
0

Существует две программы Linux C, одна из которых называется «отправитель», другая - «приемник». Обе программы используют raw (пакетные) сокеты в одном сетевом интерфейсе (eth0). Они обмениваются данными, используя собственный протокол ethernet (тип). Да, дело в том, что иметь доступ к необработанным сетям Ethernet.Дополнительные сокеты (пакетные) не могут связываться с одним и тем же сетевым интерфейсом

Гнезда открываются каким-то образом, как это:

sock = socket(AF_PACKET, SOCK_RAW, htons(MY_CUSTOM_ETH_PROTOCOL)); 

вопросы приемника это, чтобы читать из сырого сокета:

recv(sock, eth_frame, MAX_ETH_FRAME_LEN, 0); 

вопросы отправителя, чтобы это написать на сырой сокет:

struct sockaddr_ll sa; 

memset(&sa, 0, sizeof(sa)); 
sa.sll_family = AF_PACKET; 
memcpy(sa.sll_addr, dst_mac, 6); 
sa.sll_halen = 6; 
sa.sll_ifindex = itf_idx; 

Надеюсь, вам не нужно делиться тем, как я собираю действительные сетевые кадры, как я получаю сетевой интерфейс в dex и т. д.

Проблема: Если две программы работают на одной машине, приемник не может видеть кадры Ethernet, испускаемые отправителем. Однако Wireshark может видеть их всех.

Если две программы работают на отдельных машинах, подключенных к коммутатору, приемник получает кадры ethernet, испускаемые отправителем.

В первом случае не видно никаких признаков ошибок.

Что это может быть? Мне нужно сделать raw-сокет, способный получать все необработанные сетевые кадры, которые помещаются на проводе другими сырыми сокетами.

+0

Похоже, вы привязываетесь к определенному интерфейсу. Когда вы это делаете, вы устанавливаете 'sll_pkttype' в' PACKET_OUTGOING'? См. 'Man packet (7)'. –

+0

'man 7 packet' говорит:« _... и PACKET_OUTGOING для пакета, исходящего от локального хоста, который зацикливается на пакетном сокете. Эти типы имеют смысл только для получения ». Кстати, bind (...) isn 't, но используется индекс интерфейса выбранной сети itf. Я также попытался привязаться к net itf, без каких-либо успехов ... и Wireshark все еще видит фреймы. – tselmeci

+0

Кроме того: «Когда вы отправляете пакеты, достаточно указать sll_family, sll_addr, sll_halen, sll_ifindex и sll_protocol. Другие поля должны быть равны 0. sll_hatype и sll_pkttype установлены на принятые пакеты для вашей информации. Для привязки только sll_protocol и sll_ifindex._ " – tselmeci

ответ

0

Разрешение: если я создаю сокет так:

socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 

все Ethernet кадры принимаются. Поскольку мое программное обеспечение содержит фильтрацию на основе типа фрейма ethernet, он может выбирать кадры ethernet, принадлежащие настраиваемому протоколу.

Спасибо!