On Mon, Sep 09, 2002 at 05:16:29PM -0400, subramoni padmanabhan wrote:
>    I have a question about pcap. I am writing a program to capture packets 
> which arrive on any of my interfaces since I do not know on which interface 
> the packets might arrive. I am running a RHL kernel 2.4.2-2 and I am 
> assuming that this kernel supports the "any" device for capturing packets on 
> all interfaces. am I right?

Right.

> If so, when I use "any" in pcap_open_live(), it 
> returns a descriptor for the interface. What does it return in the case 
> where we use "any". Does it return an array of descriptors?

No, it returns a single descriptor for a PF_PACKET socket that's not
bound to any particular interface, so it gets packets on all interfaces.

> Also, I need to 
> use the descriptor returned by this function in pcap_compile() and 
> pcap_setfilter(). How do I do this assuming I get an array of descriptors? 

The assumption is incorrect, so the question is irrelevant.

> Finally, if "any" is not supported by my Kernel, What is an alternative 
> method of capturing packets on all interfaces? One way that I can think of 
> is to somehow get a list of all the interfaces of the machine and then call 
> pcap_open_live() and the other functions individually on each of the 
> interfaces. Am I correct

Somewhat correct.

However, you can't call "pcap_loop()" individually on each of the
interfaces; if you call it on one interface, it will loop forever
capturing on that interface, and not capture anything from any of the
other interfaces.

You could call "pcap_dispatch()" or "pcap_next()" individually on each
of the interfaces, but, while those don't loop forever, they might
block, either until the timeout expires (on OSes where the kernel's
capture mechanism supports timeouts that cause a read from the capture
device to return when the timeout expires even if no packets have
arrived) or forever (on OSes where the kernel's capture mechanism
doesn't, e.g. Solaris).

So what you really want to do, on UNIX, is:

        use "pcap_fileno()" to get a file descriptor for each of the
        capture devices;

        use "pcap_setnonblock()" to put those file descriptors in
        non-blocking mode;

        use a "select()" or "poll()" loop to wait for *any* of those
        descriptors to have packets available;

        call "pcap_dispatch()" on the ones that do, when "select()" or
        "poll()" returns.

However, there is an additional complication - in many versions of BSD,
"select()" and "poll()" don't work on BPF device descriptors, which are
the descriptors you get from "pcap_fileno()" on BSD.

So, to work around that, you would also need to have "select()" or
"poll()" have a timeout equal to the timeout you specified in the
"pcap_open_live()" calls and, instead of calling "pcap_dispatch()" on
the "pcap_t"s that "select()" or "poll()" says can be read, call it on
*all* of them.

There may be, alas, an additional complication over and above that,
which is that I suspect that FreeBSD 4.5 will not even allow that to
work, due to a change they made.  "select()" and "poll()" do, I think,
work on BPF devices in FreeBSD 4.6; I have not yet determined whether
the workaround given works on FreeBSD 4.5, nor how to find another
workaround that works on 4.5 if that one doesn't.

On Windows, you'd have to do something similar, except that you'd:

        use "pcap_getevent()" to get, for each pcap_t, a handle on which
        to do something like a Windows "WaitForMultipleEvents()" call;

        do that call rather than "select()" or "poll()".

> and/or is ther any other way of doing this?

Not unless the OS supports such a mechanism directly; I don't know of
any that provide that sort of "unbound" capture device other than Linux
2.2 and later kernels.
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to