简体   繁体   中英

'pcap_loop' is not recording packets and isn't even running

I'm trying to do some simple packet capturing with pcap, and so I've created a handle to listen through eth0. My issue is with the pcap_loop(handle, 10, myCallback, NULL); line near the end of my code. I'm trying to use pcap_loop . The expected output is supposed to be:

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

Current output is missing the increments:

eth0
Activated!
Done processing packets!

Currently it's just skipping right through to "Done processing packets!" and I have no idea why. Even if it doesn't go to the callback, it should still be waiting on packets as the ;count' parameter (see documentation for pcap_loop) is set to 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);
    }
 pcap_findalldevs(&devs, errbuf); 

That call isn't doing anything useful, as you're not doing anything with devs other than freeing it. (You also aren't checking whether it succeeds or fails.) You might as well remove it unless you have some need to know what all the devices on which you can capture are.

 pcap_can_set_rfmon(handle); 

That all isn't doing anything useful, as you're not checking its return value. If you are capturing on a Wi-Fi device, and you want to capture in monitor mode, you call pcap_set_rfmon() - not pcap_can_set_rfmon() - on the handle after creating and before activating the handle.

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

To quote the pcap_activate() man page:

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.

This means that the code above is 100% wrong - if pcap_activate() returns a non-zero value, it may have failed , and if it returns 0, it succeeded .

If the return value is negative, it's an error value, and it has failed. If it's non-zero but positive, it's a warning value; it has succeeded, but, for example, it might not have turned promiscuous mode on, as the OS or device might not let promiscuous mode be set.

So what you want is, instead:

//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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM