Refactor stations discovery and add hostapd discovery
This commit is contained in:
parent
69594c2fe4
commit
2922a03724
15 changed files with 1339 additions and 249 deletions
130
internal/station/hostapd/correlation.go
Normal file
130
internal/station/hostapd/correlation.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
package hostapd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/nemunaire/repeater/internal/models"
|
||||
)
|
||||
|
||||
// DHCPCorrelator helps correlate hostapd stations with DHCP leases to discover IP addresses
|
||||
type DHCPCorrelator struct {
|
||||
backend *Backend
|
||||
dhcpLeasesPath string
|
||||
stopChan chan struct{}
|
||||
running bool
|
||||
}
|
||||
|
||||
// NewDHCPCorrelator creates a new DHCP correlator
|
||||
func NewDHCPCorrelator(backend *Backend, dhcpLeasesPath string) *DHCPCorrelator {
|
||||
if dhcpLeasesPath == "" {
|
||||
dhcpLeasesPath = "/var/lib/dhcp/dhcpd.leases"
|
||||
}
|
||||
|
||||
return &DHCPCorrelator{
|
||||
backend: backend,
|
||||
dhcpLeasesPath: dhcpLeasesPath,
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Start begins periodic correlation of DHCP leases with hostapd stations
|
||||
func (dc *DHCPCorrelator) Start() {
|
||||
if dc.running {
|
||||
return
|
||||
}
|
||||
|
||||
dc.running = true
|
||||
go dc.correlationLoop()
|
||||
log.Printf("DHCP correlation started for hostapd backend")
|
||||
}
|
||||
|
||||
// Stop stops the correlation loop
|
||||
func (dc *DHCPCorrelator) Stop() {
|
||||
if !dc.running {
|
||||
return
|
||||
}
|
||||
|
||||
dc.running = false
|
||||
close(dc.stopChan)
|
||||
log.Printf("DHCP correlation stopped")
|
||||
}
|
||||
|
||||
// correlationLoop periodically correlates DHCP leases with stations
|
||||
func (dc *DHCPCorrelator) correlationLoop() {
|
||||
// Do an initial correlation immediately
|
||||
dc.correlate()
|
||||
|
||||
// Then correlate every 10 seconds
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
dc.correlate()
|
||||
case <-dc.stopChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// correlate performs one correlation cycle
|
||||
func (dc *DHCPCorrelator) correlate() {
|
||||
// Parse DHCP leases
|
||||
leases, err := parseDHCPLeases(dc.dhcpLeasesPath)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to parse DHCP leases: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Build MAC -> IP mapping
|
||||
macToIP := make(map[string]string)
|
||||
for _, lease := range leases {
|
||||
macToIP[lease.MAC] = lease.IP
|
||||
}
|
||||
|
||||
// Update backend with IP mappings
|
||||
dc.backend.UpdateIPMapping(macToIP)
|
||||
}
|
||||
|
||||
// parseDHCPLeases reads and parses DHCP lease file
|
||||
func parseDHCPLeases(path string) ([]models.DHCPLease, error) {
|
||||
var leases []models.DHCPLease
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return leases, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
var currentLease models.DHCPLease
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if strings.HasPrefix(line, "lease ") {
|
||||
ip := strings.Fields(line)[1]
|
||||
currentLease = models.DHCPLease{IP: ip}
|
||||
} else if strings.Contains(line, "hardware ethernet") {
|
||||
mac := strings.Fields(line)[2]
|
||||
mac = strings.TrimSuffix(mac, ";")
|
||||
currentLease.MAC = mac
|
||||
} else if strings.Contains(line, "client-hostname") {
|
||||
hostname := strings.Fields(line)[1]
|
||||
hostname = strings.Trim(hostname, `";`)
|
||||
currentLease.Hostname = hostname
|
||||
} else if line == "}" {
|
||||
if currentLease.IP != "" && currentLease.MAC != "" {
|
||||
leases = append(leases, currentLease)
|
||||
}
|
||||
currentLease = models.DHCPLease{}
|
||||
}
|
||||
}
|
||||
|
||||
return leases, scanner.Err()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue