On Jan 16, 2009, at 1:58 AM, Benoit wrote:
I don't know if I'm on the good mailing list to post this thread but
as this software use correctly the two libraries I thought about
posting here.
The right mailing list for libpcap is tcpdump-workers@xxxxxxxxxxx (a
bit confusing, perhaps, but as libpcap and tcpdump come from the same
group...).
I'm trying to create a protocol (directly on the MAC layer) to
communicate between FPGA and PC. And i would like it to be
compatible between linux and windows. My code compile and seems to
work correctly but the libpcap function doesn't act the same way as
the winpcap function.
I want to use the pcap_next_ex() function to look if there is packet
on the interface and return if true or after a timeout. It works
correctly on windows, however on linux I need to set pcap to non
blocking
Why do you need to set it to non-blocking?
and I'm loosing a lot of packet.
The packet capture mechanism libpcap uses on Linux - at least as it's
used by libpcap prior to libpcap 1.0.0 - isn't as good at dealing with
a high volume of packets.
If you're using libpcap to implement a protocol, you should probably
use pcap_compile() and pcap_setfilter() to set a filter that filters
out all packets except for the ones for your protocol.
//Open the interface.
#ifdef WIN32
adhandle= pcap_open(ifname, SIZEIB_MTU,
PCAP_OPENFLAG_PROMISCUOUS, timeout, NULL,errbuf);
#else
adhandle =
pcap_open_live
(ifname,SIZEIB_MTU,PCAP_OPENFLAG_PROMISCUOUS,timeout,errbuf);
pcap_setnonblock(adhandle,timeout,errbuf);
#endif
The pcap_open_live() will work on Windows as well (it's marked as
deprecated in some versions of the documentation, but it's not
actually deprecated, and it's not marked as deprecated in current
versions of the documentation).
Unless your protocol needs to see all traffic on your network,
including unicast traffic between two machines other than your
machine, you also don't want promiscuous mode - just pass 0, rather
than PCAP_OPENFLAG_PROMISCUOUS.
...
while(TRUE) {
#ifdef WIN32
ret = pcap_next_ex(adhandle, &(header), (const u_char**)(&p_pkt));
#else
pcap_next_ex(adhandle, &(header), (const u_char**)(&p_pkt));
ret = header->len;
#endif
That's not correct. pcap_next_ex() returns the same value on every
platform - Linux, *BSD, Mac OS X, Solaris, Windows, etc..
You should just do
ret = pcap_next_ex(adhandle, &(header), (const u_char**)(&p_pkt));
If you're running in non-blocking mode, that loop will consume a lot
of CPU time, as it won't wait for packets to arrive.
if(ret > 0) {
count++;
printf("pkt %d has size %d\n",count,ret);
That's not right, either - pcap_next_ex() doesn't return the length of
the packet, it returns a success/failure indication:
1 the packet was read without problems
0 packets are being read from a live capture, and
the time-
out expired
-1 an error occurred while reading the packet
-2 packets are being read from a ``savefile'', and
there are
no more packets to read from the savefile.
The length of the packet is header->len.