I have a program that sends a set of TCP SYN packets to a host (using raw sockets) and uses libpcap
(with a filter) to obtain the responses. I'm trying to implement this in an asynchronous I/O framework, but it seems that libpcap
is missing some of the responses (namely the first packets of a series when it takes less than 100 microseconds
between the TCP SYN and the response). The pcap handle is setup like this:
pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);
Then I add a filter (contained on the filterExpression string):
struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);
And on a loop, after sending each packet, I use select to know if I can read from libpcap:
int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);
And read it:
if (FD_ISSET(pcapFd, &fdRead)) {
struct pcap_pkthdr* pktHeader;
const u_char* pktData;
if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
// Process received response.
}
else {
// Nothing to receive (or error).
}
}
As I said before, some of the packets are missed (falling into the "nothing to receive" else). I know these packets are there, because I can capture them on a synchronous fashion (using tcpdump
or a thread running pcap_loop
). Am I missing some detail here? Or is this an issue with libpcap
?
This seem to be an issue with libpcap using memory mapping under Linux. Please see my other question for details.