0
votes

There are two Linux C programs, one called 'sender', another one called 'receiver'. Both program uses raw (packet) sockets on the same network interface (eth0). They communicate using a custom ethernet protocol (type). Yes, the point is exactly that to have access to raw ethernet frames.

The sockets are opened somehow like this:

sock = socket(AF_PACKET, SOCK_RAW, htons(MY_CUSTOM_ETH_PROTOCOL));

Receiver issues this to read from the raw socket:

recv(sock, eth_frame, MAX_ETH_FRAME_LEN, 0);

Sender issues this to write to the raw socket:

struct sockaddr_ll sa;

memset(&sa, 0, sizeof(sa));
sa.sll_family = AF_PACKET;
memcpy(sa.sll_addr, dst_mac, 6);
sa.sll_halen = 6;
sa.sll_ifindex = itf_idx;

I hope it's unnecessary to share how I assemble valid ethernet frames, how I get network interface index etc.

The problem: if the two programs run on the same machine, receiver can't see the ethernet frames emitted by the sender. However, Wireshark can see them all.

If the two programs run on separate machines connected with a switch, receiver receives the ethernet frames emitted by the sender.

In the first case, no indication of errors is seen.

What can this be? I need to make the raw socket capable of receiving all raw ethernet frames that are put on the wire by other raw sockets.

1
It sounds like you are binding to a specific interface. When you do so are you setting sll_pkttype to PACKET_OUTGOING? See man packet(7). - Jim D.
man 7 packet says: "...and PACKET_OUTGOING for a packet originating from the local host that is looped back to a packet socket. These types make sense only for receiving" By the way bind(...) isn't called, but the interface index of the selected network itf is used. I also tried to bind to net itf, without any success... and Wireshark still sees the frames. - tselmeci
Furthermore: "When you send packets, it is enough to specify sll_family, sll_addr, sll_halen, sll_ifindex, and sll_protocol. The other fields should be 0. sll_hatype and sll_pkttype are set on received packets for your information. For bind, only sll_protocol and sll_ifindex are used." - tselmeci
I think you need to bind the interface and specify that you want to see the outgoing packets. Alternatively, set the protocol to htons(ETH_P_ALL) and filter out your protocol. The usual problem with htons(ETH_P_ALL) is that people complain they get the outbound packets; you are on the other side of that! - Jim D.
Alright, I'll give it a try (ETH_P_ALL). - tselmeci

1 Answers

0
votes

The resolution: if I create the socket like this:

socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

all ethernet frames are received. Since my software contains filtering based on ethernet frame type, it can select the ethernet frames belonging to the custom protocol.

Thanks!