[Winpcap-users] Pcap_next_ex and pointer to packet data
Guy Harris
guy at alum.mit.edu
Wed Jul 22 18:20:20 UTC 2015
On Jul 22, 2015, at 7:06 AM, "Matias Chapresto" <matias.chapresto at nektra.com> wrote:
> I'm using pcap_next_ex to capture packets. And if I understand this right, if I put a 1000ms timeout, then pcap_next_ex will fill out the buffer and wait a second before returning.
For all flavors of *pcap that buffer packets, which includes WinPcap, as well as libpcap on *BSD, OS X, Digital/Tru64 UNIX, Solaris, and newer versions of libpcap on newer versions of Linux (and "newer" doesn't have to be all that new, these days), the way to think about the buffer and timeout is:
There is, in the OS kernel-mode code, a set of buffers for each pcap_t opened for live capture with libpcap/WinPcap.
As packets arrive, they are added to the current buffer by the capture mechanism code in the kernel. If there's no room in the current buffer for the packet, that buffer is marked as "full", and, if the next buffer in the set isn't full, it makes that the current buffer and puts the packet in that buffer, otherwise it discards the packet (the packet might still be processed by the main networking stack, it's just not provided to the program trying to do capturing).
There is also, in *pcap, a buffer in user-mode.
When an attempt is made to read a packet from *pcap, if there's a packet remaining in the user-mode buffer, that packet is provided.
Otherwise, an attempt is made to read the contents of the oldest kernel-mode buffer from the capture mechanism.
If that buffer is full, the attempt succeeds, the data in that buffer is copied to the user-mode buffer, and that kernel-mode buffer is marked as no longer being full. (For memory-mapped capture mechanisms, such as the ones Linux and FreeBSD provide, it's a bit different, but this is probably close enough for the purposes of this explanation.)
Otherwise, the timer is started, and the attempt to read blocks until either the buffer becomes full or the timer expires. Once either of those happens, the data in the buffer is copied to the user-mode buffer, and that buffer is marked as no longer being full.
So:
1) pcap_next_ex() will not necessarily wait a second before returning - it could even return *immediately*;
2) pcap_next_ex() does not fill the kernel-mode buffers at all, it only fills the user-mode buffer, and only does that if it's empty.
> If that is the case, then what does the packet_data* point to?
It points to the packet it just delivered.
> Because in 1 second, many packets should've been processed, so when the function returns, where are all the payloads of all those packets?
In the user-mode buffer. If you've called pcap_next_ex(), and there are more packets in the user-mode buffer following the one returned by that call to pcap_next_ex(), the next call to pcap_next_ex() will return the packet following the one returned by the preceding call to pcap_next_ex(). If there aren't any more packets left, it'll try to read the next bufferful of packets from the in-kernel capture mechanism.
Note that if, when the timer expires, *no* packets have arrived, the attempt to read data into the user-mode buffer from the in-kernel buffer will provide *no* data, and pcap_next_ex() will return 0 rather than 1. This is *not* an error; just keep reading.
More information about the Winpcap-users
mailing list