2013-12-19 4 views
0

Я работаю с Linux (Debian) и C.Разъемы Linux C - Связанный сокет принимает пакеты от другого интерфейса?

Я открыл сокет к интерфейсам - eth0 и eth1 с помощью следующей функции:

// Opening the socket 
    mSocket = socket(device->ifa_addr->sa_family, SOCK_RAW | SOCK_NONBLOCK, 
       htons(ETH_P_ALL)); 
    if (mSocket == -1) 
    { 
     throw CException("socket is bad"); 
    } 

    // Adding flag to the socket to work only on a specific interface 
    if (setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE, 
      (void *) &mIfreq, sizeof(mIfreq)) < 0) 
    { 
     throw CException(
       "Failed to add binding to specific interface flag"); 
    } 

в то время как ifreq держит имя интерфейса:

strncpy(mIfreq.ifr_ifrn.ifrn_name,device->ifa_name, IF_NAMESIZE); 

следующая вещь, которую я делаю, это прием пакетов, используя следующий код:

recvSize = recvfrom(mSocket, buffer, ETH_FRAME_LEN, 0, NULL, 
        NULL); 

вопросы:

1) почему, если оба интерфейса не подключены ни к чему, не из розеток могут быть открыты

2 *) почему (без потери общности), если eth0 подключен и eth1 ISN» т я могу открыть сокеты для каждого из них

2,1 *) почему при чтении из сокета eth1 я получаю все пакеты, полученные в eth0

(Wireshark на eth1 не показывает каких-либо пакет, как это должно быть)

[мое предположение - это то Linux вина (делать вещи за моей спиной?)]

Спасибо заранее,

Despair

+0

Что содержит 'mIfreq'? как он определяется? – Hasturkun

+1

Как «бросать CException (...)» и использовать C вместе? – glglgl

+0

ifreq был инициализирован только именем ETH0/1. – Despair

ответ

4

Предполагая, что вы хотите захватить необработанные данные так же, как это делает Wireshark.

socket(7) четко заявляет, что SO_BINDTODEVICE не относится к пакетным сокетам. Вы должны указать bind ваш сокет на адрес sockaddr_ll с номером sll_ifindex, указанным в поле интерфейса (см. packet(7)). Номер интерфейса можно получить из его имени (например, «eth0»), используя SIOCGIFINDEXioctl (см. netdevice(7)).

+0

Привет, спасибо за ваш ответ. У меня есть ifaddr struct, которая хранит 'mIfreq.ifr_ifru.ifru_ivalue' , когда я пытаюсь связать, используя этот индекс, я получаю отказ Недопустимый аргумент. Не пропустите ни одного параметра? – Despair

+0

'sockaddr_ll addr; \t \t addr.sll_family = AF_PACKET; \t \t addr.sll_ifindex = mInterfaceIndex; // 2 \t \t, если (связывания (mSocket, (SOCKADDR *) & адр, SizeOf (SOCKADDR)) <0) \t \t { \t \t \t PError ("Bind"); \t \t} ' – Despair

+0

Возможно, вам придется обнулить остальные поля. 'sockaddr_ll addr = {0};' – rkhayrov

Смежные вопросы