Rainer Weikusat <
rwei...@mssgmbh.com> writes:
> ittium <
itt...@gmail.com> writes:
>> Group,
>> Can I use packet DGRAM socket with protocol type as ETH_P_ALL
>>
>> s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) to send raw
>> frames.
>
> The protocol in the socket call is used to specify which types of
> ethernet frames are supposed to be received on this socket.
While this is consistent with the documentation, it isn't really true.
>> My doubt is if I do not specify the exact link layer protocol, how
>> will kernel module add the appropriate link layer header.
>
> If you want to send something using a packet socket, you'll need to
> use sendto and specify a destination address in form of a struct
> sockaddr_ll. This struct sockaddr_ll includes the interface index of
> the interface supposed to be used to send the datagram and the
> generated link-layer header will be one suitable for this interface.
And while this is mostly true, it doesn't answer the question :-).
I've since had a look at the code which handles this in the kernel
(I'm assuming that this is a misposted Linux question). That's the
packet_snd routine in net/packet/af_packet.c and the relevant code is
this:
if (saddr == NULL) {
ifindex = po->ifindex;
proto = po->num;
addr = NULL;
} else {
err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out;
if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
goto out;
ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol;
addr = saddr->sll_addr;
}
saddr is a pointer to the address specified in the send call (if
any). This means either an address was specified, then, a link layer
header suitable for the interface given as sll_ifindex using a
protocol of sll_protocol will be generated or no address was given and
then, interface index and protocol come from the socket. po->ifindex
comes from the sockaddr_ll structure passed as argument to an earlier
bind call and po->num is either protocol value from the same
sockaddr_ll structure or the one given in the socket call.