1
votes

I want to send a packet to another machine but with a different MAC address in the ethernet header. For this I am using raw sockets in C and creating my own ethernet header so that I can set the source MAC as desired. The trouble is that I am not sure what destination MAC address to fill in the header. I know the IP of the destination machine but not the MAC. Even if I knew, I don't want to hardcode this MAC.

One option I see is that my machine would know the MAC in its ARP table and I could read it and get the MAC address and fill it in. But doing this before sending each packet is overhead. I could read it once and keep using but what if some day the destination machine gets replaced. The admin would assign the same IP address to the new machine but the MAC address would be different. Probably when the new machine boots up, it would send a Gratuitous ARP and my machine would update its ARP table. But my program wouldn't know this. My program would keep sending packets with old MAC.

I feel I am missing something very basic. Thoughts?

2
Why would you read the arp before every packet? Reading it once when you start up seems about right. Use arpingstark
@stark, I could read it once and keep using but what if some day the destination machine gets replaced. The admin would assign the same IP address to the new machine but the MAC address would be different.yeniv
Your program has no error recovery code?stark

2 Answers

1
votes

What you are seeing here is the same problem that everyone faces, who tries to implement a network stack. You have several options:

  • If the packet is a reply packet, then just use the MAC address of the from address
  • You can maintain an own arp-table and send a arp request if the entry in your table is missing or outdated. Parse arp replies and update your table accordingly. Packets to be sent without a valid arp table entry have to be queued. This is the most elegant, but also a very demanding option.
  • You can simply send the packet to the MAC of your local router. It will forward the packet to the correct host specified in the IP header. If your local router employs protocols like vrrp, hsrp or gblp, then the MAC address is always the same and doesn't change, even if your router is replaced.
  • You can read the MAC address from /proc/net/arp or with ioctl(SIOCGARP, ...);, but the entry for the IP you are looking for might not be present, if your host hasn't tried to communicate with it recently. You could, of course, send a dummy packet with sendto(); to that host before reading the arp table.

If you describe in more detail what you are planning to do, the suggestions might get better.

0
votes

You can set the MAC address for the device with SIOCSIFHWADDR ioctl request. The manual for netdevice is a good starting point for this.