tcpdump mailing list archives

Re: pcap_next/pcap_dispatch on VMware vmnet


From: Guy Harris <guy () alum mit edu>
Date: Tue, 10 Mar 2009 17:02:29 -0700


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.)

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).

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.

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.

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
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.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: