The example program in this lesson behaves exactly like the previous program (Opening an adapter and capturing the packets), but it uses pcap_next_ex() instead of pcap_loop().
The callback-based capture mechanism of pcap_loop() is elegant and it could be a good choice in some situations. However, handling a callback is sometimes not practical – it often makes the program more complex especially in situations with multithreaded applications or C++ classes.
In these cases, pcap_next_ex() retrievs a packet with a direct call – using pcap_next_ex() packets are received only when the programmer wants them.
The parameters of this function are the same as a capture callback – it takes an adapter descriptor and a couple of pointers that will be initialized and returned to the user (one to a pcap_pkthdr structure and another to a buffer with the packet data).
In the following program, we recycle the callback code of the previous lesson's example and move it inside main() right after the call to pcap_next_ex().
#include "pcap.h"
int main()
{
int inum;
int i=0;
int res;
struct tm ltime;
char timestr[16];
const u_char *pkt_data;
time_t local_tv_sec;
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
for(d=alldevs; d; d=d->
next)
{
printf(
"%d. %s", ++i, d->
name);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf_s("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
return -1;
}
for(d=alldevs, i=0; i< inum-1 ;d=d->
next, i++);
65536,
1000,
NULL,
errbuf
) ) == NULL)
{
fprintf(stderr,
"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->
name);
return -1;
}
while((res =
pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
if(res == 0)
continue;
local_tv_sec = header->
ts.tv_sec;
localtime_s(<ime, &local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);
printf(
"%s,%.6d len:%d\n", timestr, header->
ts.tv_usec, header->
len);
}
if(res == -1){
printf(
"Error reading the packets: %s\n",
pcap_geterr(adhandle));
return -1;
}
return 0;
}
#define PCAP_OPENFLAG_PROMISCUOUS
Defines if the adapter has to go in promiscuous mode.
#define PCAP_SRC_IF_STRING
String that will be used to determine the type of source in use (file, remote/local interface).
struct pcap pcap_t
Descriptor of an open capture instance. This structure is opaque to the user, that handles its conten...
#define PCAP_ERRBUF_SIZE
Size to use when allocating the buffer that contains the libpcap errors.
pcap_t * pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
Open a generic source in order to capture / send (WinPcap only) traffic.
void pcap_freealldevs(pcap_if_t *alldevsp)
Free an interface list returned by pcap_findalldevs().
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data)
Read a packet from an interface or from an offline capture.
char * pcap_geterr(pcap_t *p)
return the error text pertaining to the last pcap library error.
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
Create a list of network devices that can be opened with pcap_open().
Item in a list of interfaces, used by pcap_findalldevs().
char * name
a pointer to a string giving a name for the device to pass to pcap_open_live()
struct pcap_if * next
if not NULL, a pointer to the next element in the list; NULL for the last element of the list
char * description
if not NULL, a pointer to a string giving a human-readable description of the device
Header of a packet in the dump file.
struct timeval ts
time stamp
bpf_u_int32 len
length this packet (off wire)
Why do we use pcap_next_ex() instead of the old pcap_next()? Because pcap_next() has some drawbacks. First of all, it is inefficient because it hides the callback method but still relies on pcap_dispatch(). Second, it is not able to detect EOF, so it's not very useful when gathering packets from a file.
Notice also that pcap_next_ex() returns different values for success, timeout elapsed, error and EOF conditions.
<<< Previous Next >>>