Scan routine
This commit is contained in:
parent
73db704cf7
commit
3a3bc5da09
11 changed files with 142 additions and 50 deletions
|
|
@ -18,6 +18,8 @@ func Get(path string) (config models.Conf) {
|
|||
viper.SetDefault("SCANER", "arpscan")
|
||||
viper.SetDefault("ARPARGS", "")
|
||||
viper.SetDefault("IFACES", "")
|
||||
viper.SetDefault("TIMEOUT", 60)
|
||||
viper.SetDefault("IGNOREIP", "no")
|
||||
|
||||
viper.SetConfigFile(path)
|
||||
viper.SetConfigType("yaml")
|
||||
|
|
@ -34,6 +36,8 @@ func Get(path string) (config models.Conf) {
|
|||
config.Scaner = viper.Get("SCANER").(string)
|
||||
config.ArpArgs = viper.Get("ARPARGS").(string)
|
||||
config.Ifaces = viper.Get("IFACES").(string)
|
||||
config.Timeout = viper.GetInt("TIMEOUT")
|
||||
config.IgnoreIP = viper.Get("IGNOREIP").(string)
|
||||
|
||||
return config
|
||||
}
|
||||
|
|
@ -52,6 +56,8 @@ func Write(config models.Conf) {
|
|||
viper.Set("SCANER", config.Scaner)
|
||||
viper.Set("ARPARGS", config.ArpArgs)
|
||||
viper.Set("IFACES", config.Ifaces)
|
||||
viper.Set("TIMEOUT", config.Timeout)
|
||||
viper.Set("IGNOREIP", config.IgnoreIP)
|
||||
|
||||
err := viper.WriteConfig()
|
||||
check.IfError(err)
|
||||
|
|
|
|||
|
|
@ -21,41 +21,55 @@ func Create(path string) {
|
|||
"NOW" INTEGER DEFAULT 0
|
||||
);`
|
||||
dbExec(path, sqlStatement)
|
||||
|
||||
sqlStatement = `CREATE TABLE IF NOT EXISTS "history" (
|
||||
"ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
"NAME" TEXT NOT NULL,
|
||||
"IFACE" TEXT,
|
||||
"IP" TEXT,
|
||||
"MAC" TEXT,
|
||||
"HW" TEXT,
|
||||
"DATE" TEXT,
|
||||
"KNOWN" INTEGER DEFAULT 0,
|
||||
"NOW" INTEGER DEFAULT 0
|
||||
);`
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Insert - insert host into table
|
||||
func Insert(path string, oneHost models.Host) {
|
||||
func Insert(path, table string, oneHost models.Host) {
|
||||
oneHost.Name = quoteStr(oneHost.Name)
|
||||
oneHost.Hw = quoteStr(oneHost.Hw)
|
||||
sqlStatement := `INSERT INTO "now" (NAME, IFACE, IP, MAC, HW, DATE, KNOWN, NOW)
|
||||
sqlStatement := `INSERT INTO '%s' (NAME, IFACE, IP, MAC, HW, DATE, KNOWN, NOW)
|
||||
VALUES ('%s','%s','%s','%s','%s','%s','%d','%d');`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now)
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, table, oneHost.Name, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now)
|
||||
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Update - update host
|
||||
func Update(path string, oneHost models.Host) {
|
||||
func Update(path, table string, oneHost models.Host) {
|
||||
oneHost.Name = quoteStr(oneHost.Name)
|
||||
oneHost.Hw = quoteStr(oneHost.Hw)
|
||||
sqlStatement := `UPDATE "now" set
|
||||
sqlStatement := `UPDATE '%s' set
|
||||
NAME = '%s', IFACE = '%s', IP = '%s', MAC = '%s', HW = '%s', DATE = '%s',
|
||||
KNOWN = '%d', NOW = '%d'
|
||||
WHERE ID = '%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.ID)
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, table, oneHost.Name, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.ID)
|
||||
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Delete - delete host from DB
|
||||
func Delete(path string, id int) {
|
||||
sqlStatement := `DELETE FROM "now" WHERE ID='%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, id)
|
||||
func Delete(path, table string, id int) {
|
||||
sqlStatement := `DELETE FROM '%s' WHERE ID='%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, table, id)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Clear - delete all hosts from table
|
||||
func Clear(path string) {
|
||||
sqlStatement := `DELETE FROM "now";`
|
||||
func Clear(path, table string) {
|
||||
sqlStatement := `DELETE FROM '%s';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, table)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ func dbExec(path, sqlStatement string) {
|
|||
}
|
||||
|
||||
// Select - select all hosts
|
||||
func Select(path string) (dbHosts []models.Host) {
|
||||
func Select(path, table string) (dbHosts []models.Host) {
|
||||
|
||||
sqlStatement := `SELECT * FROM "now" ORDER BY DATE DESC`
|
||||
sqlStatement := "SELECT * FROM " + table + " ORDER BY DATE DESC"
|
||||
|
||||
mu.Lock()
|
||||
db, _ := sqlx.Connect("sqlite", path)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ type Conf struct {
|
|||
Ifaces string
|
||||
Scaner string
|
||||
ArpArgs string
|
||||
Timeout int
|
||||
IgnoreIP string
|
||||
}
|
||||
|
||||
// Host - one host
|
||||
|
|
@ -28,24 +30,10 @@ type Host struct {
|
|||
Now int `db:"NOW"`
|
||||
}
|
||||
|
||||
// History for hosts
|
||||
type History struct {
|
||||
ID int `db:"ID"`
|
||||
Host int `db:"HOST"`
|
||||
Name string `db:"NAME"`
|
||||
IP string `db:"IP"`
|
||||
Mac string `db:"MAC"`
|
||||
Hw string `db:"HW"`
|
||||
Date string `db:"DATE"`
|
||||
Known int `db:"KNOWN"`
|
||||
State int `db:"STATE"`
|
||||
}
|
||||
|
||||
// GuiData - all data sent to html page
|
||||
type GuiData struct {
|
||||
Config Conf
|
||||
Hosts []Host
|
||||
Themes []string
|
||||
Version string
|
||||
Hist []History
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ var (
|
|||
appConfig models.Conf
|
||||
|
||||
allHosts []models.Host
|
||||
// histHosts []models.Host
|
||||
|
||||
quitScan chan bool
|
||||
)
|
||||
|
||||
// templFS - html templates
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
.my-button {
|
||||
.my-btn {
|
||||
height: 100%;
|
||||
background-color: #00000000;
|
||||
color: var(--bs-primary);
|
||||
text-align: center;
|
||||
}
|
||||
.my-button:hover {
|
||||
.my-btn:hover {
|
||||
background-color: #0000001a;
|
||||
}
|
||||
|
|
@ -11,10 +11,18 @@ function createHTML(addr, i) {
|
|||
now = `<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>`;
|
||||
}
|
||||
|
||||
let known = '';
|
||||
|
||||
if (addr.Known == 1) {
|
||||
known = `<button type="button" class="btn btn-success">Yes</button>`;
|
||||
} else {
|
||||
known = `<button type="button" class="btn btn-warning" disabled>No</button>`;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<tr>
|
||||
<td style="opacity: 45%;">${i}.</td>
|
||||
<td>${addr.Name}</td>
|
||||
<td><input name="name" type="text" class="form-control" value="${addr.Name}"></td>
|
||||
<td>${addr.Iface}</td>
|
||||
<td>
|
||||
<a href="http://${addr.IP}">${addr.IP}</a>
|
||||
|
|
@ -22,7 +30,7 @@ function createHTML(addr, i) {
|
|||
<td>${addr.Mac}</td>
|
||||
<td>${addr.Hw}</td>
|
||||
<td>${addr.Date}</td>
|
||||
<td>${addr.Known}</td>
|
||||
<td>${known}</td>
|
||||
<td>${now}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
|
|
|||
80
internal/web/scan.go
Normal file
80
internal/web/scan.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
// "log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/arp"
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
func updateScan() {
|
||||
db.Create(appConfig.DBPath)
|
||||
|
||||
allHosts = db.Select(appConfig.DBPath, "now")
|
||||
// histHosts = db.Select(appConfig.DBPath, "history")
|
||||
|
||||
quitScan = make(chan bool)
|
||||
go startScan()
|
||||
}
|
||||
|
||||
func startScan() {
|
||||
var lastDate time.Time
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-quitScan:
|
||||
return
|
||||
default:
|
||||
nowDate := time.Now()
|
||||
plusDate := lastDate.Add(time.Duration(appConfig.Timeout) * time.Second)
|
||||
|
||||
if nowDate.After(plusDate) {
|
||||
|
||||
foundHosts := arp.Scan(appConfig.Ifaces)
|
||||
compareHosts(foundHosts)
|
||||
allHosts = db.Select(appConfig.DBPath, "now")
|
||||
// histHosts = db.Select(appConfig.DBPath, "history")
|
||||
|
||||
lastDate = time.Now()
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(1) * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func compareHosts(foundHosts []models.Host) {
|
||||
|
||||
// Make map and Insert history
|
||||
foundHostsMap := make(map[string]models.Host)
|
||||
for _, fHost := range foundHosts {
|
||||
foundHostsMap[fHost.Mac] = fHost
|
||||
db.Insert(appConfig.DBPath, "history", fHost)
|
||||
}
|
||||
|
||||
for _, aHost := range allHosts {
|
||||
|
||||
fHost, exists := foundHostsMap[aHost.Mac]
|
||||
if exists && (appConfig.IgnoreIP == "yes" || aHost.IP == fHost.IP) {
|
||||
|
||||
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(appConfig.DBPath, "now", aHost)
|
||||
}
|
||||
|
||||
for _, fHost := range foundHostsMap {
|
||||
|
||||
// NOTIFY, LOG
|
||||
db.Insert(appConfig.DBPath, "now", fHost)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
<link href="{{ .Config.NodePath }}/node_modules/bootswatch/dist/{{ .Config.Theme }}/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="{{ .Config.NodePath }}/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
{{ end }}
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="/fs/public/css/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary">
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@
|
|||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th style="width: 3em;"></th>
|
||||
<th>Name <i class="bi bi-sort-down-alt" onclick="sortBy('Name')"></i></th>
|
||||
<th>Iface <i class="bi bi-sort-down-alt" onclick="sortBy('Iface')"></i></th>
|
||||
<th>IP <i class="bi bi-sort-down-alt" onclick="sortBy('IP')"></i></th>
|
||||
<th>MAC <i class="bi bi-sort-down-alt" onclick="sortBy('Mac')"></i></th>
|
||||
<th>Hardware <i class="bi bi-sort-down-alt" onclick="sortBy('Hw')"></i></th>
|
||||
<th>Date <i class="bi bi-sort-down-alt" onclick="sortBy('Date')"></i></th>
|
||||
<th>Known <i class="bi bi-sort-down-alt" onclick="sortBy('Known')"></i></th>
|
||||
<th>Online <i class="bi bi-sort-down-alt" onclick="sortBy('Now')"></i></th>
|
||||
<th>Name <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Name')"></i></th>
|
||||
<th>Iface <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Iface')"></i></th>
|
||||
<th>IP <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('IP')"></i></th>
|
||||
<th>MAC <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Mac')"></i></th>
|
||||
<th>Hardware <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Hw')"></i></th>
|
||||
<th>Date <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Date')"></i></th>
|
||||
<th>Known <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Known')"></i></th>
|
||||
<th>Online <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Now')"></i></th>
|
||||
</thead>
|
||||
<tbody id="tBody"></tbody>
|
||||
<!-- index.js -->
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/arp"
|
||||
"github.com/aceberg/WatchYourLAN/internal/check"
|
||||
"github.com/aceberg/WatchYourLAN/internal/conf"
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
)
|
||||
|
||||
// Gui - start web server
|
||||
|
|
@ -26,6 +24,8 @@ func Gui(dirPath, nodePath string) {
|
|||
appConfig.DBPath = dirPath + "/scan.db"
|
||||
appConfig.NodePath = nodePath
|
||||
|
||||
updateScan() // scan.go
|
||||
|
||||
slog.Info("config", "path", appConfig.DirPath)
|
||||
|
||||
address := appConfig.Host + ":" + appConfig.Port
|
||||
|
|
@ -34,11 +34,6 @@ func Gui(dirPath, nodePath string) {
|
|||
slog.Info("Web GUI at http://" + address)
|
||||
slog.Info("=================================== ")
|
||||
|
||||
updateAllHosts()
|
||||
// Run scan
|
||||
allHosts = arp.Scan(appConfig.Ifaces)
|
||||
slog.Info("ARPSCAN:", "found", allHosts)
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
router := gin.Default()
|
||||
|
||||
|
|
@ -57,7 +52,3 @@ func Gui(dirPath, nodePath string) {
|
|||
err := router.Run(address)
|
||||
check.IfError(err)
|
||||
}
|
||||
|
||||
func updateAllHosts() {
|
||||
allHosts = db.Select(appConfig.DBPath)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue