ZBLOG

go语言发送广播的arp请求报文,arp请求报文的目标IP填写指定的IP,之后如果接收到arp应答报文,则对比应答报文的源ip是否是指定的目标主机地址,是的话输出成功,否则输出失败

以下是一个简单的 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助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=1586

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?