Search code examples
clinuxmacosraw-sockets

When using a raw socket, why do I need to give out MAC address twice?


I want to send Ethernet frames using raw_socket in Linux, and I use the code below. It works, but I cannot understand that since I have given out the MAC address in the frame (buffer), why do I have to give it again in the struct sockaddr_ll?

s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
/*socket_address*/
struct sockaddr_ll socket_address;      
socket_address.sll_addr[0]  = 0x00;     
socket_address.sll_addr[1]  = 0x04;     
socket_address.sll_addr[2]  = 0x75;
socket_address.sll_addr[3]  = 0xC8;
socket_address.sll_addr[4]  = 0x28;
socket_address.sll_addr[5]  = 0xE5;
/*frame*/
unsigned char src_mac[6] = {0x00, 0x01, 0x02, 0xFA, 0x70, 0xAA};
unsigned char dest_mac[6] = {0x00, 0x04, 0x75, 0xC8, 0x28, 0xE5};
memcpy((void*)buffer, (void*)dest_mac, ETH_ALEN);
memcpy((void*)(buffer+ETH_ALEN), (void*)src_mac, ETH_ALEN);

send_result = sendto(s, buffer, ETH_FRAME_LEN, 0, 
          (struct sockaddr*)&socket_address, sizeof(socket_address));

Solution

  • Similar thread at sendto function does not use MAC address provided in struct sockaddr_ll when sending raw packets.

    It seems that in other case the destination address struct will provide additional data like the interface index for example.