key interfaces by name when available and normalize port names
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
35
nodes.go
35
nodes.go
@@ -91,12 +91,18 @@ func (n *Nodes) Update(mac net.HardwareAddr, ips []net.IP, ifaceName, nodeName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
macKey := mac.String()
|
macKey := mac.String()
|
||||||
var targetID int
|
targetID := -1
|
||||||
isNew := false
|
isNew := false
|
||||||
|
|
||||||
if id, exists := n.macIndex[macKey]; exists {
|
if id, exists := n.macIndex[macKey]; exists {
|
||||||
targetID = id
|
if _, nodeExists := n.nodes[id]; nodeExists {
|
||||||
} else {
|
targetID = id
|
||||||
|
} else {
|
||||||
|
delete(n.macIndex, macKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if targetID == -1 {
|
||||||
targetID = n.nextID
|
targetID = n.nextID
|
||||||
n.nextID++
|
n.nextID++
|
||||||
n.nodes[targetID] = &Node{
|
n.nodes[targetID] = &Node{
|
||||||
@@ -108,15 +114,24 @@ func (n *Nodes) Update(mac net.HardwareAddr, ips []net.IP, ifaceName, nodeName,
|
|||||||
node := n.nodes[targetID]
|
node := n.nodes[targetID]
|
||||||
var added []string
|
var added []string
|
||||||
|
|
||||||
iface, exists := node.Interfaces[macKey]
|
ifaceKey := macKey
|
||||||
|
if ifaceName != "" {
|
||||||
|
ifaceKey = ifaceName
|
||||||
|
}
|
||||||
|
|
||||||
|
iface, exists := node.Interfaces[ifaceKey]
|
||||||
if !exists {
|
if !exists {
|
||||||
iface = &Interface{
|
iface = &Interface{
|
||||||
MAC: mac,
|
Name: ifaceName,
|
||||||
IPs: map[string]net.IP{},
|
MAC: mac,
|
||||||
|
IPs: map[string]net.IP{},
|
||||||
}
|
}
|
||||||
node.Interfaces[macKey] = iface
|
node.Interfaces[ifaceKey] = iface
|
||||||
|
added = append(added, "iface="+ifaceKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := n.macIndex[macKey]; !exists {
|
||||||
n.macIndex[macKey] = targetID
|
n.macIndex[macKey] = targetID
|
||||||
added = append(added, "mac="+macKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
@@ -128,10 +143,6 @@ func (n *Nodes) Update(mac net.HardwareAddr, ips []net.IP, ifaceName, nodeName,
|
|||||||
n.ipIndex[ipKey] = targetID
|
n.ipIndex[ipKey] = targetID
|
||||||
}
|
}
|
||||||
|
|
||||||
if ifaceName != "" && iface.Name == "" {
|
|
||||||
iface.Name = ifaceName
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodeName != "" && node.Name == "" {
|
if nodeName != "" && node.Name == "" {
|
||||||
node.Name = nodeName
|
node.Name = nodeName
|
||||||
}
|
}
|
||||||
|
|||||||
72
snmp.go
72
snmp.go
@@ -5,12 +5,29 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gosnmp/gosnmp"
|
"github.com/gosnmp/gosnmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var portNameRewrites = []struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
repl string
|
||||||
|
}{
|
||||||
|
{regexp.MustCompile(`.*Slot: (\d+) Port: (\d+).*`), "$1/$2"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func rewritePortName(name string) string {
|
||||||
|
for _, rw := range portNameRewrites {
|
||||||
|
if rw.re.MatchString(name) {
|
||||||
|
return rw.re.ReplaceAllString(name, rw.repl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
type snmpConfig struct {
|
type snmpConfig struct {
|
||||||
username string
|
username string
|
||||||
authKey string
|
authKey string
|
||||||
@@ -105,10 +122,6 @@ func (t *Tendrils) querySNMPDevice(ip net.IP) {
|
|||||||
}
|
}
|
||||||
defer snmp.Conn.Close()
|
defer snmp.Conn.Close()
|
||||||
|
|
||||||
if t.DebugSNMP {
|
|
||||||
log.Printf("[snmp] %s: connected", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.querySysName(snmp, ip)
|
t.querySysName(snmp, ip)
|
||||||
t.queryInterfaceMACs(snmp, ip)
|
t.queryInterfaceMACs(snmp, ip)
|
||||||
t.queryBridgeMIB(snmp, ip)
|
t.queryBridgeMIB(snmp, ip)
|
||||||
@@ -152,24 +165,47 @@ func (t *Tendrils) queryInterfaceMACs(snmp *gosnmp.GoSNMP, deviceIP net.IP) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var macs []net.HardwareAddr
|
ifNames := t.getInterfaceNames(snmp)
|
||||||
|
|
||||||
|
type ifaceEntry struct {
|
||||||
|
mac net.HardwareAddr
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
var ifaces []ifaceEntry
|
||||||
|
|
||||||
for _, result := range results {
|
for _, result := range results {
|
||||||
if result.Type == gosnmp.OctetString {
|
if result.Type != gosnmp.OctetString {
|
||||||
macBytes := result.Value.([]byte)
|
continue
|
||||||
if len(macBytes) == 6 {
|
|
||||||
mac := net.HardwareAddr(macBytes)
|
|
||||||
if !isBroadcastOrZero(mac) {
|
|
||||||
macs = append(macs, mac)
|
|
||||||
if t.DebugSNMP {
|
|
||||||
log.Printf("[snmp] %s: interface mac=%s", deviceIP, mac)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macBytes := result.Value.([]byte)
|
||||||
|
if len(macBytes) != 6 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
mac := net.HardwareAddr(macBytes)
|
||||||
|
if isBroadcastOrZero(mac) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
oidSuffix := strings.TrimPrefix(strings.TrimPrefix(result.Name, "."+oid), ".")
|
||||||
|
var ifIndex int
|
||||||
|
if _, err := fmt.Sscanf(oidSuffix, "%d", &ifIndex); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := rewritePortName(ifNames[ifIndex])
|
||||||
|
if t.DebugSNMP {
|
||||||
|
log.Printf("[snmp] %s: interface %d mac=%s name=%s", deviceIP, ifIndex, mac, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
ifaces = append(ifaces, ifaceEntry{mac: mac, name: name})
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mac := range macs {
|
var macs []net.HardwareAddr
|
||||||
t.nodes.Update(mac, nil, "", "", "snmp-ifmac")
|
for _, iface := range ifaces {
|
||||||
|
t.nodes.Update(iface.mac, nil, iface.name, "", "snmp-ifmac")
|
||||||
|
macs = append(macs, iface.mac)
|
||||||
}
|
}
|
||||||
if len(macs) > 1 {
|
if len(macs) > 1 {
|
||||||
t.nodes.Merge(macs, "snmp-ifmac")
|
t.nodes.Merge(macs, "snmp-ifmac")
|
||||||
|
|||||||
Reference in New Issue
Block a user