Чтение с разнородного сетевого устройства

Я хочу написать инструмент анализа в реальном времени для беспроводного трафика.

Кто-нибудь знает, как читать с разнородного (или нюхающего) устройства в C?

Я знаю, что для этого вам нужен root-доступ. Мне было интересно, если кто-нибудь знает, какие функции необходимы для этого. Обычные сокеты здесь не имеют смысла.

 jbleners22 сент. 2008 г., 15:27
да, тег тоже
 GEOCHET22 сент. 2008 г., 15:19
В линуксе? В вашем сообщении не указана ОС, но мы должны предполагать, что вы используете «root». ты имеешь ввиду linux?

Ответы на вопрос(5)

WireShark в Linux имеет возможность собирать информацию заголовка PLCP (протокол конвергенции физического уровня).

Почему бы вам не использовать что-то вродеWireShark?

Это открытый исходный код, так что, по крайней мере, вы можете извлечь из него несколько вещей, если не хотите просто использовать его.

 jbleners22 сент. 2008 г., 15:28
Я не уверен, что WireShark может захватить полный беспроводной пакет. Я думаю, что он настроен на обычный MAC, а не беспроводной MAC. Мне нужно иметь возможность смотреть на трафик из нескольких essids.
 22 сент. 2008 г., 15:32
Опять же, я бы начал с просмотра исходного кода wireshark.
 23 окт. 2008 г., 12:50
WireShark не работает с беспроводными картами в Windows (полная остановка).

Мне когда-то приходилось слушать необработанные кадры Ethernet, и в итоге я создал обертку для этого. Вызывая функцию с именем устройства, напримерeth0 Взамен я получил розетку, которая была в беспорядочном режиме. Что вам нужно сделать, это создать необработанный сокет и затем перевести его в беспорядочный режим. Вот как я это сделал.

int raw_init (const char *device)
{
    struct ifreq ifr;
    int raw_socket;

    memset (&ifr, 0, sizeof (struct ifreq));

    /* Open A Raw Socket */
    if ((raw_socket = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 1)
    {
        printf ("ERROR: Could not open socket, Got #?\n");
        exit (1);
    }

    /* Set the device to use */
    strcpy (ifr.ifr_name, device);

    /* Get the current flags that the device might have */
    if (ioctl (raw_socket, SIOCGIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not retrive the flags from the device.\n");
        exit (1);
    }

    /* Set the old flags plus the IFF_PROMISC flag */
    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl (raw_socket, SIOCSIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not set flag IFF_PROMISC");
        exit (1);
    }
    printf ("Entering promiscuous mode\n");

    /* Configure the device */

    if (ioctl (raw_socket, SIOCGIFINDEX, &ifr) < 0)
    {
        perror ("Error: Error getting the device index.\n");
        exit (1);
    }

    return raw_socket;
}

Затем, когда у вас есть сокет, вы можете просто использовать команду select для обработки пакетов по мере их поступления.

Решение Вопроса

ного устройства, такого как интерфейс Ethernet, работающий в смешанном режиме:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

Это отправит копии каждого полученного пакета на ваш сокет. Впрочем, вполне вероятно, что вам не нужен каждый пакет. Ядро может выполнять фильтрацию первого уровня, используя BPF,Беркли пакетный фильтр, BPF - это виртуальная машина на основе стека: она обрабатывает небольшой набор инструкций, таких как:

ldh = load halfword (from packet)  
jeq = jump if equal  
ret = return with exit code  

Код завершения BPF сообщает ядру, копировать ли пакет в сокет или нет. Можно написать относительно небольшие программы BPF напрямую, используя setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,). (ВНИМАНИЕ: Ядро принимает struct sock_fprog, а не struct bpf_program, не путайте их, иначе ваша программа не будет работать на некоторых платформах).

Для чего-то достаточно сложного, вы действительно хотите использовать libpcap. BPF ограничен в том, что он может делать, в частности, в количестве команд, которые он может выполнять для каждого пакета.Libpcap Он позаботится о разделении сложного фильтра на две части, при этом ядро выполнит первый уровень фильтрации, а более мощный код пользовательского пространства отбросит пакеты, которые он на самом деле не хочет видеть.

libpcap также абстрагирует интерфейс ядра от кода вашего приложения. Linux и BSD используют схожие API, но Solaris требует DLPI, а Windows использует что-то другое.

 jbleners22 сент. 2008 г., 16:36
Спасибо за ответ!
 19 окт. 2012 г., 22:41
На самом деле, нет, libpcap не разделит фильтр на две части. Но да, libpcap - это то, что вы хотите использовать - он знает, как перевести интерфейс в смешанный режим на разных платформах (просто используяETH_P_ALL например, недостаточно для Linux; что "SAP разнородный", в котором вы получаете все пакеты независимо от типа протокола, но он не "физически разнородный", в том смысле, что адаптер не будет доставлять на хост одноадресные пакеты, не отправляемые на хост. ).

Вы можете использовать библиотеку pcap (см.http://www.tcpdump.org/pcap.htm), который также используется tcpdump и Wireshark.

Ваш ответ на вопрос