linux raw ethernet socket bind to specific protocol

dschatz picture dschatz · Jul 29, 2010 · Viewed 11.4k times · Source

I'm writing code to send raw Ethernet frames between two Linux boxes. To test this I just want to get a simple client-send and server-receive.

I have the client correctly making packets (I can see them using a packet sniffer).

On the server side I initialize the socket like so:

fd = socket(PF_PACKET, SOCK_RAW, htons(MY_ETH_PROTOCOL));

where MY_ETH_PROTOCOL is a 2 byte constant I use as an ethertype so I don't hear extraneous network traffic.

when I bind this socket to my interface I must pass it a protocol again in the socket_addr struct: socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
If I compile and run the code like this then it fails. My server does not see the packet. However if I change the code like so:
socket_address.sll_protocol = htons(ETH_P_ALL);
The server then can see the packet sent from the client (as well as many other packets) so I have to do some checking of the packet to see that it matches MY_ETH_PROTOCOL.

But I don't want my server to hear traffic that isn't being sent on the specified protocol so this isn't a solution. How do I do this?

Answer

dschatz picture dschatz · Jul 30, 2010

I have resolved the issue.

According to http://linuxreviews.org/dictionary/Ethernet/ referring to the 2 byte field following the MAC addresses:

"values of that field between 64 and 1522 indicated the use of the new 802.3 Ethernet format with a length field, while values of 1536 decimal (0600 hexadecimal) and greater indicated the use of the original DIX or Ethernet II frame format with an EtherType sub-protocol identifier."

so I have to make sure my ethertype is >= 0x0600.

According to http://standards.ieee.org/regauth/ethertype/eth.txt use of 0x88b5 and 0x88b6 is "available for public use for prototype and vendor-specific protocol development." So this is what I am going to use as an ethertype. I shouldn't need any further filtering as the kernel should make sure to only pick up ethernet frames with the right destination MAC address and using that protocol.