LINUX.ORG.RU

Как узнать сетевой интерфейс от которого пришел пакет на raw socket.

 , ,


0

1

Есть raw socket.

s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
Слушаю сокет так
length = recvfrom(s, buffer, BUF_SIZE, 0, NULL, NULL);
Принимаю пакеты со всех интерфейсов. Нужно только с одного. Пробовал это
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
    (void *)&ifr_tmp, sizeof(ifr_tmp)) < 0) 
{
   perror("SO_BINDTODEVICE failed");
}
Ошибки нет, но и эффекта . Собственно вопрос в том получать пакеты только с одного интерфейса или как получать все пакеты , но узнавать c какого интерфейса они пришли.

Встречный вопрос

За что отвечает пятый параметр recvfrom, который у тебя NULL?

Stil ★★★★★ ()

man packet:

To only get packets from a specific interface use bind(2) specifying an address in a struct sockaddr_ll to bind the packet socket to an interface.

И это работает!

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

а можно ссылку откуда инфа . просто я нашел только это

 int bind(int sockfd, const struct sockaddr *addr,
         socklen_t addrlen);
. НЕ sockaddr_ll.

xionovermazes ()
Ответ на: комментарий от xionovermazes

а можно ссылку откуда инфа

В первой же строке поста.

tailgunner ★★★★★ ()
Ответ на: Встречный вопрос от Stil

понял. тогда можно спросить чем заполнять эту структуру (sockaddr)

struct sockaddr
  {
    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
    char sa_data[14];		/* Address data.  */
  };

xionovermazes ()
Ответ на: комментарий от xionovermazes

За что отвечает пятый параметр recvfrom, который у тебя NULL?

понял. тогда можно спросить чем заполнять эту структуру (sockaddr)

Смотри man: её заполнять не надо.

А вот уже посоветовали bind. Вот там как раз надо.

gag ★★★★★ ()

> Собственно вопрос в том получать пакеты только с одного интерфейса

ВНЕЗАПНО, bind() умеет биндиться на интерфейс.

DELIRIUM ☆☆☆☆☆ ()

Вот посмотри в моей программе. https://github.com/xverizex/da/blob/master/main.c Там функция есть.

char *know_device(char *caddr)
В этой функции есть функция
int membership(char *address, char *caddr, char *mask);
В функции know_device проверяются все сетевые устройства, которые есть. Потом адрес твой и адрес , который нужно проверить на принадлежность к сети отправляются в функцию membership. В этоге возвращается один или ноль.

u0atgKIRznY5 ()

Что-то я не то посоветовал, мой способ для локальной сети подходит только.

u0atgKIRznY5 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.