watchyourlan/internal/routines/scan-routine.go
2025-07-23 21:30:18 +07:00

92 lines
2.1 KiB
Go

package routines
import (
"fmt"
"log/slog"
"time"
"github.com/aceberg/WatchYourLAN/internal/arp"
"github.com/aceberg/WatchYourLAN/internal/check"
"github.com/aceberg/WatchYourLAN/internal/conf"
"github.com/aceberg/WatchYourLAN/internal/db"
"github.com/aceberg/WatchYourLAN/internal/influx"
"github.com/aceberg/WatchYourLAN/internal/models"
"github.com/aceberg/WatchYourLAN/internal/notify"
"github.com/aceberg/WatchYourLAN/internal/prometheus"
)
func startScan(quit chan bool) {
var lastDate, nowDate, plusDate time.Time
var foundHosts []models.Host
for {
select {
case <-quit:
return
default:
nowDate = time.Now()
plusDate = lastDate.Add(time.Duration(conf.AppConfig.Timeout) * time.Second)
if nowDate.After(plusDate) {
foundHosts = arp.Scan(conf.AppConfig.Ifaces, conf.AppConfig.ArpArgs, conf.AppConfig.ArpStrs)
compareHosts(foundHosts)
allHosts = db.Select("now")
lastDate = time.Now()
}
time.Sleep(time.Duration(1) * time.Second)
}
}
}
func compareHosts(foundHosts []models.Host) {
// Make map of found hosts
foundHostsMap := make(map[string]models.Host)
for _, fHost := range foundHosts {
foundHostsMap[fHost.Mac] = fHost
}
for _, aHost := range allHosts {
fHost, exists := foundHostsMap[aHost.Mac]
if exists {
aHost.Iface = fHost.Iface
aHost.IP = fHost.IP
aHost.Date = fHost.Date
aHost.Now = 1
delete(foundHostsMap, aHost.Mac)
} else {
aHost.Now = 0
}
db.Update("now", aHost)
aHost.Date = time.Now().Format("2006-01-02 15:04:05")
histHosts = append(histHosts, aHost)
if conf.AppConfig.HistInDB {
db.Insert("history", aHost)
}
if conf.AppConfig.InfluxEnable {
influx.Add(conf.AppConfig, aHost)
}
if conf.AppConfig.PrometheusEnable {
prometheus.Add(aHost)
}
}
for _, fHost := range foundHostsMap {
fHost.Name, fHost.DNS = check.DNS(fHost)
msg := fmt.Sprintf("WatchYourLAN: unknown host found. Names: '%s', IP: '%s', MAC: '%s', Hw: '%s', Iface: '%s'", fHost.DNS, fHost.IP, fHost.Mac, fHost.Hw, fHost.Iface)
slog.Warn(msg)
notify.Shout(msg, conf.AppConfig.ShoutURL) // Notify through Shoutrrr
db.Insert("now", fHost)
}
}