My current code (before using libpcap) uses this very method.
I set up a raw socket, set the DEMUX type, and I capture traffic. The problem 
with this approach is that it seems to  have a fair bit of overhead in the OS. 
(At least on the Mac.) I have to throttle traffic down my hardware to about 25 
to 30% (ouch!) in order to get my data. Any higher, packets are dropped.

Just by using libpcap/bpf, I have more than doubled the speed using Immediate 
mode along with my pcap_open_live session. So in this case, libpcap is the way 
forward for my application. But now, I want to work out a way to let pcap/bpf 
work at full rate, if possible. If I can balance the buffer sizes, I may be 
able to side-step the timeouts. - maybe. :)

Thanks!

bob


On 2013-03-25, at 12:27 AM, Guy Harris <g...@alum.mit.edu> wrote:

> 
> On Mar 24, 2013, at 2:59 PM, Guy Harris <g...@alum.mit.edu> wrote:
> 
>> Arguably, something like Linux's PF_PACKET sockets would be best for people 
>> trying to implement protocols atop the link-layer, as (either when not in 
>> memory-mapped mode, or when in TPACKET_V1 or TPACKET_V2 memory-mapped mode) 
>> it has no timeouts, but does have a buffer, so that you don't have to 
>> *immediately* read the packet or have further packets dropped due to being 
>> out of buffer space.  (In TPACKET_V3 mode, it appears to work more like, 
>> err, umm, BPF, with entire buffers full of packets being delivered, and with 
>> a timeout to keep it from waiting forever for a buffer to fill up; I think 
>> that mode was introduce for the benefit of packet capture.)
> 
> After a bit of a dive into xnu, it appears that there might be something 
> *somewhat* similar to PF_PACKET sockets in OS X - PF_NDRV sockets.
> 
> The documentation is somewhat, umm, sparse.  See, for example, 
> /usr/include/net/ndrv.h.
> 
> You'd presumably open a socket with a protocol family of PF_NDRV and type 
> SOCK_RAW, bind it to a network adapter (the struct sockaddr_ndrv structure 
> has an interface name in it, and that's what you'd use in a bind; set the 
> family to AF_NDRV), and then use setsockopt() calls to do the *real* bind, 
> i.e. binding it to a particular protocol type.
> 
> The socket level for setsockopt() would be SOL_NDRVPROTO, and the option 
> would be NDRV_SETDMXSPEC to bind and NDRV_DELDMXSPEC to unbind.  They both 
> take a struct ndrv_protocol_desc as an argument.  The version member of that 
> structure should be set to NDRV_PROTOCOL_DESC_VERS; the protocol_family 
> member should, I guess, be set to some number you pick to identify that 
> protocol (maybe it's only used when unbinding), and the rest is a counted 
> list of struct ndrv_demux_desc's, each of which specifies a link-layer 
> protocol to bind to the socket.
> 
> That structure has:
> 
>       type, which is an indication of the type of protocol specification:
> 
>               NDRV_DEMUXTYPE_ETHERTYPE - an Ethertype (which is what you'd 
> use);
> 
>               NDRV_DEMUXTYPE_SAP - an 802.2 header (DSAP, SSAP, and 1st byte 
> of the packet type);
> 
>               NDRV_DEMUXTYPE_SNAP - a SNAP type (OUI and protocol ID);
> 
>             all in network byte order;
> 
>       length, which is the length of the protocol specification;
> 
>       a union for the various protocol specifications.
> 
> I have not tried any of this.
> 
>       https://github.com/okunnig-/Foobar/blob/master/main.c
> 
> is a very simple example, but it doesn't do any protocol type binding.  
> Googling for NDRV_DEMUXTYPE_ETHERTYPE might find some better examples.
> 
> (What might be Really Nice, as I've said on occasion, would be a "access to 
> particular link-layer packets" library, for use by programs implementing 
> protocols atop the link layer (rather than by programs running as packet 
> capture and/or injection tools), which would use whatever mechanisms are 
> appropriate for that.  Those mechanisms might be different from the ones used 
> for packet capture:
> 
>       on Linux, packet capture might use TPACKET_V3 PF_PACKET/SOCK_RAW 
> sockets not bound to a particular protocol type value, while protocols atop 
> the link layer might use non-memory-mapped or TPACKET_V2 PF_PACKET/SOCK_DGRAM 
> or SOCK_RAW sockets bound to a particular protocol type value;
> 
>       on AIX and Solaris 11, packet capture might use BPF while protocols 
> atop the link-layer would use DLPI and bind to particular protocol type 
> values;
> 
>       on other systems with DLPI, packet capture might use SAP-promiscuous 
> DLPI devices while protocols atop the link-layer would use DLPI and bind to 
> particular protocol type values;
> 
>       on OS X, packet capture might use BPF while protocols atop the 
> link-layer would use PF_NDRV sockets;
> 
> etc..)

_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Reply via email to