2015-02-27 6 views
4

Я пытаюсь написать приложение C++ (linux), которое будет захватывать беспроводной пакет вместе с соответствующей силой сигнала (в дБм). Захватывающая часть проста, но проблема в том, что я не могу найти документацию о том, как получить уровень сигнала для каждого пакета.libpcap и захват беспроводного сигнала

Это часть заголовка?

Вот что я до сих пор:

printf("Device: %s\n", dev); 
printf("Number of packets: %d\n", num_packets); 
printf("Filter expression: %s\n", filter_exp); 

/* open capture device */ 
    pcap_t *handler = pcap_create("wlan0", errbuf); 
    if (handler == NULL) 
    { 
     exit(-1); 
    } 
    if(pcap_set_rfmon(handler,1)==0) 
    { 
     printf("monitor mode enabled\n"); 
    } 
    pcap_set_snaplen(handler, 2048); // Set the snapshot length to 2048 
    pcap_set_promisc(handler, 0); // Turn promiscuous mode off 
    pcap_set_timeout(handler, 512); // Set the timeout to 512 milliseconds 
    int status = pcap_activate(handler); 


/* now we can set our callback function */ 
pcap_loop(handle, num_packets, got_packet, NULL); 

Вот код got_packet:

/* define ethernet header */ 
ethernet = (struct sniff_ethernet*)(packet); 

/* define/compute ip header offset */ 
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); 
size_ip = IP_HL(ip)*4; 
if (size_ip < 20) { 
    printf(" * Invalid IP header length: %u bytes\n", size_ip); 
    return; 
} 

/* print source and destination IP addresses */ 
printf("  From: %s\n", inet_ntoa(ip->ip_src)); 
printf("   To: %s\n", inet_ntoa(ip->ip_dst)); 

/* determine protocol */  
switch(ip->ip_p) { 
    case IPPROTO_TCP: 
     printf(" Protocol: TCP\n"); 
     break; 
    case IPPROTO_UDP: 
     printf(" Protocol: UDP\n"); 
     return; 
    case IPPROTO_ICMP: 
     printf(" Protocol: ICMP\n"); 
     return; 
    case IPPROTO_IP: 
     printf(" Protocol: IP\n"); 
     return; 
    default: 
     printf(" Protocol: unknown\n"); 
     return; 
} 

/* define/compute tcp header offset */ 
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); 
size_tcp = TH_OFF(tcp)*4; 
if (size_tcp < 20) { 
    printf(" * Invalid TCP header length: %u bytes\n", size_tcp); 
    return; 
} 

printf(" Src port: %d\n", ntohs(tcp->th_sport)); 
printf(" Dst port: %d\n", ntohs(tcp->th_dport)); 

/* define/compute tcp payload (segment) offset */ 
payload = (char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); 

/* compute tcp payload (segment) size */ 
size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp); 

/* 
* Print payload data; it might be binary, so don't just 
* treat it as a string. 
*/ 
if (size_payload > 0) { 
    printf(" Payload (%d bytes):\n", size_payload); 
    //print_payload(payload, size_payload); 
} 

Любая помощь будет очень признателен.

UPDATE: /***************/ Вот обновление: Так на основе своих исследований и, как Гай Скотт упоминал, что я искал неверный информацию. Мне нужно посмотреть на беспроводные пакеты и вместо этого загружать пакет ethernet. Итак, вот обновленный код:

pcap_set_snaplen(handle, 2048); // Set the snapshot length to 2048 
    pcap_set_promisc(handle, 1);  // Turn promiscuous mode off 
    pcap_set_timeout(handle, 512); // Set the timeout to 512 milliseconds 
    int status = pcap_activate(handle); 

    if(pcap_set_datalink(handle, DLT_IEEE802_11_RADIO) == -1) { 
     printf("Couldn't set datalink type %s: %s\n", device, pcap_geterr(handle)); 
    } 

Так что проблема теперь заключается в разборе пакета, который кажется довольно сложной проблемой. Меня интересует адрес источника, адрес назначения и связанный с ним сигнал и т. Д. Я не знаю, как сопоставлять и загружать данные из пакета и сопоставлять их с структурой radiotap.

struct ieee80211_radiotap_header { 
u_int8_t it_version; /* set to 0 */ 
u_int8_t it_pad; 
u_int16_t it_len; /* entire length */ 
u_int32_t it_present; /* fields present */ 
} __attribute__((__packed__)); 

/* Presence bits */ 
#define RADIOTAP_TSFT 0 
#define RADIOTAP_FLAGS 1 
#define RADIOTAP_RATE 2 
#define RADIOTAP_CHANNEL 3 
#define RADIOTAP_FHSS 4 
#define RADIOTAP_ANTENNA_SIGNAL 5 
#define RADIOTAP_ANTENNA_NOISE 6 
#define RADIOTAP_LOCK_QUALITY 7 
#define RADIOTAP_TX_ATTENUATION 8 
#define RADIOTAP_DB_TX_ATTENUATION 9 
#define RADIOTAP_DBM_TX_POWER 10 
#define RADIOTAP_ANTENNA 11 
#define RADIOTAP_DB_ANTENNA_SIGNAL 12 

void process_packet (u_char * args, const struct pcap_pkthdr *header, const u_char * packet) 
{ 
    struct ieee80211_radiotap_header *packet_header = (struct ieee80211_radiotap_header *) header; 
    // This is where I am stuck 

Может ли кто-нибудь сказать мне, как только я захватил пакет, как вытащить из него вышеуказанные значения?

Благодаря

+0

ИТАК после немного больше исследований я понял, что я делал это неправильно. поэтому пакет, который я хочу захватить, на самом деле не является пакетом Ethernet, а скорее пакетом Wi-Fi. Пакет Wi-Fi имеет поле сигнала. –

ответ

1

Каждая программа, которая вызывает pcap_open_live(), pcap_create()/pcap_activate() или pcap_open_offline() должны, если вызовы удастся, позвоните pcap_datalink(), чтобы выяснить, что канального уровня типа заголовок захвата есть.

Есть нет исключений из этого правила.

Затем просмотрите the link-layer header types page for tcpdump.org, чтобы увидеть, какие значения возвращают pcap_datalink(). Сравните их с указанными здесь значениями DLT_. Те, которые вы, скорее всего, получите, - DLT_IEEE802_11, которые не имеют информации о силе сигнала и DLT_PRISM_HEADER, DLT_IEEE802_11_RADIO и DLT_IEEE802_11_RADIO_AVS, которые имеют информацию о силе сигнала. См. Ссылки для последних трех возможностей для информации о том, как информация о силе сигнала (и других метаданных радио) представлена ​​в пакетных данных.

(И, да, это три варианты метаданных радио, поэтому ссылка дается в другой ответ является неполным источником, большую часть времени вы, вероятно, получите radiotap заголовки, а не AVS или заголовки Prism. Radiotap является более общим, так как он предназначен для расширения, но сложнее разобрать.)

0

Я столкнулся с той же проблемой, подумал, что должен поделиться своим решением. Сила сигнала не находится в header обратного вызова PCAP, но в пределах packet.Для DLT_IEEE802_11_RADIO сигнал и шум может быть:

void process_packet (u_char * args, 
        const struct pcap_pkthdr *header, 
        const u_char * packet){ 
    int8_t signal_dbm = packet[22]; 
    int8_t noise_dbm = packet[23]; 
    .... 
} 

Но я нашел 22 и 23, глядя в WireShark.

Более подходящее решение было бы, конечно, использовать radiotap (GitHub).

Вот пример:

void process_packet (u_char * args, 
        const struct pcap_pkthdr *header, 
        const u_char * packet) { 
    struct ieee80211_radiotap_iterator iterator; 
    int ret = ieee80211_radiotap_iterator_init(&iterator, packet, header->len, NULL); 
    while (!ret) { 
     ret = ieee80211_radiotap_iterator_next(&iterator); 
     if (ret) break; 
     switch (iterator.this_arg_index) { 
      case IEEE80211_RADIOTAP_TSFT: 
       printf("timestamp: %lu\n", (uint64_t)*iterator.this_arg); 
       break; 
      case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: 
       printf("sig: %d\n", (int8_t)*iterator.this_arg); 
       break; 
      case IEEE80211_RADIOTAP_DBM_ANTNOISE: 
       printf("noise: %d\n", (int8_t)*iterator.this_arg); 
       break; 
      default: 
       break; 
     } 
    } 
} 

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

  • Нет связанных вопросов^_^