The manpage packet(7) currently states that:
"When you send packets it is enough to specify sll_family, sll_addr,
sll_halen, sll_ifindex."
This is incorrect: you also need to specify sll_protocol.
(The protocol specified when the socket is created is used for filtering
inbound packets, but not for constructing outbound packets.)
I encountered this while researching a page for my website:
http://www.microhowto.info/howto/send_an_arbitrary_ethernet_frame_using_an_af_packet_socket_in_c.html
To empirically verify the behaviour I took my test code from the above
page then changed it to use different values for the third argument to
socket() and the sll_protocol field:
- socket created with ETH_P_ARP, packet sent with ETH_P_ARP:
packet sent with EtherType of ETH_P_ARP
- socket created with ETH_P_ARP, sll_protocol==0:
packet sent with EtherType of 0
- socket created with 0x88b5, sll_protocol==htons(ETH_P_ARP):
packet sent with EtherType of ETH_P_ARP
- socket created with ETH_P_ARP, sll_protocol==htons(0x88b5):
packet sent with EtherType of 0x88b5
This shows that leaving sll_protocol set to zero does not have the
desired effect and that it needs to be set to the desired link-layer
protocol.
There is code in the relevant kernel source file
(net/packet/af_packet.c) which appears to inspect the value of the
sll_protocol field and use it as the link-layer protocol number, however
I am not sufficiently familiar with this subsystem to be fully confident
of what is happening. The line in question is:
proto = saddr->sll_protocol;
In version 3.4 of the kernel this can be found in the functions
packet_snd and tpacket_snd. In version 2.6.26 it is in packet_sendmsg.
Below is a patch that adds sll_protocol to the list of required fields.
This may not be the whole truth, since it is not clear what role if any
sll_protocol, sll_halen or sll_addr would play when the socket type is
SOCK_RAW, however I'm confident it is more accurate than the page as it
stands at present:
diff --git a/man7/packet.7 b/man7/packet.7
index 374f6da..fb09f15 100644
--- a/man7/packet.7
+++ b/man7/packet.7
@@ -160,7 +160,9 @@ When you send packets it is enough to specify
.IR sll_family ,
.IR sll_addr ,
.IR sll_halen ,
-.IR sll_ifindex .
+.IR sll_ifindex
+and
+.IR sll_protocol .
The other fields should be 0.
.I sll_hatype
and
Yours,
Graham Shaw
http://gdshaw.net/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html