Reputation: 55
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];
Upvotes: 0
Views: 744
Reputation:
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".
Upvotes: 0
Reputation: 967
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.
Upvotes: 0
Reputation: 20174
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);
Upvotes: 1