2008-09-22 3 views
9

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

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

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

+0

В Linux? Ваше сообщение не указывает на ОС, но следует ли предположить, что вы используете «root», то есть Linux? – GEOCHET 2008-09-22 13:19:47

+1

yep, так что тег я думаю – jbleners 2008-09-22 13:27:30

ответ

16

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

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

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

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

0

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

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

+0

Я не уверен, что WireShark может захватить полный беспроводной пакет. Я думаю, что он настроен для обычного MAC не беспроводного MAC. Мне нужно уметь смотреть трафик с нескольких эссейд. – jbleners 2008-09-22 13:28:10

7

Мне когда-то приходилось слушать необработанные ракеты 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 для обработки пакетов по мере их поступления.

0

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

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