以下是一个简单的 Go 代码实现,用于发送 ARP 请求并接收应答:
package main
import (
"fmt"
"net"
)
func main() {
// 指定目标 IP 地址
targetIP := net.ParseIP("192.168.1.1")
// 构造广播地址
broadcastAddr := &net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(255, 255, 255, 255)}
// 打开网络接口
iface, err := net.InterfaceByName("eth0")
if err != nil {
panic(err)
}
// 构造 ARP 请求包
arpPacket := makeARPPacket(iface.HardwareAddr, iface.Addrs[0].(*net.IPNet).IP.To4(), targetIP.To4())
// 发送 ARP 请求包到广播地址
conn, err := net.Dial("udp", fmt.Sprintf("%s:9", broadcastAddr.IP.String()))
if err != nil {
panic(err)
}
_, err = conn.Write(arpPacket)
if err != nil {
panic(err)
}
// 接收 ARP 应答包
buffer := make([]byte, 2048)
for {
n, _, err := conn.ReadFrom(buffer)
if err != nil {
panic(err)
}
if isARPPacketForTarget(buffer[:n], targetIP.To4()) {
fmt.Println("ARP request succeeded!")
break
}
}
}
// 构造 ARP 请求包函数,返回字节数组形式的请求报文
func makeARPPacket(srcMAC, srcIP, targetIP net.IP) []byte {
packet := make([]byte, 42)
// 构造以太网头部
copy(packet[:6], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) // 目标 MAC 地址(广播地址)
copy(packet[6:12], srcMAC) // 源 MAC 地址
copy(packet[12:14], []byte{0x08, 0x06}) // 类型(ARP)
// 构造 ARP 请求报文
copy(packet[14:16], []byte{0x00, 0x01}) // 硬件类型(以太网)
copy(packet[16:18], []byte{0x08, 0x00}) // 协议类型(IPv4)
packet[18] = byte(6) // 硬件地址长度(MAC 地址长度为 6)
packet[19] = byte(4) // 协议地址长度(IPv4 地址长度为 4)
copy(packet[20:22], []byte{0x00, 0x01}) // 操作码(ARP 请求)
copy(packet[22:28], srcMAC) // 发送方 MAC 地址
copy(packet[28:32], srcIP) // 发送方 IP 地址
copy(packet[32:38], []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) // 接收方 MAC 地址(未知,填充全零)
copy(packet[38:], targetIP) // 接收方 IP 地址
return packet
}
// 判断接收到的 ARP 应答包是否为目标主机发送的
func isARPPacketForTarget(packet []byte, targetIP net.IP) bool {
if len(packet) < 42 || packet[12] != 0x08 || packet[13] != 0x06 {
return false
}
if !bytes.Equal(packet[38:42], targetIP.To4()) {
return false
}
return true
}
需要注意的是,广播地址可能会因网络环境而有所不同。在上述代码中,我使用了 255.255.255.255
这个地址作为广播地址,以太网协议中对广播地址的定义是所有比特位均为 1 的 MAC 地址(即 ff-ff-ff-ff-ff-ff
)。在某些情况下,例如局域网内有路由器时,广播地址可能需要设置为路由器所在子网内的广播地址。
内容由零声教学AI助手提供,问题来源于学员提问