diff --git a/Makefile b/Makefile index 66ecf02..bf1173a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ DUSER=aceberg DNAME=watchyourlan IFACE=virbr-bw -DBPATH=data/hosts.db +DBPATH=/data/hosts.db SHOUTRRR_URL=gotify://192.168.2.1:8083/AwQqpAae.rrl5Ob/?title=Unknown host detected&DisableTLS=yes THEME=darkly @@ -13,7 +13,7 @@ mod: go mod tidy run: - cd src && \ + cd cmd/WatchYourLAN/ && \ sudo \ env IFACE=$(IFACE) DBPATH=$(DBPATH) THEME=$(THEME) \ go run . diff --git a/cmd/WatchYourLAN/main.go b/cmd/WatchYourLAN/main.go index bec1143..e608f0a 100644 --- a/cmd/WatchYourLAN/main.go +++ b/cmd/WatchYourLAN/main.go @@ -4,11 +4,12 @@ import ( "fmt" // "time" "github.com/aceberg/WatchYourLAN/pkg/conf" - . "github.com/aceberg/WatchYourLAN/pkg/models" + "github.com/aceberg/WatchYourLAN/pkg/db" + "github.com/aceberg/WatchYourLAN/pkg/web" + // . "github.com/aceberg/WatchYourLAN/pkg/models" ) -var AppConfig Conf - +// var AppConfig Conf // var AllHosts []Host // func scan_and_compare() { @@ -26,14 +27,13 @@ var AppConfig Conf // } func main() { - // AllHosts = []Host{} - AppConfig = conf.GetConfig() // Get config from Defaults, Config file, Env + appConfig := conf.GetConfig() // Get config from Defaults, Config file, Env - fmt.Println("CONF =", AppConfig) + fmt.Println("CONF =", appConfig) - // db_create() // Check if DB exists. Create if not + db.CreateDB(appConfig.DbPath) // Check if DB exists. Create if not // go scan_and_compare() - // webgui() // Start web GUI + web.Webgui(appConfig) // Start web GUI } diff --git a/go.mod b/go.mod index 0b20b06..fac804f 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,10 @@ module github.com/aceberg/WatchYourLAN go 1.19 -require github.com/spf13/viper v1.14.0 +require ( + github.com/mattn/go-sqlite3 v1.14.16 + github.com/spf13/viper v1.14.0 +) require ( github.com/fsnotify/fsnotify v1.6.0 // indirect diff --git a/go.sum b/go.sum index 89fe32d..950442e 100644 --- a/go.sum +++ b/go.sum @@ -133,6 +133,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= diff --git a/pkg/conf/getconfig.go b/pkg/conf/getconfig.go index 09073b1..f637966 100644 --- a/pkg/conf/getconfig.go +++ b/pkg/conf/getconfig.go @@ -33,9 +33,9 @@ func GetConfig() (config Conf) { return config } -func WriteConfig() { +func WriteConfig(theme string) { viper.SetConfigFile(configPath) viper.SetConfigType("env") - viper.Set("THEME", AppConfig.Theme) + viper.Set("THEME", theme) viper.WriteConfig() } diff --git a/pkg/db/db-connect.go b/pkg/db/db-connect.go index 244930e..08fa4b7 100644 --- a/pkg/db/db-connect.go +++ b/pkg/db/db-connect.go @@ -2,44 +2,44 @@ package db import ( //"fmt" - "log" "database/sql" _ "github.com/mattn/go-sqlite3" + "log" ) -func db_exec(sqlStatement string) { - db, _ := sql.Open("sqlite3", AppConfig.DbPath) +func dbExec(path, sqlStatement string) { + db, _ := sql.Open("sqlite3", path) defer db.Close() - + _, err := db.Exec(sqlStatement) if err != nil { log.Fatal("ERROR: db_exec: ", err) } } -func db_select() (dbHosts []Host) { - db, _ := sql.Open("sqlite3", AppConfig.DbPath) - defer db.Close() +// func db_select() (dbHosts []Host) { +// db, _ := sql.Open("sqlite3", AppConfig.DbPath) +// defer db.Close() - sqlStatement := `SELECT * FROM "now" ORDER BY DATE DESC` +// sqlStatement := `SELECT * FROM "now" ORDER BY DATE DESC` - res, err := db.Query(sqlStatement) - if err != nil { - log.Fatal("ERROR: db_select: ", err) - } +// res, err := db.Query(sqlStatement) +// if err != nil { +// log.Fatal("ERROR: db_select: ", err) +// } - dbHosts = []Host{} - for res.Next() { - var oneHost 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) - } +// dbHosts = []Host{} +// for res.Next() { +// var oneHost 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 -} \ No newline at end of file +// //fmt.Println("Select all:", dbHosts) +// return dbHosts +// } diff --git a/pkg/db/db-edit.go b/pkg/db/db-edit.go index aea48a2..80cbc86 100644 --- a/pkg/db/db-edit.go +++ b/pkg/db/db-edit.go @@ -1,15 +1,15 @@ package db import ( - "os" "log" - "fmt" + "os" + // "fmt" ) -func db_create() { - if _, err := os.Stat(AppConfig.DbPath); err == nil { - log.Println("INFO: DB exists") - } else { +func CreateDB(path string) { + if _, err := os.Stat(path); err == nil { + log.Println("INFO: DB exists") + } else { sqlStatement := `CREATE TABLE "now" ( "ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, "NAME" TEXT NOT NULL, @@ -20,34 +20,34 @@ func db_create() { "KNOWN" INTEGER DEFAULT 0, "NOW" INTEGER DEFAULT 0 );` - db_exec(sqlStatement) + dbExec(path, sqlStatement) log.Println("INFO: Table created!") - } + } } -func db_insert(oneHost Host) { - oneHost.Name = quote_str(oneHost.Name) - oneHost.Hw = quote_str(oneHost.Hw) - sqlStatement := `INSERT INTO "now" (NAME, IP, MAC, HW, DATE, KNOWN, NOW) - VALUES ('%s','%s','%s','%s','%s','%d','%d');` - sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Ip, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now) - //fmt.Println("Insert statement:", sqlStatement) - db_exec(sqlStatement) -} +// func db_insert(oneHost Host) { +// oneHost.Name = quote_str(oneHost.Name) +// oneHost.Hw = quote_str(oneHost.Hw) +// sqlStatement := `INSERT INTO "now" (NAME, IP, MAC, HW, DATE, KNOWN, NOW) +// VALUES ('%s','%s','%s','%s','%s','%d','%d');` +// sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Ip, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now) +// //fmt.Println("Insert statement:", sqlStatement) +// db_exec(sqlStatement) +// } -func db_update(oneHost Host) { - oneHost.Name = quote_str(oneHost.Name) - oneHost.Hw = quote_str(oneHost.Hw) - sqlStatement := `UPDATE "now" set - NAME = '%s', IP = '%s', MAC = '%s', HW = '%s', DATE = '%s', - KNOWN = '%d', NOW = '%d' - WHERE ID = '%d';` - sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Ip, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.Id) - //fmt.Println("Update statement:", sqlStatement) - db_exec(sqlStatement) -} +// func db_update(oneHost Host) { +// oneHost.Name = quote_str(oneHost.Name) +// oneHost.Hw = quote_str(oneHost.Hw) +// sqlStatement := `UPDATE "now" set +// NAME = '%s', IP = '%s', MAC = '%s', HW = '%s', DATE = '%s', +// KNOWN = '%d', NOW = '%d' +// WHERE ID = '%d';` +// sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.Ip, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.Id) +// //fmt.Println("Update statement:", sqlStatement) +// db_exec(sqlStatement) +// } -func db_setnow() { - sqlStatement := `UPDATE "now" set NOW = '0';` - db_exec(sqlStatement) -} \ No newline at end of file +// func db_setnow() { +// sqlStatement := `UPDATE "now" set NOW = '0';` +// db_exec(sqlStatement) +// } diff --git a/pkg/models/models.go b/pkg/models/models.go index fe990fc..14894cf 100644 --- a/pkg/models/models.go +++ b/pkg/models/models.go @@ -20,3 +20,8 @@ type Conf struct { ShoutUrl string Theme string } + +type GuiData struct { + Config Conf + Hosts []Host +} diff --git a/pkg/web/index.go b/pkg/web/index.go new file mode 100644 index 0000000..1e4b8b2 --- /dev/null +++ b/pkg/web/index.go @@ -0,0 +1,45 @@ +package web + +import ( + // "fmt" + "html/template" + "net/http" + // "strconv" + . "github.com/aceberg/WatchYourLAN/pkg/models" +) + +func index(w http.ResponseWriter, r *http.Request) { + var guiData GuiData + guiData.Config = AppConfig + guiData.Hosts = []Host{} + + tmpl, _ := template.ParseFS(TemplHTML, "templates/index.html", "templates/header.html", "templates/footer.html") + tmpl.ExecuteTemplate(w, "index", guiData) +} + +// func update_host(w http.ResponseWriter, r *http.Request) { +// idStr := r.FormValue("id") +// name := r.FormValue("name") +// knownStr := r.FormValue("known") + +// if idStr == "" { +// fmt.Fprintf(w, "No data!") +// } else { +// var known uint16 +// id, _ := strconv.Atoi(idStr) +// known = 0 +// if knownStr == "on" { +// known = 1 +// } + +// for i, oneHost := range AllHosts { +// if oneHost.Id == uint16(id) { +// AllHosts[i].Name = name +// AllHosts[i].Known = known +// db_update(AllHosts[i]) +// } +// } +// } + +// http.Redirect(w, r, r.Header.Get("Referer"), 302) +// } diff --git a/pkg/web/templates/footer.html b/pkg/web/templates/footer.html new file mode 100644 index 0000000..5dd8ca7 --- /dev/null +++ b/pkg/web/templates/footer.html @@ -0,0 +1,4 @@ +{{ define "footer"}} + + +{{ end }} \ No newline at end of file diff --git a/pkg/web/templates/header.html b/pkg/web/templates/header.html new file mode 100644 index 0000000..3721ad5 --- /dev/null +++ b/pkg/web/templates/header.html @@ -0,0 +1,72 @@ +{{ define "header"}} + + + Watch Your LAN + + + + + + + + + + + + +{{ end }} \ No newline at end of file diff --git a/pkg/web/templates/index.html b/pkg/web/templates/index.html new file mode 100644 index 0000000..43d5abc --- /dev/null +++ b/pkg/web/templates/index.html @@ -0,0 +1,74 @@ +{{ define "index"}} + +{{ template "header" }} + + + + + + +
+

Online

+

Scanning interfaces: {{ .Config.Iface }}

+ + + + + + + + + {{ range .Hosts }} + {{ if eq .Now 1 }} + + + + + + + + {{ end }} + {{ end }} +
NameIpMacHardwareKnown
{{ .Name }}{{ .Ip }}{{ .Mac }}{{ .Hw }} + {{ if eq .Known 1 }} + + {{ else }} + + {{ end }} +
+

Log

+ + + + + + + + + + {{ range .Hosts }} + + + + + + + + + + + + {{ end }} +
NameIpMacHardwareLast seenKnown
+ + {{ .Ip }}{{ .Mac }}{{ .Hw }}{{ .Date }} + {{ if eq .Known 1 }} + + {{ else }} + + {{ end }} +
+
+ +{{ template "footer" }} +{{ end }} \ No newline at end of file diff --git a/pkg/web/templates/offline.html b/pkg/web/templates/offline.html new file mode 100644 index 0000000..dd7f029 --- /dev/null +++ b/pkg/web/templates/offline.html @@ -0,0 +1,75 @@ +{{ define "offline"}} + +{{ template "header" }} + + + + + + +
+ + + + + + + + + + + + {{ range .Hosts }} + + + + + + + + + + + + {{ end }} +
Name
+ + +
Ip
+ + +
MacHardwareLast seen
+ + +
Known
+ + +
+ + {{ .Ip }}{{ .Mac }}{{ .Hw }}{{ .Date }} + {{ if eq .Known 1 }} + + {{ else }} + + {{ end }} +
+
+ +{{ template "footer" }} +{{ end }} \ No newline at end of file diff --git a/pkg/web/webgui.go b/pkg/web/webgui.go new file mode 100644 index 0000000..b4ed391 --- /dev/null +++ b/pkg/web/webgui.go @@ -0,0 +1,36 @@ +package web + +import ( + "embed" + "fmt" + . "github.com/aceberg/WatchYourLAN/pkg/models" + "log" + "net/http" +) + +var AppConfig Conf + +// var AllHosts []Host + +//go:embed templates/* +var TemplHTML embed.FS + +func Webgui(appConfig Conf) { + + AppConfig = appConfig + address := AppConfig.GuiIP + ":" + AppConfig.GuiPort + + log.Println("=================================== ") + log.Println(fmt.Sprintf("Web GUI at http://%s", address)) + log.Println("=================================== ") + + http.HandleFunc("/", index) + http.HandleFunc("/home/", index) + // http.HandleFunc("/offline/", offline) + // http.HandleFunc("/online/", online) + // http.HandleFunc("/search_hosts/", search_hosts) + // http.HandleFunc("/sort_hosts/", sort_hosts) + // http.HandleFunc("/theme/", theme) + // http.HandleFunc("/update_host/", update_host) + http.ListenAndServe(address, nil) +}