Как мне захватить MAC-адрес точек доступа и подключенных к нему хостов? - PullRequest
2 голосов
/ 24 декабря 2010

Я знаю, что мне нужно использовать библиотеку libpcap для захвата кадров IEEE 802.11, чтобы показать их MAC-адреса, например, мой беспроводной адаптер находится в режиме монитора и поддерживает только «заголовок радиосвязи 802.11 plus radiotap», когда я выполняю pcap_datalink.

В функции обратного вызова pcap_loop, что я должен сделать, чтобы извлечь MAC-адреса из пакетов?Как я различаю разные типы пакетов?Поиск в гугле не дает мне много ответов, в основном о том, как извлечь пакеты из проводных интерфейсов.

 void procPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
 {
         //what should i do here?
 }

  pcap_t *handler=pcap_open_live ("wlan0", BUFSIZ,1,-1,errbuff);
 if(pcap_datalink(handler) == DLT_IEEE802_11_RADIO) 
 {
          pcap_loop(handler, -1 ,procPacket, NULL );              
 }

Ответы [ 2 ]

3 голосов
/ 30 декабря 2010

Хорошо, я нашел решение, в основном следующий код пропускает заголовок радиосвязи для пакета ech и получает bassid / MAC-адрес точки доступа.

Например: мой заголовок радиостанции имеет длину 18, и это заголовок радиоленты, если у вас заголовок призмы / AVS, длина будет другого размера.

Чтобы подключить MAC-адрес клиента к точке доступа, я полагал, что вам нужно проверить биты ОТ DS / TO DS.

typedef struct mac_header{
unsigned char fc[2];
unsigned char id[2];
unsigned char add1[6];
unsigned char add2[6];
unsigned char add3[6];
unsigned char sc[2];
}mac_header;
typedef struct frame_control{
unsigned protocol:2;
unsigned type:2;
unsigned subtype:4;
unsigned to_ds:1;
unsigned from_ds:1;
unsigned more_frag:1;
unsigned retry:1;
unsigned pwr_mgt:1;
unsigned more_data:1;
unsigned wep:1;
unsigned order:1;
}frame_control;

typedef struct beacon_header{
unsigned char timestamp[8];

unsigned char beacon_interval[2];
unsigned char cap_info[2];
}beacon_header;

void procPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{

    char * temp;
    char ssid[32];    
    struct mac_header *p= (struct mac_header *)(packet+RADIOTAP_HEADER_SIZE);
    struct frame_control *control = (struct frame_control *) p->fc;
    temp = (char *) (packet + sizeof (struct mac_header) +sizeof (struct    beacon_header)+RADIOTAP_HEADER_SIZE);
    if ((control->protocol == 0) && (control->type == 0) && (control->subtype == 8) )  // beacon frame
    {        
         memset(ssid,0,32);
         memcpy (ssid, &temp[2], temp[1]);
         printf ("Destination Add : %s\n", ether_ntoa ((struct ether_addr *)p->add1));
         printf ("Source Add : %s\n", ether_ntoa ((struct ether_addr *)p->add2));
         printf ("BSSID : %s\n", ether_ntoa ((struct ether_addr *)p->add3));
         printf ("ssid = %s\n", ssid);
    }


}
3 голосов
/ 24 декабря 2010

Лучшее место для этого - извлечь требуемый код из исходного кода tcpdump, который, на мой взгляд, в основном является как руководством по libpcap, так и сетевым введением в одном.

В любом случае, вам нужна функция обработки пакетов, полученная из pcap_open_live. Вам также нужно будет создать другой поток или процесс, потому что pcap_open_live заблокирует текущий поток, пока он работает.

Теперь функция обработки пакетов выглядит следующим образом:

void packethandler( u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet )
{
    // ... allocs etc

    // these instructions convert the "packet" string
    // to a struct and determine it's type, a setting in 
    // the ethernet header.
    eptr = (struct ether_header *) packet;
    ether_type = ntohs(eptr->ether_type);

    // ...

    // these two functions extract the mac addresses 
    // into appropriately alloc'd strings.
    // ether_ntoa converts the binary representation
    // of the mac address into a string
    snprintf(ethernet_shost, 20, "%s", ether_ntoa((struct ether_addr *)eptr->ether_shost));
    snprintf(ethernet_dhost, 20, "%s", ether_ntoa((struct ether_addr *)eptr->ether_dhost));

    // carry on...
}

Это даст вам MAC-адрес в виде строки. Имейте в виду, однако, сеть не так просто. Вам нужно знать, что вы делаете с двоичными строками информации, приведениями и т. Д., И вам нужно знать, что означают числа и параметры. Если источник tcpdump выглядит сложным, то это потому, что сеть сложна. Кроме того, я не перечислил заголовки, которые вам нужны для этого процесса. Там есть учебники по pcap; Я предлагаю вам не торопиться, чтобы прочитать их. Мой простой ответ не научит вас общаться.

Кроме того, эта функция неполная. Вам потребуются соответствующие выделения для массивов хранения (pcap - это библиотека C, которую вы можете использовать char* вместо string, а затем извлечь обратно в string позже).

...