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