Решено: Привязка сокета к сетевой карте

Модератор: Модераторы разделов

nill
Сообщения: 146

Решено: Привязка сокета к сетевой карте

Сообщение nill »

Начал писать на C небольшую программку для работы с сетью и столкнулся с непонятной для себя ситуацией.
Суть в следующем. Внешнее устройство отправляет данные на компьютер голыми ethernet кадрами, нужно организовать их прием. Я открываю сокет и пытаюсь привязать его к определённой сетевой карте следующим образом:

Код:

int createSocket(char *dev_name) { // Create communication socket and bind it with the specified net interface. // _in char *dev_name - name of the net interface to use; // _out int - socket descriptor. struct sockaddr_ll sock_param; struct ifreq ifr; int sockd; // create socket sockd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sockd < 0) { perror("Can not create raw socket"); return -1; } // bind the socket to the specified net interface memset((void *)&ifr, 0, sizeof(struct ifreq)); sprintf(ifr.ifr_name, "%s", dev_name); if (setsockopt(sockd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr)) < 0) { perror("Can not bind socket to the specified net interface"); close(sockd); return -1; } return sockd; }

Далее я читаю данные из сокета функцией recvfrm, извлекаю MAC адреса и вывожу их на экран. При установке интерфейса eth0 выводятся некие MAC адреса, в т.ч. и моей сетевой карты. На этом интерфейсе у меня инет. А если установить интерфейс eth1, к которому в данный момент ничего не подключено, то выводятся те же адреса, что и в случае с eth0. Но ведь через этот интерфейс нет траффика и ничего не должно выводиться. Почему не осуществляется привязка? Где я не прав?
Спасибо сказали:
nill
Сообщения: 146

Re: Решено: Привязка сокета к сетевой карте

Сообщение nill »

Вношу небольшое уточнение. После связывание сокета с сетевой картой я проверяю MAC адрес

Код:

if (ioctl(sockd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); } else ...

Адрес соответствует выбранной сетевой карте. Получается, что связывание происходит. Поэтому уточняю свой вопрос: почему я получаю данные с другого сетевого интерфейса и можно ли их отфильтровать срествами ОС?
Спасибо сказали:
Аватара пользователя
кодировщик
Сообщения: 974
Статус: зарёган в пятницу 13
ОС: Linux

Re: Решено: Привязка сокета к сетевой карте

Сообщение кодировщик »

Если не трудно выложите весь код.
Спасибо сказали:
Аватара пользователя
Gloomy
Сообщения: 340
Статус: сочувствующий

Re: Решено: Привязка сокета к сетевой карте

Сообщение Gloomy »

1) SO_BINDTODEVICE корректно работает не во всех системах;

2) даже если SO_BINDTODEVICE работает в твоей системе, для RAW-сокетов существуют специальные опции, позволяющие биндить сетевые интерфейсы. Замечу к слову что режим PACKET_MR_PROMISC поддерживается не всеми сетёвками и не всеми системами;

3) SIOCGIFHWADDR возвращает MAC девайса, переданный в поле ifr_name структуры ifreq. В это поле ты предварительно записал значение переменной dev_name - вот и получил корректный MAC;

4) обязательно нужно изобретать велосипед, снифферя сеть врукопашную через RAW-сокеты? Не вижу, отчего бы не воспользоваться libpcap, где все давно уже реализовано, отлажно и проверено в сотнях проектов :rolleyes:
Спасибо сказали:
nill
Сообщения: 146

Re: Решено: Привязка сокета к сетевой карте

Сообщение nill »

Разобрался с функцией bind(). Похоже, что теперь работает.
А за libpcap отдельное спасибо. Эта библиотеке мне на глаза не попадалась, когда искал информацию. Позже попробую и её.
Спасибо сказали:
Аватара пользователя
Gloomy
Сообщения: 340
Статус: сочувствующий

Re: Решено: Привязка сокета к сетевой карте

Сообщение Gloomy »

Разобрался с функцией bind()

Главное помнить что эта функция привязывает сокет к IP, а не к интерфейсу. Так что не удивляйся если вдруг не сможешь ловить широковещательные пакеты.
Спасибо сказали: