Add SNMP v2c probing and results endpoint.

Probe sysName/sysDescr/sysObjectID for alive hosts, persist SNMP outcomes, and expose scan SNMP data via REST.

Made-with: Cursor
This commit is contained in:
Andrey Lutsenko
2026-04-09 21:56:31 +10:00
parent e9452dcc0a
commit cca4477792
10 changed files with 234 additions and 3 deletions
+43
View File
@@ -63,6 +63,8 @@ type Store interface {
ListHostResults(scanID string, limit int) []HostResult
SaveOpenPortResult(scanID string, result OpenPortResult) error
ListOpenPortResults(scanID string, limit int) []OpenPortResult
SaveSNMPResult(scanID string, result SNMPResult) error
ListSNMPResults(scanID string, limit int) []SNMPResult
}
type HostResult struct {
@@ -78,11 +80,22 @@ type OpenPortResult struct {
CheckedAt time.Time `json:"checked_at"`
}
type SNMPResult struct {
IP string `json:"ip"`
Success bool `json:"success"`
SysName string `json:"sys_name"`
SysDescr string `json:"sys_descr"`
SysObjectID string `json:"sys_object_id"`
Error string `json:"error,omitempty"`
CheckedAt time.Time `json:"checked_at"`
}
type MemoryStore struct {
mu sync.RWMutex
jobs map[string]ScanJob
hosts map[string][]HostResult
ports map[string][]OpenPortResult
snmp map[string][]SNMPResult
}
func NewMemoryStore() *MemoryStore {
@@ -90,6 +103,7 @@ func NewMemoryStore() *MemoryStore {
jobs: make(map[string]ScanJob),
hosts: make(map[string][]HostResult),
ports: make(map[string][]OpenPortResult),
snmp: make(map[string][]SNMPResult),
}
}
@@ -240,6 +254,35 @@ func (s *MemoryStore) ListOpenPortResults(scanID string, limit int) []OpenPortRe
return out
}
func (s *MemoryStore) SaveSNMPResult(scanID string, result SNMPResult) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.jobs[scanID]; !ok {
return errors.New("scan not found")
}
s.snmp[scanID] = append(s.snmp[scanID], result)
return nil
}
func (s *MemoryStore) ListSNMPResults(scanID string, limit int) []SNMPResult {
if limit <= 0 {
limit = 1000
}
s.mu.RLock()
defer s.mu.RUnlock()
items := s.snmp[scanID]
if len(items) <= limit {
out := make([]SNMPResult, len(items))
copy(out, items)
return out
}
out := make([]SNMPResult, limit)
copy(out, items[:limit])
return out
}
func applyDefaultOptions(opts *ScanOptions) {
if opts.PingTimeoutMS <= 0 {
opts.PingTimeoutMS = 700