Maison >développement back-end >Golang >Obtenez l'adresse IP de l'interface réseau virtuelle

Obtenez l'adresse IP de l'interface réseau virtuelle

王林
王林avant
2024-02-08 22:12:361226parcourir

Obtenez ladresse IP de linterface réseau virtuelle

Dans la communication réseau, l'interface réseau virtuelle est une méthode de configuration réseau courante. Il peut fournir des interfaces réseau supplémentaires pour les systèmes informatiques, permettant au système de se connecter à plusieurs réseaux en même temps. L'obtention de l'adresse IP de l'interface réseau virtuelle est une opération que nous devons souvent effectuer lors de la configuration du réseau. En obtenant l'adresse IP de l'interface réseau virtuelle, nous pouvons garantir la stabilité et l'exactitude de la connexion réseau. Dans cet article, l'éditeur PHP Apple vous présentera plusieurs méthodes courantes pour obtenir l'adresse IP d'une interface réseau virtuelle afin de vous aider à mieux comprendre et appliquer cette technologie.

Contenu de la question

Comment obtenir l'adresse IP de l'interface réseau virtuelle ? C'est une interface qui ressemble à ceci :

lo:0: flags=73<up,loopback,running>  mtu 65536
        inet 192.168.40.1  netmask 255.255.255.255
        loop  txqueuelen 1000  (local loopback)

Voici comment je récupère l'adresse IP d'une interface classique :

func GetInterfaceIpAddr(interfaceName string) (string, error) {
    var (
        ief      *net.Interface
        addrs    []net.Addr
        ipv4Addr net.IP
    )

    ief, err := net.InterfaceByName(interfaceName)

    if err != nil { // get interface
        log.Info("InterfaceByName failed")
        return "", err
    }

    addrs, err = ief.Addrs()

    if err != nil {
        return "", err
    }

    for _, addr := range addrs { // get ipv4 address
        if ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {
            break
        }
    }
    if ipv4Addr == nil {
        return "", errors.New(fmt.Sprintf("interface %s doesn't have an ipv4 address\n", interfaceName))
    }

    return ipv4Addr.String(), nil
}

Quand je le ferai lo:0 传递给上面时,net.interfacebyname 失败并出现以下错误:route ip+net: no such network interface.

Solution

Sous Linux, vous pouvez utiliser https://www.php.cn/link/5c528e25e1fdeaf9d8160dc24dbf4d60 pour obtenir l'adresse IP et l'étiquette.

Il s'agit d'une bibliothèque qui permet aux programmes de l'espace utilisateur Linux de communiquer avec le noyau via l'interface netlink. Peut être utilisé pour configurer des interfaces, des routes, etc. ou pour récupérer des informations.

Le concept d'alias est apparu dans Linux 2.0, qui est formé en ajoutant des deux-points et des chaînes au nom de l'interface lors de l'exécution de ifconfig. Ce concept est obsolète depuis que Linux 2.2 a introduit la possibilité d'avoir plusieurs adresses par interface, voir https://www.php.cn/link/96b8294326cb6595573cf2689f3f6dda

Néanmoins, il est rétrocompatible, et via l'interface netlink vous pouvez récupérer des attributs dont ifa_label, qui représente le nom de l'interface (y compris les alias).

Étant donné que la question implique explicitement des alias, supposez qu'une adresse IP est configurée par nom d'interface. Cependant, il peut facilement être ajouté pour renvoyer plusieurs adresses IP par interface si nécessaire, car les données netlinkrouteattr complètes seront bien sûr renvoyées. Cela couvrira les deux cas.

Cela pourrait ressembler à ceci :

package main

import (
    "fmt"
    "github.com/vishvananda/netlink"
    "github.com/vishvananda/netlink/nl"
    "net"
    "syscall"
)

func main() {
    interfacename := "lo:0"
    ip, err := getinterfaceipaddr(interfacename)
    if err != nil {
        fmt.println(err)
        return
    }
    fmt.printf("%s -> %s\n", interfacename, ip)
}

func getinterfaceipaddr(interfacename string) (string, error) {
    ifis, err := interfaces(netlink.family_v4)
    if err != nil {
        return "", err
    }
    ip, ok := ifis[interfacename]
    if !ok {
        return "", fmt.errorf("%s not found", interfacename)
    }
    return ip.string(), nil
}

func interfaces(family int) (map[string]net.ip, error) {
    req := nl.newnetlinkrequest(syscall.rtm_getaddr, syscall.nlm_f_dump)
    msg := nl.newifinfomsg(family)
    req.adddata(msg)
    messages, err := req.execute(syscall.netlink_route, syscall.rtm_newaddr)
    if err != nil {
        return nil, err
    }
    ifis := make(map[string]net.ip)
    for _, m := range messages {
        msg := nl.deserializeifaddrmsg(m)
        attrs, err := nl.parserouteattr(m[msg.len():])
        if err != nil {
            return nil, err
        }
        var ip net.ip
        var label string
        for _, attr := range attrs {
            switch attr.attr.type {
            case syscall.ifa_local:
                ip = attr.value
            case syscall.ifa_label:
                label = string(attr.value[:len(attr.value)-1])
            }
        }
        if ip != nil && label != "" {
            ifis[label] = ip
        }
    }
    return ifis, nil
}
Tester sur

ubuntu donne :

lo:0 -> 127.0.0.2

Ce ne sont peut-être pas encore les détails dont vous avez besoin. Mais cela pourrait être un premier pas dans la bonne direction.

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer