Wireshark-users: Re: [Wireshark-users] Pcap library (Portability between linux	and	windows)
      
      
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.