Artikel ini akan memperkenalkan cara menggunakan Golang untuk menghantar permintaan ARP untuk mendapatkan alamat MAC peranti sasaran.
ARP (Address Resolution Protocol) ialah protokol yang menyelesaikan alamat lapisan rangkaian (alamat IP) dan alamat lapisan pautan data (alamat MAC). Dalam LAN, setiap peranti mempunyai alamat MAC unik yang mengenal pasti peranti tersebut. Apabila kami mengetahui alamat IP peranti sasaran, tetapi bukan alamat MACnya, kami boleh menghantar permintaan ARP untuk mendapatkan alamat MAC peranti tersebut.
Di Golang, kita boleh menggunakan fungsi net.InterfaceAddrs() dalam pakej bersih untuk mendapatkan alamat IP dan MAC peranti semasa. Kemudian, gunakan fungsi net.ParseIP() dalam pakej bersih untuk menghuraikan alamat IP sasaran kepada pembolehubah jenis IP. Seterusnya, gunakan perpustakaan gopacket untuk membina paket permintaan ARP dan hantar ke rangkaian.
Mari kita lihat contoh kod:
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") }
Dalam kod sampel, kami mula-mula menggunakan pakej bersih untuk mendapatkan alamat IP dan MAC peranti semasa. Kemudian, gunakan fungsi net.ParseIP() untuk menghuraikan alamat IP sasaran kepada pembolehubah jenis IP. Seterusnya, kami menggunakan fungsi gopacket.SerializeLayers() untuk membina paket permintaan ARP. Kami mula-mula menentukan lapisan Ethernet, tetapkan alamat MAC sumber kepada alamat MAC tempatan, dan alamat MAC destinasi kepada alamat siaran. Kemudian tentukan lapisan ARP, tetapkan jenis permintaan kepada permintaan ARP, alamat MAC sumber dan alamat IP sumber kepada alamat MAC tempatan dan alamat IP tempatan, alamat MAC sasaran kepada 0, dan alamat IP sasaran kepada alamat IP sasaran. Akhir sekali, kami membuka antara muka rangkaian melalui fungsi pcap.OpenLive() dan tulis paket permintaan ARP.
Kami menunggu seketika untuk mendapat respons daripada peranti sasaran. Gunakan fungsi packetio.NewPacketSource() untuk mendapatkan sumber data yang diterima, dan kemudian gunakan gelung for untuk mengulangi paket yang diterima. Jika respons ARP diterima dan alamat IP sumber ialah alamat IP destinasi, ini bermakna kami telah memperoleh alamat MAC peranti destinasi. Program ini mengeluarkan alamat MAC peranti sasaran dan menamatkan larian.
Gunakan kod di atas untuk menghantar permintaan ARP dengan mudah dan mendapatkan alamat MAC peranti sasaran.
Atas ialah kandungan terperinci permintaan golang arp. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!