refactor
This commit is contained in:
parent
2d2d662f78
commit
4326c673bb
9 changed files with 162 additions and 15 deletions
|
|
@ -2,11 +2,13 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
|
||||||
// Import sqlite module
|
// Import sqlite module
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
"github.com/aceberg/WatchYourLAN/internal/check"
|
"github.com/aceberg/WatchYourLAN/internal/check"
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dbExec(path, sqlStatement string) {
|
func dbExec(path, sqlStatement string) {
|
||||||
|
|
@ -17,3 +19,30 @@ func dbExec(path, sqlStatement string) {
|
||||||
_, err = db.Exec(sqlStatement)
|
_, err = db.Exec(sqlStatement)
|
||||||
check.IfError(err)
|
check.IfError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Select(path string) (dbHosts []models.Host) {
|
||||||
|
db, _ := sql.Open("sqlite", path)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlStatement := `SELECT * FROM "now" ORDER BY DATE DESC`
|
||||||
|
|
||||||
|
res, err := db.Query(sqlStatement)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("ERROR: db_select: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbHosts = []models.Host{}
|
||||||
|
for res.Next() {
|
||||||
|
var oneHost models.Host
|
||||||
|
err = res.Scan(&oneHost.ID, &oneHost.Name, &oneHost.IP, &oneHost.Mac, &oneHost.Hw, &oneHost.Date, &oneHost.Known, &oneHost.Now)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// oneHost.Name = unquote_str(oneHost.Name)
|
||||||
|
// oneHost.Hw = unquote_str(oneHost.Hw)
|
||||||
|
dbHosts = append(dbHosts, oneHost)
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println("Select all:", dbHosts)
|
||||||
|
return dbHosts
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,8 @@ func Create(path string) {
|
||||||
log.Println("INFO: Table created!")
|
log.Println("INFO: Table created!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetNow(path string) {
|
||||||
|
sqlStatement := `UPDATE "now" set NOW = '0';`
|
||||||
|
dbExec(path, sqlStatement)
|
||||||
|
}
|
||||||
|
|
|
||||||
57
internal/scan/arpscan.go
Normal file
57
internal/scan/arpscan.go
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
package scan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scanIface(iface string) string {
|
||||||
|
cmd, err := exec.Command("arp-scan", "-glNx", "-I", iface).Output()
|
||||||
|
if err != nil {
|
||||||
|
return string("")
|
||||||
|
}
|
||||||
|
return string(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseOutput(text string) []models.Host {
|
||||||
|
var foundHosts = []models.Host{}
|
||||||
|
|
||||||
|
perString := strings.Split(text, "\n")
|
||||||
|
currentTime := time.Now()
|
||||||
|
|
||||||
|
for _, host := range perString {
|
||||||
|
if host != "" {
|
||||||
|
var oneHost models.Host
|
||||||
|
p := strings.Split(host, " ")
|
||||||
|
oneHost.IP = p[0]
|
||||||
|
oneHost.Mac = p[1]
|
||||||
|
oneHost.Hw = p[2]
|
||||||
|
oneHost.Date = currentTime.Format("2006-01-02 15:04:05")
|
||||||
|
oneHost.Now = 1
|
||||||
|
foundHosts = append(foundHosts, oneHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundHosts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan all interfaces
|
||||||
|
func arpScan(allIfaces string) []models.Host {
|
||||||
|
var text string
|
||||||
|
var foundHosts = []models.Host{}
|
||||||
|
|
||||||
|
perString := strings.Split(allIfaces, " ")
|
||||||
|
|
||||||
|
for _, iface := range perString {
|
||||||
|
log.Println("INFO: scanning interface", iface)
|
||||||
|
text = scanIface(iface)
|
||||||
|
log.Println("INFO: found IPs:", text)
|
||||||
|
foundHosts = append(foundHosts, parseOutput(text)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundHosts
|
||||||
|
}
|
||||||
33
internal/scan/compare.go
Normal file
33
internal/scan/compare.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package scan
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func host_in_db(host Host, dbHosts []Host) bool { // Check if host is already in DB
|
||||||
|
// for _, oneHost := range dbHosts {
|
||||||
|
// if host.Ip == oneHost.Ip && host.Mac == oneHost.Mac && host.Hw == oneHost.Hw {
|
||||||
|
// oneHost.Date = host.Date
|
||||||
|
// oneHost.Now = 1
|
||||||
|
// db_update(oneHost)
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
|
func hostsCompare(foundHosts []models.Host, dbHosts []models.Host) {
|
||||||
|
for _, oneHost := range foundHosts {
|
||||||
|
// if !(host_in_db(oneHost, dbHosts)) {
|
||||||
|
// oneHost.Now = 1 // Mark host online
|
||||||
|
// msg := fmt.Sprintf("UNKNOWN HOST IP: '%s', MAC: '%s', Hw: '%s'", oneHost.Ip, oneHost.Mac, oneHost.Hw)
|
||||||
|
// log.Println("WARN:", msg)
|
||||||
|
// shoutr_notify(msg) // Notify through Shoutrrr
|
||||||
|
// db_insert(oneHost)
|
||||||
|
// }
|
||||||
|
log.Println("FOUND:", oneHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
internal/scan/start.go
Normal file
21
internal/scan/start.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
package scan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Start(appConfig models.Conf) {
|
||||||
|
var foundHosts []models.Host
|
||||||
|
var dbHosts []models.Host
|
||||||
|
for { // Endless
|
||||||
|
foundHosts = arpScan(appConfig.Iface) // Scan interfaces
|
||||||
|
dbHosts = db.Select(appConfig.DbPath) // Select everything from DB
|
||||||
|
db.SetNow(appConfig.DbPath) // Mark hosts in DB as offline
|
||||||
|
hostsCompare(foundHosts, dbHosts) // Compare hosts online and in DB
|
||||||
|
// and add them to DB
|
||||||
|
time.Sleep(time.Duration(appConfig.Timeout) * time.Second) // Timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,8 +11,9 @@ import (
|
||||||
|
|
||||||
func index(w http.ResponseWriter, r *http.Request) {
|
func index(w http.ResponseWriter, r *http.Request) {
|
||||||
var guiData models.GuiData
|
var guiData models.GuiData
|
||||||
|
|
||||||
guiData.Config = AppConfig
|
guiData.Config = AppConfig
|
||||||
guiData.Hosts = []models.Host{}
|
guiData.Hosts = AllHosts
|
||||||
guiData.Icon = Icon
|
guiData.Icon = Icon
|
||||||
|
|
||||||
tmpl, _ := template.ParseFiles(TemplPath+"index.html", TemplPath+"header.html", TemplPath+"footer.html")
|
tmpl, _ := template.ParseFiles(TemplPath+"index.html", TemplPath+"header.html", TemplPath+"footer.html")
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Ip</th>
|
<th>IP</th>
|
||||||
<th>Mac</th>
|
<th>Mac</th>
|
||||||
<th>Hardware</th>
|
<th>Hardware</th>
|
||||||
<th>Known</th>
|
<th>Known</th>
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
{{ if eq .Now 1 }}
|
{{ if eq .Now 1 }}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ .Name }}</td>
|
<td>{{ .Name }}</td>
|
||||||
<td><a href="http://{{ .Ip }}" target="_blank">{{ .Ip }}</a></td>
|
<td><a href="http://{{ .IP }}" target="_blank">{{ .IP }}</a></td>
|
||||||
<td>{{ .Mac }}</td>
|
<td>{{ .Mac }}</td>
|
||||||
<td>{{ .Hw }}</td>
|
<td>{{ .Hw }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -44,12 +44,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
{{ range .Hosts }}
|
{{ range .Hosts }}
|
||||||
<form action="/update_host/" method="post">
|
<form action="/update_host/" method="post">
|
||||||
<input name="id" type="hidden" class="form-control" value="{{ .Id }}">
|
<input name="id" type="hidden" class="form-control" value="{{ .ID }}">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input name="name" type="text" class="form-control text-dark" value="{{ .Name }}">
|
<input name="name" type="text" class="form-control text-dark" value="{{ .Name }}">
|
||||||
</td>
|
</td>
|
||||||
<td>{{ .Ip }}</td>
|
<td>{{ .IP }}</td>
|
||||||
<td>{{ .Mac }}</td>
|
<td>{{ .Mac }}</td>
|
||||||
<td>{{ .Hw }}</td>
|
<td>{{ .Hw }}</td>
|
||||||
<td>{{ .Date }}</td>
|
<td>{{ .Date }}</td>
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
{{ range .Hosts }}
|
{{ range .Hosts }}
|
||||||
<form action="/update_host/" method="post">
|
<form action="/update_host/" method="post">
|
||||||
<input name="id" type="hidden" class="form-control" value="{{ .Id }}">
|
<input name="id" type="hidden" class="form-control" value="{{ .ID }}">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input name="name" type="text" class="form-control text-dark" value="{{ .Name }}">
|
<input name="name" type="text" class="form-control text-dark" value="{{ .Name }}">
|
||||||
</td>
|
</td>
|
||||||
<td><a href="http://{{ .Ip }}" target="_blank">{{ .Ip }}</a></td>
|
<td><a href="http://{{ .IP }}" target="_blank">{{ .IP }}</a></td>
|
||||||
<td>{{ .Mac }}</td>
|
<td>{{ .Mac }}</td>
|
||||||
<td>{{ .Hw }}</td>
|
<td>{{ .Hw }}</td>
|
||||||
<td>{{ .Date }}</td>
|
<td>{{ .Date }}</td>
|
||||||
|
|
|
||||||
|
|
@ -7,29 +7,30 @@ import (
|
||||||
|
|
||||||
"github.com/aceberg/WatchYourLAN/internal/check"
|
"github.com/aceberg/WatchYourLAN/internal/check"
|
||||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/scan"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// AppConfig - app config
|
// AppConfig - app config
|
||||||
AppConfig models.Conf
|
AppConfig models.Conf
|
||||||
|
|
||||||
// TemplPath - path to html templates
|
// AllHosts - all hosts from DB
|
||||||
TemplPath string
|
AllHosts []models.Host
|
||||||
)
|
)
|
||||||
|
|
||||||
// var AllHosts []Host
|
|
||||||
|
|
||||||
////go:embed templates/*
|
////go:embed templates/*
|
||||||
// var TemplHTML embed.FS
|
// var TemplHTML embed.FS
|
||||||
|
|
||||||
|
// TemplPath - path to html templates
|
||||||
|
const TemplPath = "../../internal/web/templates/"
|
||||||
|
|
||||||
// Gui - start web GUI
|
// Gui - start web GUI
|
||||||
func Gui(appConfig models.Conf) {
|
func Gui(appConfig models.Conf) {
|
||||||
|
|
||||||
TemplPath = "../../internal/web/templates/"
|
|
||||||
|
|
||||||
AppConfig = appConfig
|
AppConfig = appConfig
|
||||||
address := AppConfig.GuiIP + ":" + AppConfig.GuiPort
|
address := AppConfig.GuiIP + ":" + AppConfig.GuiPort
|
||||||
|
|
||||||
|
go scan.Start(AppConfig)
|
||||||
|
|
||||||
log.Println("=================================== ")
|
log.Println("=================================== ")
|
||||||
log.Printf("Web GUI at http://%s", address)
|
log.Printf("Web GUI at http://%s", address)
|
||||||
log.Println("=================================== ")
|
log.Println("=================================== ")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue