You should probably use
socket(AF_PACKET, SOCK_DGRAM, htons(proto)))
instead of a SOCK_RAW socket. With a SOCK_RAW, you are sending/receiving the entire ethernet frame, including source and destination MAC address. with SOCK_DGRAM, the kernel will fill in the ethernet header.
You probably want to send the reply to the same address as the request comes from, recvfrom() can fill in the source address;
struct sockaddr_ll src_addr;
socklen_t addr_len = sizeof src_addr;
n = recvfrom(sckfd, buffer, 2048, 0,
(struct sockaddr*)&src_addr, &addr_len);
Now you've learned the source address, so send the packet back to it:
...
sendto(sckfd, data, data_len, src_addr, addr_len);
And if you rather need to use SOCK_RAW, your will receive the ethernet header too, so just copy out the MAC addresses from the received data and swap them around when you are constructing the reply frame.
For an a SOCK_RAW socket, you craft the entire ethernet frame, you don't need to fill in the ethernet address, so the following is not needed;
memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);