Query DHCP binding table from Netgear switches via SNMP

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ian Gulliver
2026-01-24 23:11:55 -08:00
parent 1f2b2c2156
commit cc3d84b97e

61
snmp.go
View File

@@ -111,6 +111,7 @@ func (t *Tendrils) querySNMPDevice(node *Node, ip net.IP) {
t.queryInterfaceStats(snmp, node, ifNames)
t.queryPoEBudget(snmp, node)
t.queryBridgeMIB(snmp, node, ifNames)
t.queryDHCPBindings(snmp)
}
func (t *Tendrils) querySysName(snmp *gosnmp.GoSNMP, node *Node) {
@@ -469,3 +470,63 @@ func (t *Tendrils) getInterfaceNames(snmp *gosnmp.GoSNMP) map[int]string {
return names
}
func (t *Tendrils) queryDHCPBindings(snmp *gosnmp.GoSNMP) {
baseOID := "1.3.6.1.4.1.4526.10.12.3.2.1"
ipOID := baseOID + ".1"
macOID := baseOID + ".3"
ipResults, err := snmp.BulkWalkAll(ipOID)
if err != nil {
return
}
macResults, err := snmp.BulkWalkAll(macOID)
if err != nil {
return
}
ips := map[int]net.IP{}
for _, result := range ipResults {
if result.Type != gosnmp.IPAddress {
continue
}
oidSuffix := strings.TrimPrefix(strings.TrimPrefix(result.Name, "."+ipOID), ".")
var idx int
if _, err := fmt.Sscanf(oidSuffix, "%d", &idx); err != nil {
continue
}
ips[idx] = net.ParseIP(result.Value.(string))
}
macs := map[int]net.HardwareAddr{}
for _, result := range macResults {
if result.Type != gosnmp.OctetString {
continue
}
macBytes := result.Value.([]byte)
if len(macBytes) != 6 {
continue
}
oidSuffix := strings.TrimPrefix(strings.TrimPrefix(result.Name, "."+macOID), ".")
var idx int
if _, err := fmt.Sscanf(oidSuffix, "%d", &idx); err != nil {
continue
}
macs[idx] = net.HardwareAddr(macBytes)
}
for idx, ip := range ips {
mac, ok := macs[idx]
if !ok {
continue
}
if isBroadcastOrZero(mac) {
continue
}
if t.DebugSNMP {
log.Printf("[snmp] %s: dhcp binding mac=%s ip=%s", snmp.Target, mac, ip)
}
t.nodes.Update(nil, mac, []net.IP{ip}, "", "", "dhcp")
}
}