2015-06-28 72 views
0

我試圖用pcap做一些簡單的數據包捕獲,所以我創建了一個句柄來監聽eth0。我的問題是在接近我的代碼末尾的pcap_loop(handle, 10, myCallback, NULL);行。我正在嘗試使用pcap_loop。 預期的輸出應該是:'pcap_loop'沒有記錄數據包,甚至沒有運行

eth0 
Activated! 
1 
2 
3 
... 
10 
Done processing packets! 

電流輸出缺少增量:「處理完的數據包」

eth0 
Activated! 
Done processing packets! 

目前它只是跳繩一直到我不知道爲什麼。即使不進入回調,應該還是等待數據包作爲;計數」參數(見pcap_loop文檔)設置爲10

#include <iostream> 
#include <pcap.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

void myCallback(u_char *useless, const struct pcap_pkthdr* hdr, const u_char*packet){ 
    static int count = 1; 
    std::cout <<count<<std::endl; 
    count ++; 
} 

int main(){ 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    char * devName; 
    char* net; 
    char* mask; 
    const u_char*packet; 
    struct in_addr addr; 
    struct pcap_pkthdr hdr; 
    bpf_u_int32 netp; 
    bpf_u_int32 maskp; 

    pcap_if_t *devs; 
    pcap_findalldevs(&devs, errbuf); 
    devName = pcap_lookupdev(errbuf); 
    std::cout <<devName<<std::endl; 

    int success = pcap_lookupnet(devName, &netp, &maskp, errbuf); 
    if(success<0){ 
     exit(EXIT_FAILURE); 
    } 
    pcap_freealldevs(devs); 

    //Create a handle 
    pcap_t *handle = pcap_create(devName, errbuf); 
    pcap_set_promisc(handle, 1); 
    pcap_can_set_rfmon(handle); 

    //Activate the handle 
    if(pcap_activate(handle)){ 
     std::cout <<"Activated!"<<std::endl; 
    } 
    else{ 
     exit(EXIT_FAILURE); 
    } 

    pcap_loop(handle, 10, myCallback, NULL); 
    std::cout <<"Done processing packets!"<<std::endl; 

    //close handle 
    pcap_close(handle); 
    } 

回答

1
pcap_findalldevs(&devs, errbuf); 

那電話沒有做任何有用的事情,因爲除了釋放它之外,您沒有對devs做任何事情。 (您也沒有檢查它是成功還是失敗。)除非您需要知道可以捕獲的設備是什麼,否則您不妨將其刪除。

pcap_can_set_rfmon(handle); 

這一切都沒有做任何有用的,因爲你不檢查其返回值。如果您在Wi-Fi設備上進行捕捉,並且希望以監視模式進行捕捉,則在創建之後並在激活手柄之前,您可以在手柄上撥打pcap_set_rfmon() - 而不是pcap_can_set_rfmon()

//Activate the handle 
if(pcap_activate(handle)){ 
    std::cout <<"Activated!"<<std::endl; 
} 
else{ 
    exit(EXIT_FAILURE); 
} 

引述pcap_activate()手冊頁:

RETURN VALUE 
    pcap_activate() returns 0 on success without warnings, PCAP_WARN- 
    ING_PROMISC_NOTSUP on success on a device that doesn't support promis- 
    cuous mode if promiscuous mode was requested, PCAP_WARNING on success 
    with any other warning, PCAP_ERROR_ACTIVATED if the handle has already 
    been activated, PCAP_ERROR_NO_SUCH_DEVICE if the capture source speci- 
    fied when the handle was created doesn't exist, PCAP_ERROR_PERM_DENIED 
    if the process doesn't have permission to open the capture source, 
    PCAP_ERROR_RFMON_NOTSUP if monitor mode was specified but the capture 
    source doesn't support monitor mode, PCAP_ERROR_IFACE_NOT_UP if the 
    capture source is not up, and PCAP_ERROR if another error occurred. If 
    PCAP_WARNING or PCAP_ERROR is returned, pcap_geterr() or pcap_perror() 
    may be called with p as an argument to fetch or display a message 
    describing the warning or error. If PCAP_WARNING_PROMISC_NOTSUP, 
    PCAP_ERROR_NO_SUCH_DEVICE, or PCAP_ERROR_PERM_DENIED is returned, 
    pcap_geterr() or pcap_perror() may be called with p as an argument to 
    fetch or display an message giving additional details about the problem 
    that might be useful for debugging the problem if it's unexpected. 

這意味着上面的代碼是100%錯誤的 - 如果pcap_activate()返回一個非零值,它可能有失敗,如果返回0,則成功

如果返回值爲負值,則爲錯誤值,但失敗。如果它不是零但是肯定的,那是一個警告值;它已成功,但是,例如,它可能未啓用混雜模式,因爲操作系統或設備可能不會讓混雜模式被設置。

所以,你想要的是,代替:

//Activate the handle 
int status; 
status = pcap_activate(handle); 
if(status >= 0){ 
    if(status == PCAP_WARNING){ 
     // warning 
     std:cout << "Activated, with warning: " << pcap_geterror(handle) << std::endl; 
    } 
    else if (status != 0){ 
     // warning 
     std:cout << "Activated, with warning: " << pcap_statustostr(status) << std::endl; 
    } 
    else{ 
     // no warning 
     std::cout <<"Activated!"<<std::endl; 
    } 
} 
else{ 
    if(status == PCAP_ERROR){ 
     std:cout << "Failed to activate: " << pcap_geterror(handle) << std::endl; 
    } 
    else{ 
     std:cout << "Failed to activate: " << pcap_statustostr(status) << std::endl; 
    } 
    exit(EXIT_FAILURE); 
} 
+0

我應該更加重視的文檔。在檢查pcap_activate的成功時,這是一個非常大的錯誤。謝謝 –