Question

I'm trying to use pcap_next but my program stops on this line:

packet = pcap_next([self pcap_socket], hdr);

with the error:

thread1: EXC_BAD_ACCESS (code=1, address=0x0)

here is my code:

-(const u_char*)readOnPcapDescriptor
{
    if([self pcap_is_open]) {
        struct pcap_pkthdr *hdr = NULL;
        const u_char *packet;

        // read for the next packet
        packet = pcap_next([self pcap_socket], hdr);

        if(packet==NULL)
            return NULL;
        else
            return packet;
    }

    printf("NOK\nOpen descriptor First!\n\n");
    exit(1);
}

I don't understand where is my error here. The pcap_t descriptor is open before with this :

pcap_t * open_socket = pcap_open_live(if_name,BUFSIZ,1,1,pcap_errbuf);

And affected to an instance variable:

[self setPcap_socket:open_socket];
Was it helpful?

Solution

The pcap_next documentation does not say that the pcap_pkthdr argument is allowed to be NULL. Try passing a valid pointer to a pcap_pkthdr struct:

struct pcap_pkthdr hdr = {0};
packet = pcap_next([self pcap_socket], &hdr);

OTHER TIPS

The documentation of pcap_next() tells you that "The pcap_pkthdr structure pointed to by h is filled in with the appropriate values for the packet."

That h is called hdr in your example, and you initialize it like this:

struct pcap_pkthdr *hdr = NULL;

In other words, pcap_next() tries to access the address at NULL, which is exactly what is stated in the error message.

I can only read 2 packets

To quote the pcap_next() man page:

   pcap_next() returns a pointer  to  the  packet  data  on  success,  and
   returns  NULL  if  an  error occured, or if no packets were read from a
   live capture (if, for example, they were discarded because they  didn't
   pass the packet filter, or if, on platforms that support a read timeout
   that starts before any packets arrive, the timeout expires  before  any
   packets  arrive, or if the file descriptor for the capture device is in
   non-blocking mode and no packets were available to be read), or  if  no
   more  packets are available in a ``savefile.''  Unfortunately, there is
   no way to determine whether an error occured or not.

The important thing here is "and returns NULL if ... or if no packets were read from a live capture (...or if, on platforms that support a read timeout that starts before any packets arrive, the timeout expires before any packets arrive ..."

BSD-flavored OSes, such as OS X and iOS, support a read timeout that starts before any packets arrive, so you may get NULL returned if there aren't any packets right now. That does not mean that there will never be any packets; you have to keep looping.

pcap_next() does not distinguish between errors and timeouts; as the man page says, "Unfortunately, there is no way to determine whether an error occured or not.". Therefore, it is not, and has never been, a very good routine to use.

If you don't want to use routines that take callbacks, such as pcap_dispatch() or pcap_loop(), I suggest you use pcap_next_ex(), which does distinguish between errors and "no packets arrived within the timeout interval".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top