feat(mac-locations): VLAN-aware port MAC counts, access/trunk thresholds, likely_attachment
Made-with: Cursor
This commit is contained in:
@@ -73,6 +73,8 @@ type Store interface {
|
||||
ListPortDeviceResults(scanID string, filterIP string, filterIfIndex int, limit int) []PortDeviceResult
|
||||
// ListPortDevicesByMac — строки FDB по точному MAC (mac уже в каноническом виде, см. NormalizeMAC).
|
||||
ListPortDevicesByMac(scanID string, mac string, limit int) []PortDeviceResult
|
||||
// CountDistinctMACsPerSwitchPort — число уникальных MAC на каждом (коммутатор, ifIndex, bridge_port, vlan) в скане.
|
||||
CountDistinctMACsPerSwitchPort(scanID string) (map[string]int, error)
|
||||
// PurgeAllScanData удаляет все сканы и связанные строки (хосты, порты, SNMP, LLDP, интерфейсы).
|
||||
PurgeAllScanData() error
|
||||
}
|
||||
@@ -482,6 +484,29 @@ func (s *MemoryStore) ListPortDevicesByMac(scanID string, mac string, limit int)
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *MemoryStore) CountDistinctMACsPerSwitchPort(scanID string) (map[string]int, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
items := s.fdb[scanID]
|
||||
per := make(map[string]map[string]struct{})
|
||||
for _, r := range items {
|
||||
mk := NormalizeMAC(r.MAC)
|
||||
if mk == "" {
|
||||
continue
|
||||
}
|
||||
k := PortFDBLocationKey(r.IP, r.IfIndex, r.BridgePort, r.Vlan)
|
||||
if per[k] == nil {
|
||||
per[k] = make(map[string]struct{})
|
||||
}
|
||||
per[k][mk] = struct{}{}
|
||||
}
|
||||
out := make(map[string]int, len(per))
|
||||
for k, set := range per {
|
||||
out[k] = len(set)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func applyDefaultOptions(opts *ScanOptions) {
|
||||
if opts.PingTimeoutMS <= 0 {
|
||||
opts.PingTimeoutMS = 700
|
||||
|
||||
Reference in New Issue
Block a user