Reputation: 10846
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
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
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