Maison >développement back-end >Golang >demande d'arp golang

demande d'arp golang

WBOY
WBOYoriginal
2023-05-16 17:51:081322parcourir

Cet article expliquera comment utiliser Golang pour envoyer une requête ARP afin d'obtenir l'adresse MAC du périphérique cible.

ARP (Address Resolution Protocol) est un protocole qui résout les adresses de couche réseau (adresses IP) et les adresses de couche liaison de données (adresses MAC). Dans un réseau local, chaque appareil possède une adresse MAC unique qui l'identifie. Lorsque nous connaissons l'adresse IP de l'appareil cible, mais pas son adresse MAC, nous pouvons envoyer une requête ARP pour obtenir l'adresse MAC de l'appareil.

Dans Golang, nous pouvons utiliser la fonction net.InterfaceAddrs() dans le package net pour obtenir l'adresse IP et MAC de l'appareil actuel. Ensuite, utilisez la fonction net.ParseIP() dans le package net pour analyser l'adresse IP cible dans une variable de type IP. Ensuite, utilisez la bibliothèque gopacket pour créer un paquet de requête ARP et l'envoyer au réseau.

Jetons un coup d'œil à l'exemple de code :

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")
}

Dans l'exemple de code, nous utilisons d'abord le package net pour obtenir l'adresse IP et MAC de l'appareil actuel. Ensuite, utilisez la fonction net.ParseIP() pour analyser l'adresse IP cible en une variable de type IP. Ensuite, nous utilisons la fonction gopacket.SerializeLayers() pour créer le paquet de requête ARP. Nous définissons d'abord la couche Ethernet, définissons l'adresse MAC source sur l'adresse MAC locale et l'adresse MAC de destination sur l'adresse de diffusion. Définissez ensuite la couche ARP, définissez le type de requête sur Requête ARP, l'adresse MAC source et l'adresse IP source sur l'adresse MAC locale et l'adresse IP locale, l'adresse MAC cible sur 0 et l'adresse IP cible sur l'adresse IP cible. Enfin, nous ouvrons l'interface réseau via la fonction pcap.OpenLive() et écrivons le paquet de requête ARP.

Nous attendons un certain temps pour obtenir la réponse de l'appareil cible. Utilisez la fonction packetio.NewPacketSource() pour obtenir la source des données reçues, puis utilisez une boucle for pour parcourir les paquets reçus. Si une réponse ARP est reçue et que l'adresse IP source est l'adresse IP de destination, cela signifie que nous avons obtenu l'adresse MAC du périphérique de destination. Le programme génère l'adresse MAC du périphérique cible et termine l'exécution.

Utilisez le code ci-dessus pour envoyer facilement une requête ARP et obtenir l'adresse MAC de l'appareil cible.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:installation de Golang LinuxArticle suivant:installation de Golang Linux