本文將介紹如何使用Golang發送ARP請求來取得目標設備的MAC位址。
ARP(Address Resolution Protocol)是解析網路層位址(IP位址)和資料鏈結層位址(MAC位址)的一種協定。在區域網路中,每個設備都有一個唯一的MAC位址,用於識別該設備。當我們知道目標設備的IP位址,但不知道其MAC位址時,可以發送ARP請求以取得該設備的MAC位址。
在Golang中,我們可以使用net套件中的net.InterfaceAddrs()函數來取得目前裝置的IP和MAC位址。然後,使用net包中的net.ParseIP()函數將目標IP位址解析為IP類型的變數。接下來,使用gopacket庫建立一個ARP請求包,並將它發送到網路中。
讓我們來看看範例程式碼:
package main import ( "fmt" "net" "time" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/packetio" "github.com/google/gopacket/pcap" ) func main() { // 获取当前设备的IP和MAC地址 interfaces, err := net.Interfaces() if err != nil { panic(err) } var localIP net.IP var localMAC net.HardwareAddr for _, iface := range interfaces { if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagLoopback == 0 { addrs, err := iface.Addrs() if err != nil { panic(err) } for _, addr := range addrs { switch addr := addr.(type) { case *net.IPNet: if addr.IP.To4() != nil { localIP = addr.IP } case *net.IPAddr: if addr.IP.To4() != nil { localIP = addr.IP } } } localMAC = iface.HardwareAddr break } } if localIP == nil || localMAC == nil { panic("Could not find local IP and MAC addresses") } fmt.Println("Local IP:", localIP) fmt.Println("Local MAC:", localMAC) // 目标IP地址 targetIP := net.ParseIP("192.168.1.1") if targetIP == nil { panic("Invalid target IP address") } fmt.Println("Target IP:", targetIP) // 使用gopacket构建ARP请求包 var buf gopacket.SerializeBuffer opts := gopacket.SerializeOptions{} eth := layers.Ethernet{ SrcMAC: localMAC, DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, EthernetType: layers.EthernetTypeARP, } arp := layers.ARP{ AddrType: layers.LinkTypeEthernet, Protocol: layers.EthernetTypeIPv4, HwAddressSize: 6, ProtAddressSize: 4, Operation: layers.ARPRequest, SourceHwAddress: []byte(localMAC), SourceProtAddress: []byte(localIP.To4()), DstHwAddress: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, DstProtAddress: []byte(targetIP.To4()), } if err := gopacket.SerializeLayers(&buf, opts, ð, &arp); err != nil { panic(err) } // 打开网络接口并发送ARP请求包 handle, err := pcap.OpenLive("eth0", 65535, true, pcap.BlockForever) if err != nil { panic(err) } defer handle.Close() if err := handle.WritePacketData(buf.Bytes()); err != nil { panic(err) } // 等待一段时间以获得目标设备的MAC地址 time.Sleep(time.Second) packetSource := packetio.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { arpLayer := packet.Layer(layers.LayerTypeARP) if arpLayer != nil { arpPacket, _ := arpLayer.(*layers.ARP) if arpPacket.Operation == layers.ARPReply && bytes.Equal(arpPacket.SourceProtAddress, targetIP.To4()) { fmt.Println("Target MAC:", net.HardwareAddr(arpPacket.SourceHwAddress)) return } } } panic("Could not resolve target MAC address") }
在範例程式碼中,我們先使用net套件來取得目前裝置的IP和MAC位址。然後,使用net.ParseIP()函數將目標IP位址解析為IP類型的變數。接下來,我們使用gopacket.SerializeLayers()函數來建構ARP請求包。我們先定義Ethernet層,設定來源MAC位址為本地MAC位址,目標MAC位址為廣播位址。然後定義ARP層,設定請求類型為ARP請求,來源MAC位址及來源IP位址為本地MAC位址及本機IP位址,目標MAC位址為0,目標IP位址為目標IP位址。最後,我們透過pcap.OpenLive()函數開啟網路介面並寫入ARP請求包。
我們等待一段時間以便取得目標裝置的回應。使用packetio.NewPacketSource()函數取得接收資料的來源,然後使用for迴圈來遍歷接收到的資料包。如果收到ARP回應,且來源IP位址為目標IP位址,則表示我們已經取得了目標設備的MAC位址。程式輸出目標設備的MAC位址,並結束運作。
使用以上程式碼可以輕鬆地發送ARP請求並取得目標設備的MAC位址。
以上是golang arp請求的詳細內容。更多資訊請關注PHP中文網其他相關文章!