add flags for disabling discovery and controlling logging

This commit is contained in:
Ian Gulliver
2026-01-17 21:02:30 -08:00
parent 477b6e9c99
commit 3c8afa9bdf
4 changed files with 54 additions and 21 deletions

2
arp.go
View File

@@ -37,7 +37,7 @@ func (t *Tendrils) readARPTable() {
entries := t.parseARPTable() entries := t.parseARPTable()
for _, entry := range entries { for _, entry := range entries {
if t.iface != "" && entry.iface != t.iface { if t.Interface != "" && entry.iface != t.Interface {
continue continue
} }
if isBroadcastOrZero(entry.mac) { if isBroadcastOrZero(entry.mac) {

View File

@@ -7,9 +7,20 @@ import (
) )
func main() { func main() {
iface := flag.String("i", "", "interface to use (default: all interfaces)") iface := flag.String("i", "", "interface to use")
noARP := flag.Bool("no-arp", false, "disable ARP discovery")
noLLDP := flag.Bool("no-lldp", false, "disable LLDP discovery")
noSNMP := flag.Bool("no-snmp", false, "disable SNMP discovery")
logTree := flag.Bool("log-tree", false, "log full tree on changes")
logReasons := flag.Bool("log-reasons", false, "log addition reasons")
flag.Parse() flag.Parse()
t := tendrils.New(*iface) t := tendrils.New()
t.Interface = *iface
t.DisableARP = *noARP
t.DisableLLDP = *noLLDP
t.DisableSNMP = *noSNMP
t.LogTree = *logTree
t.LogReasons = *logReasons
t.Run() t.Run()
} }

View File

@@ -44,14 +44,16 @@ type Nodes struct {
ipIndex map[string]int ipIndex map[string]int
macIndex map[string]int macIndex map[string]int
nextID int nextID int
t *Tendrils
} }
func NewNodes() *Nodes { func NewNodes(t *Tendrils) *Nodes {
n := &Nodes{ n := &Nodes{
nodes: map[int]*Node{}, nodes: map[int]*Node{},
ipIndex: map[string]int{}, ipIndex: map[string]int{},
macIndex: map[string]int{}, macIndex: map[string]int{},
nextID: 1, nextID: 1,
t: t,
} }
n.nodes[0] = &Node{ n.nodes[0] = &Node{
@@ -122,11 +124,15 @@ func (n *Nodes) UpdateWithParent(parentIP net.IP, ips []net.IP, macs []net.Hardw
merging = append(merging, n.nodes[ids[i]].String()) merging = append(merging, n.nodes[ids[i]].String())
n.mergeNodes(targetID, ids[i]) n.mergeNodes(targetID, ids[i])
} }
if n.t.LogReasons {
log.Printf("merged nodes %v into %s (via %s)", merging, n.nodes[targetID], source) log.Printf("merged nodes %v into %s (via %s)", merging, n.nodes[targetID], source)
}
if n.t.LogTree {
n.mu.Unlock() n.mu.Unlock()
n.LogTree() n.LogTree()
n.mu.Lock() n.mu.Lock()
} }
}
node := n.nodes[targetID] node := n.nodes[targetID]
var added []string var added []string
@@ -162,12 +168,16 @@ func (n *Nodes) UpdateWithParent(parentIP net.IP, ips []net.IP, macs []net.Hardw
} }
if len(added) > 0 { if len(added) > 0 {
if n.t.LogReasons {
log.Printf("updated %s +%v (via %s)", node, added, source) log.Printf("updated %s +%v (via %s)", node, added, source)
}
if n.t.LogTree {
n.mu.Unlock() n.mu.Unlock()
n.LogTree() n.LogTree()
n.mu.Lock() n.mu.Lock()
} }
} }
}
func (n *Nodes) mergeNodes(keepID, mergeID int) { func (n *Nodes) mergeNodes(keepID, mergeID int) {
keep := n.nodes[keepID] keep := n.nodes[keepID]

View File

@@ -11,15 +11,21 @@ import (
type Tendrils struct { type Tendrils struct {
activeInterfaces map[string]context.CancelFunc activeInterfaces map[string]context.CancelFunc
nodes *Nodes nodes *Nodes
iface string
Interface string
DisableARP bool
DisableLLDP bool
DisableSNMP bool
LogTree bool
LogReasons bool
} }
func New(iface string) *Tendrils { func New() *Tendrils {
return &Tendrils{ t := &Tendrils{
activeInterfaces: map[string]context.CancelFunc{}, activeInterfaces: map[string]context.CancelFunc{},
nodes: NewNodes(),
iface: iface,
} }
t.nodes = NewNodes(t)
return t
} }
func (t *Tendrils) Run() { func (t *Tendrils) Run() {
@@ -28,8 +34,12 @@ func (t *Tendrils) Run() {
t.populateLocalAddresses() t.populateLocalAddresses()
if !t.DisableARP {
go t.pollARP(ctx) go t.pollARP(ctx)
}
if !t.DisableSNMP {
go t.pollSNMP(ctx) go t.pollSNMP(ctx)
}
ticker := time.NewTicker(1 * time.Second) ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop() defer ticker.Stop()
@@ -90,7 +100,7 @@ func (t *Tendrils) listInterfaces() []net.Interface {
var validInterfaces []net.Interface var validInterfaces []net.Interface
for _, iface := range interfaces { for _, iface := range interfaces {
if t.iface != "" && iface.Name != t.iface { if t.Interface != "" && iface.Name != t.Interface {
continue continue
} }
if iface.Flags&net.FlagUp == 0 { if iface.Flags&net.FlagUp == 0 {
@@ -145,5 +155,7 @@ func (t *Tendrils) updateInterfaces(interfaces []net.Interface) {
} }
func (t *Tendrils) startInterface(ctx context.Context, iface net.Interface) { func (t *Tendrils) startInterface(ctx context.Context, iface net.Interface) {
if !t.DisableLLDP {
go t.listenLLDP(ctx, iface) go t.listenLLDP(ctx, iface)
} }
}