The user with no hat
The user with no hat

Reputation: 10846

How to monitor a network interface ( go-lang)

I need to monitor the local address(IP) of a network interface(i.e. whenever it's changed or the interface is unplugged do some stuff) and I'm wondering what's the best way to do that. Currently I'm using InterfaceByName to get and verify/match the interface details in an infinite loop. I monitor several interfaces so I'm wondering if it's a bad thing or if I should use some delays etc. It would be great if the OS would send a signal whenever the interface is updated but I'm not aware of a such thing.

Upvotes: 3

Views: 4605

Answers (2)

Cyberience
Cyberience

Reputation: 1078

In Golang, you can achieve network interface monitoring by utilizing the net and syscall packages, as well as the platform-specific features provided by the underlying operating system. Here's an example implementation:

package main

import (
    "fmt"
    "net"
    "os"
    "syscall"
    "time"
)

func main() {
    interfaceName := "eth0" // Replace with your interface name

    // Retrieve the initial IP address of the interface
    initialIP, err := getCurrentIPAddress(interfaceName)
    if err != nil {
        fmt.Println("Failed to retrieve initial IP address:", err)
        os.Exit(1)
    }

    fmt.Println("Initial IP address:", initialIP)

    // Start monitoring the interface
    for {
        time.Sleep(time.Second) // Delay between each iteration

        // Retrieve the current IP address of the interface
        currentIP, err := getCurrentIPAddress(interfaceName)
        if err != nil {
            fmt.Println("Failed to retrieve current IP address:", err)
            continue
        }

        // Compare current IP with initial IP
        if currentIP != initialIP {
            fmt.Println("IP address changed:", currentIP)
            // Perform actions here for IP address change

            // Update the initial IP address for subsequent comparisons
            initialIP = currentIP
        }
    }
}

func getCurrentIPAddress(interfaceName string) (string, error) {
    iface, err := net.InterfaceByName(interfaceName)
    if err != nil {
        return "", err
    }

    addrs, err := iface.Addrs()
    if err != nil {
        return "", err
    }

    for _, addr := range addrs {
        ipNet, ok := addr.(*net.IPNet)
        if ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
            return ipNet.IP.String(), nil
        }
    }

    return "", fmt.Errorf("No IPv4 address found for interface")
}

This example demonstrates a basic network interface monitoring implementation in Golang. It retrieves the initial IP address of the specified interface and then enters an infinite loop, periodically checking for changes in the IP address. When a change is detected, you can perform the necessary actions in the corresponding section of the code.

Note that this implementation uses the net.InterfaceByName function to retrieve the interface details and the iface.Addrs function to obtain the IP addresses associated with the interface. The example assumes IPv4 addresses; however, you can modify the code to support IPv6 addresses if needed.

Remember to replace "eth0" with the name of the interface you want to monitor. You can also customize the delay between each iteration using the time.Sleep function to adjust the polling interval according to your requirements.

Upvotes: 0

Mr_Pink
Mr_Pink

Reputation: 109416

This is going to be very system specific. On Linux I think the simplest way right now is reading the sysfs files for each interface.

$ cat /sys/class/net/eth0/operstate
up
$ cat /sys/class/net/eth0/carrier
1

Polling them occasionally shouldn't consume too many resources, and give you what you need.

For more timely updates, you can setup a netlink socket to receive NETLINK_ROUTE updates from the kernel. There's a few Go netlink packages around, but I'm not sure how general they are.

Upvotes: 0

Related Questions