Чтение с разнородного сетевого устройства - PullRequest
9 голосов
/ 22 сентября 2008

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

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

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

Ответы [ 5 ]

17 голосов
/ 22 сентября 2008

В Linux вы используете сокет PF_PACKET для чтения данных с необработанного устройства, такого как интерфейс Ethernet, работающий в случайном режиме:

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

Это отправит копии каждого полученного пакета на ваш сокет. Вполне вероятно, что вам не нужен каждый пакет. Ядро может выполнять фильтрацию первого уровня с использованием BPF, Berkeley Packet Filter . 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 использует что-то другое.

7 голосов
/ 23 октября 2008

Мне когда-то приходилось слушать необработанные кадры Ethernet, и в итоге я создал обертку для этого. Вызвав функцию с именем устройства ex 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 для обработки пакетов по мере их поступления.

2 голосов
/ 22 сентября 2008

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

0 голосов
/ 22 января 2015

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

0 голосов
/ 22 сентября 2008

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

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

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