ホームページ  >  記事  >  バックエンド開発  >  golang arp リクエスト

golang arp リクエスト

WBOY
WBOYオリジナル
2023-05-16 17:51:081303ブラウズ

この記事では、Golang を使用して ARP リクエストを送信し、ターゲット デバイスの MAC アドレスを取得する方法を紹介します。

ARP (Address Resolution Protocol) は、ネットワーク層アドレス (IP アドレス) とデータリンク層アドレス (MAC アドレス) を解決するプロトコルです。 LAN では、各デバイスはデバイスを識別する一意の 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, &eth, &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 リクエスト パケットを構築します。まずイーサネット層を定義し、送信元 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。