tcpdump mailing list archives

Re: pcap_next/pcap_dispatch on VMware vmnet


From: Chris Morgan <chmorgan () gmail com>
Date: Tue, 10 Mar 2009 20:40:10 -0400

On Tue, Mar 10, 2009 at 8:02 PM, Guy Harris <guy () alum mit edu> wrote:

On Mar 10, 2009, at 9:52 AM, Chris Morgan wrote:

Does mac osx have epoll?

No.  It has poll(), but that, as noted, doesn't work with character special
files, such as the BPF devices used for traffic capture in OS X.  (BPF
devices *do* work with poll() in *BSD.)


Hmm. Yeah I'll make sure to put in a comment about mac os support.


You mentioned that Linux doesn't support a timeout, I see that the
call used by libpcap is a recvmsg() call. Does Windows have a timeout
on the packet read

Yes.  It's similar to the BPF timeout, in that the timer starts when the
read is done (rather than when the first packet arrives, as is the case on
Solaris).


Cool. That should mean that we don't need to we don't need to do
anything special on Windows.


Because we pass each packet off as we receive it we don't buffer
internal to SharpPcap. I thought that for performance reasons
Wireshark would group packets together and upon reaching a high water
mark or exceeding some interval, that the group of packets would be
passed somewhere. Maybe I'm not understanding your initial comments
about buffering but not holding onto packets forever if the buffer
never fills up.

For performance reasons, some in-kernel packet capture mechanisms, such as:

       BPF, as used in *BSD and Mac OS X

       the bufmod STREAMS module in Solaris (which is one component of the
mechanism);

       the packetfilter mechanism in Tru64 UNIX;

       the WinPcap kernel code;

will *NOT* return from a read as soon as the first packet arrives; they
will, instead, try to accumulate multiple packets and hand all of them up in
a single read.

Obviously, if you get one packet an hour, you don't want to have the
application wait several hours until enough packets have been accumulated,
so those mechanisms also include a timer, so that, after enough time
expires, the read will return even if a bufferful of packets hasn't been
accumulated.

This isn't done by Wireshark, or, rather, by dumpcap - and it isn't done by
tcpdump, or any other such application, either.

It's not even done by libpcap; the applications just call pcap_open_live(),
passing it a timeout value, and pcap_open_live() passes that timeout value
to the kernel packet capture mechanism, if it supports a timeout.

In BPF and WinPcap, and, I think, in packetfilter, the timer starts when the
read starts, and the read will return after the timer expires even if *no*
packets have been accumulated.

In Solaris, the timer starts - and is reset - whenever a packet arrives, so
the read won't return until at least one packet has been accumulated.

On those platforms, the buffering will be done regardless of what SharpPcap
does, as it's not something that the caller of libpcap/WinPcap does - it's
done by the kernel-mode code that libpcap and the WinPcap user-mode code
use.


Right. I was thinking that there might be cases where if the timeout
wasn't supported you would end up with the os buffering packets and
never returning them to the caller.

How does it work if there is no timeout and packets get captured but
not enough for the callback to occur?



Is there some reason not to implement pcap_breakloop() such that it
will send a signal to wake up the pcap_dispatch() thread?

Well, one reason not to do that might be that there *isn't* necessarily a
separate thread doing pcap_dispatch() or pcap_loop() or....

I suppose
that opens a huge can of worms since now you are dealing with cross
platform thread synchronization issues.

Yes.  The code would be significantly different between UN*X and Windows.

If there were a pcap_breakloop_thread() operation, which would take a pcap_t
* and a thread, the UN*X version could use pthread_kill() to send a signal
to the thread and the Windows version could use QueueUserAPC() to queue an
APC for the thread.

That would require that WinPcap use a WaitFor...Ex() call; I'd have to see
whether it already uses a WaitFor...() call or not.


Ahh. Considering the delay in adding such a feature and getting a
release out etc it seems simpler to just handle the issue at the
application level.



Alternatively why not use poll() or select() inside of pcap_dispatch()
to avoid performing the read if there is no pending data?

Because, in many cases, you don't *want* to avoid performing the read if
there's no pending data - you want to wait for data.  That's what tcpdump
does, and what the program Wireshark and TShark run to do captures (dumpcap)
does.


Wouldn't using poll if the timeout was set and not if it wasn't solve
that problem?



Wouldn't
that let you implement the timeout functionality

To what timeout functionality are you referring?  A timeout that prevents
reads from blocking forever even if no packets arrive is, as noted, not
something that all applications need or want - that's *NOT* what the timeout
specified in pcap_open_live() is intended to do, and not what it was ever
guaranteed to do - and a timeout that just prevents packets from being
buffered indefinitely if they're not arriving fast enough is *already*
implemented.
-

Right, I'm referring to the to_ms timeout in pcap_open_live(). I see
what you mean, the man page certainly disclaims support for the
timeout on all platforms. The documentation on to_ms does sound like
exactly what I'm trying to do though, cause the read to timeout. I was
trying to use this functionality to have the read abort and return to
the caller.

I'll just use poll() under linux to avoid the read if there are no
packets available. That will let us avoid using signals and keep cpu
usage low by reducing the idle call rate to once a second or
something.

Chris
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: