Add network interface discovery and monitoring
This commit is contained in:
93
tendrils.go
Normal file
93
tendrils.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package tendrils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Tendrils struct {
|
||||
goroutines map[string]context.CancelFunc
|
||||
}
|
||||
|
||||
func New() *Tendrils {
|
||||
return &Tendrils{
|
||||
goroutines: map[string]context.CancelFunc{},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tendrils) Run() {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
interfaces := t.listInterfaces()
|
||||
t.updateGoroutines(interfaces)
|
||||
<-ticker.C
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tendrils) listInterfaces() []net.Interface {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] error getting interfaces: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
var validInterfaces []net.Interface
|
||||
for _, iface := range interfaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
}
|
||||
if iface.Flags&net.FlagLoopback != 0 {
|
||||
continue
|
||||
}
|
||||
if iface.Flags&net.FlagPointToPoint != 0 {
|
||||
continue
|
||||
}
|
||||
if iface.Flags&net.FlagBroadcast == 0 {
|
||||
continue
|
||||
}
|
||||
if len(iface.HardwareAddr) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil || len(addrs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
validInterfaces = append(validInterfaces, iface)
|
||||
}
|
||||
|
||||
return validInterfaces
|
||||
}
|
||||
|
||||
func (t *Tendrils) updateGoroutines(interfaces []net.Interface) {
|
||||
current := map[string]bool{}
|
||||
for _, iface := range interfaces {
|
||||
current[iface.Name] = true
|
||||
}
|
||||
|
||||
for name, cancel := range t.goroutines {
|
||||
if !current[name] {
|
||||
log.Printf("interface removed: %s", name)
|
||||
cancel()
|
||||
delete(t.goroutines, name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, iface := range interfaces {
|
||||
if _, exists := t.goroutines[iface.Name]; !exists {
|
||||
log.Printf("interface added: %s", iface.Name)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.goroutines[iface.Name] = cancel
|
||||
go t.handleInterface(ctx, iface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tendrils) handleInterface(ctx context.Context, iface net.Interface) {
|
||||
<-ctx.Done()
|
||||
}
|
||||
Reference in New Issue
Block a user