summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE29
-rw-r--r--README.md36
-rw-r--r--hisgle.go122
3 files changed, 187 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ba49ae1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) 2018 Martin Samuelsson. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e5c41b3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+There are two kinds of people in this world. Those who use just one single
+smartphone for all their information technology needs, and those who suddenly
+find themselves with more devices than they can keep track of without having
+information about them written down somewhere.
+
+If you are anything like me, sharing home with a couple of actively used
+laptops, several smartphones, document and label printers, physical servers,
+virtual servers and IoT things doing all kinds of weirdness, then just maybe
+hisgle might be helpful to you too.
+
+I've implemented hisgle (Host Inventory Script, Go Learning Experience) having
+no less than 131 devices with individual mac addresses. Remembering exactly
+where all of them were networkwise was becoming a challenge, so I put them all
+in a database with the following structure:
+
+ CREATE TABLE devices (name, mac, interface);
+ CREATE TABLE addresses (mac, vlan, ipv4);
+ CREATE TABLE aliases (alias, target);
+ CREATE TABLE networks (vlan, description TEXT, ipv4);
+
+Invoking hisgle generates ethers and hosts files which can be read directly by
+dnsmasq on e.g. OpenWRT routers.
+
+A typical command line would be:
+
+ hisgle --database=/somewhere/devices.db hosts 4 5 104
+
+Above line would generate a hosts file for vlan:s 4, 5 and 104. You might want
+to create a script which generates, copies and reloads hosts and ethers files
+for all your routers. That's what the script I run whenever updating my list
+of devices does.
+
+Wanting to try using the Go language for a something helped giving a name to
+this script. This is the first time I attempt writing something at all in Go.
+I'm sure there are heaps of things which could be improved, but I'm happy for
+now with a script which does what I need.
diff --git a/hisgle.go b/hisgle.go
new file mode 100644
index 0000000..2ef755a
--- /dev/null
+++ b/hisgle.go
@@ -0,0 +1,122 @@
+package main
+
+import ( "fmt"
+ "log"
+ "os"
+ "strconv" )
+
+// http://go-database-sql.org/importing.html
+// _ "github.com/mattn/go-sqlite3"
+// _ "code.google.com/p/gosqlite/sqlite3"
+import (
+ "database/sql"
+ _ "github.com/mxk/go-sqlite/sqlite3"
+ "github.com/pborman/getopt"
+)
+
+func ethers(db *sql.DB, vlan int) {
+ var (
+ mac string
+ ipv4 string
+ )
+
+//CREATE TABLE devices (name, mac, interface);
+//CREATE TABLE addresses (mac, vlan, ipv4);
+
+ rows, err := db.Query("SELECT mac, ipv4 FROM addresses WHERE vlan=?", vlan)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for rows.Next() {
+ err := rows.Scan(&mac, &ipv4)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(mac, " ", ipv4)
+ }
+}
+
+func hosts(db *sql.DB, vlan int) {
+ var (
+ ipv4 string
+ name string
+ alias string
+ )
+
+//CREATE TABLE devices (name, mac, interface);
+//CREATE TABLE addresses (mac, vlan, ipv4);
+
+ rows, err := db.Query("SELECT a.ipv4, d.name FROM addresses AS a JOIN devices AS d ON a.mac=d.mac WHERE vlan=?", vlan)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for rows.Next() {
+ err := rows.Scan(&ipv4, &name)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Print(ipv4, "\t", name)
+
+// CREATE TABLE aliases (alias, target);
+ rows, err := db.Query("SELECT alias FROM aliases WHERE target=?", name)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for rows.Next() {
+ err := rows.Scan(&alias)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Print(" ", alias)
+ }
+ fmt.Println()
+ }
+}
+
+func main() {
+ var (
+ description string
+ ipv4 string
+ )
+
+ optDatabase := getopt.StringLong("database", 'd', "", "Path to SQLite3 database file with device addresses")
+ optHelp := getopt.BoolLong("help", 0, "Help")
+ getopt.SetParameters("{ethers|hosts} list_of_networks")
+ getopt.Parse()
+
+ if *optHelp {
+ getopt.Usage()
+ os.Exit(0)
+ }
+ args := getopt.Args()
+
+ db, err := sql.Open("sqlite3", *optDatabase)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, arg := range args[1:] {
+ vlan, _ := strconv.Atoi(arg)
+ rows, err := db.Query("SELECT description, ipv4 FROM networks WHERE vlan=?", vlan)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for rows.Next() {
+ err := rows.Scan(&description, &ipv4)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Print("\n# ", description, ", ", ipv4, "\n")
+ fmt.Println("# vlan:", vlan)
+ switch args[0] {
+ case "ethers":
+ ethers(db, vlan)
+ case "hosts":
+ hosts(db, vlan)
+ default:
+ os.Exit(1)
+ }
+ }
+ }
+ defer db.Close()
+}