Вопрос

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

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

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

Это было полезно?

Решение

В Linux вы используете сокет PF_PACKET для чтения данных с необработанного устройства, например интерфейса 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 напрямую, используя setockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, ).(ПРЕДУПРЕЖДЕНИЕ:Ядро использует структуру sock_fprog, а не структуру bpf_program, не путайте их, иначе ваша программа не будет работать на некоторых платформах).

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

libpcap также абстрагирует интерфейс ядра от кода вашего приложения.Linux и BSD используют схожие API, но Solaris требует DLPI, а 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 для обработки пакетов по мере их поступления.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top