Get the IP address of the virtual network interface

王林
Release: 2024-02-08 22:12:36
forward
1175 people have browsed it

Get the IP address of the virtual network interface

In network communication, virtual network interface is a common network configuration method. It can provide additional network interfaces for computer systems, allowing the system to connect to multiple networks at the same time. Obtaining the IP address of the virtual network interface is an operation we often need to perform when configuring the network. By obtaining the IP address of the virtual network interface, we can ensure the stability and correctness of the network connection. In this article, PHP editor Apple will introduce you to several common methods to obtain the IP address of a virtual network interface to help you better understand and apply this technology.

Question content

How to obtain the IP address of the virtual network interface? This is an interface that looks like this:

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

This is how I retrieve the ip address of a regular interface:

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
}
Copy after login

When I pass lo:0 to the above, net.interfacebyname fails with the following error: route ip net: no such network interface.

Solution

On linux, you can use https://www.php.cn/link/5c528e25e1fdeaf9d8160dc24dbf4d60 to obtain the ip address and label.

This is a library that allows linux user space programs to communicate with the kernel through the netlink interface. Can be used to configure interfaces, routes, etc. or to retrieve information.

The concept of aliases appeared in Linux 2.0, which is formed by adding colons and strings to the interface name when executing ifconfig. This concept has been deprecated since linux 2.2 introduced the possibility of having multiple addresses per interface, see https://www.php.cn/link/96b8294326cb6595573cf2689f3f6dda

Nevertheless, it is backwards compatible, and through the netlink interface you can retrieve attributes including ifa_label, which represents the interface name (including aliases).

Since the question explicitly involves aliases, assume one ip address is configured per interface name. However, this can easily be added to return multiple ip addresses per interface if necessary, as the full netlinkrouteattr data will of course be returned. This will cover both cases.

This might look like this:

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
}
Copy after login

Testing on ubuntu gives:

lo:0 -> 127.0.0.2
Copy after login

This may not be the details you need yet. But it could be a first step in the right direction.

The above is the detailed content of Get the IP address of the virtual network interface. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!