According to RFC 826, the target hardware address in the ARP packet isn't important (in one place even marked as "don't care"), and it specifically says that the address lacks meaning in the request form. Nevertheless, hardware exists that (regardless of whether or not it's compliant) imposes requirements on the target address.
Previously, the WriteTo
function in this library has disregarded its addr
parameter and instead used the target MAC address from inside the ARP packet for the Ethernet destination address. This made it impossible to communicate with hardware that has expectations on the target MAC address field as you couldn't use an ARP target MAC address that's distinct from the Ethernet frame's destination address.
Example
package main
import (
"net"
"github.com/mdlayher/arp"
"github.com/mdlayher/ethernet"
)
func main() {
sourceMAC := net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}
sourceIP := net.IPv4(10, 1, 2, 3)
targetMAC := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
targetIP := net.IPv4(10, 1, 2, 4)
packet, _ := arp.NewPacket(arp.OperationRequest, sourceMAC, sourceIP, targetMAC, targetIP)
iface, _ := net.InterfaceByName("wlp3s0")
client, _ := arp.Dial(iface)
destinationMAC := ethernet.Broadcast // this one's ignored and replaced with zeroes
client.WriteTo(packet, destinationMAC)
}
Before
15:55:02.410404 ARP, Request who-has 10.1.2.4 tell 10.1.2.3, length 46
0x0000: 0000 0000 0000 1234 5678 9abc 0806 0001 .......4Vx......
0x0010: 0800 0604 0001 1234 5678 9abc 0a01 0203 .......4Vx......
0x0020: 0000 0000 0000 0a01 0204 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............
After
15:57:30.886322 ARP, Request who-has 10.1.2.4 tell 10.1.2.3, length 46
0x0000: ffff ffff ffff 1234 5678 9abc 0806 0001 .......4Vx......
0x0010: 0800 0604 0001 1234 5678 9abc 0a01 0203 .......4Vx......
0x0020: 0000 0000 0000 0a01 0204 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............