Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web interface addition #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

- uses: golangci/golangci-lint-action@v2
with:
version: v1.38
version: v1.45.2

go-mod-tidy:
runs-on: ubuntu-20.04
Expand All @@ -24,6 +24,8 @@ jobs:
- uses: actions/checkout@v2

- uses: actions/setup-go@v2
with:
go-version: "1.17"

- run: |
go mod download
Expand Down
13 changes: 12 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@
linters:
enable:
- bodyclose
- dupl
- exportloopref
- gochecknoinits
- gocritic
- gofmt
- gofumpt
- golint
- misspell
- lll
- prealloc
- revive
- unconvert
- whitespace
disable:
- errcheck

issues:
exclude-use-default: false

linters-settings:
govet:
enable-all: true
disable:
- fieldalignment
- reflectvaluecompare
- shadow
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

BASE_IMAGE = golang:1.15-alpine3.12
LINT_IMAGE = golangci/golangci-lint:v1.38.0
BASE_IMAGE = golang:1.17-alpine3.14
LINT_IMAGE = golangci/golangci-lint:v1.45.2

.PHONY: $(shell ls)

all: build

help:
@echo "usage: make [action]"
@echo ""
Expand All @@ -26,19 +28,18 @@ endef

mod-tidy:
docker run --rm -it -v $(PWD):/s -w /s amd64/$(BASE_IMAGE) \
sh -c "go get && GOPROXY=direct go mod tidy"
sh -c "apk add git && go get && GOPROXY=direct go mod tidy"

define DOCKERFILE_FORMAT
FROM $(BASE_IMAGE)
RUN apk add --no-cache git
RUN GO111MODULE=on go get mvdan.cc/gofumpt
RUN go install mvdan.cc/[email protected]
endef
export DOCKERFILE_FORMAT

format:
echo "$$DOCKERFILE_FORMAT" | docker build -q . -f - -t temp
docker run --rm -it -v $(PWD):/s -w /s temp \
sh -c "find . -type f -name '*.go' | xargs gofumpt -l -w"
sh -c "gofumpt -l -w ."

define DOCKERFILE_TEST
FROM amd64/$(BASE_IMAGE)
Expand Down Expand Up @@ -177,3 +178,11 @@ dockerhub:

docker buildx rm builder
rm -rf $$HOME/.docker/manifests/*

build:
$(eval export CGO_ENABLED=0)
go build -o landiscover .
build-freebsd:
$(eval export GOOS=freebsd)
$(eval export GOARCH=386)
go build -o landiscover-freebsd .
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Fork additions

In this fork i've added simple web interface (it also updating entries on the fly).



# landiscover

Expand Down Expand Up @@ -40,6 +45,7 @@ Machine and service discovery tool.
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
--passive do not send any packet
--httpd Run in httpd mode (web interface)

Args:
[<interface>] Interface to listen to
Expand Down
13 changes: 9 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
module github.com/gswly/landiscover

go 1.14
go 1.17

require (
github.com/google/gopacket v1.1.19-0.20200930201211-6bf70f9bd488
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)

require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/google/gopacket v1.1.18
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1
gopkg.in/alecthomas/kingpin.v2 v2.2.6
golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
19 changes: 18 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.19-0.20200930201211-6bf70f9bd488 h1:n/lGruDFTKDqwZjBL+DkRMxHyWpyfDbe7UbR3QvYThI=
github.com/google/gopacket v1.1.19-0.20200930201211-6bf70f9bd488/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag=
Expand All @@ -16,15 +20,28 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
175 changes: 175 additions & 0 deletions httpd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package main

import (
"fmt"
"net/http"
"sort"
"net"
"bytes"
"encoding/json"
)

func httpdaemonize(nodes map[nodeKey]*node) {
var htmlPage = `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="landiscover">
<meta name="generator" content="landiscover">
<title>Landiscover</title>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
</head>
<body>
<table class="table table-dark" id="rowslist">
<thead>
<tr>
<th scope="col">Last seen</th>
<th scope="col">Hardware Address</th>
<th scope="col">IP</th>
<th scope="col">Vendor</th>
<th scope="col">DNS</th>
<th scope="col">NetBIOS</th>
<th scope="col">multicast DNS</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var i = setInterval(function(){
jQuery.ajax({
type:"GET",
url:"/refresh",
dataType:"json",
success:function(data) {
// clear table
$('#rowslist tbody').empty();
data.forEach(function(node){
// add items
$('#rowslist tbody').append("<tr><td>"+node.last_seen+"</td><td>"+node.mac_addr+"</td><td>"+node.ip+"</td><td>"+node.vendor+"</td><td>"+node.dns+"</td><td>"+node.nbns+"</td><td>"+node.mdns+"</td></tr>");
});
}
});
},2000)
</script>
</body>
</html>
`

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w,"%s",htmlPage)
})

http.HandleFunc("/refresh", func(w http.ResponseWriter, r *http.Request){
tableSortBy := "mac"
tableSortAsc := true

var tableRows []uiTableRow
tableRows = func() []uiTableRow {
var ret []uiTableRow
for _, n := range nodes {
row := uiTableRow{
id: fmt.Sprintf("%s_%s", n.mac.String(), n.ip.String()),
cells: []string{
n.lastSeen.Format("Jan 2 15:04:05"),
n.mac.String(),
n.ip.String(),
macVendor(n.mac),
func() string {
if n.dns == "" {
return "-"
}
return n.dns
}(),
func() string {
if n.nbns == "" {
return "-"
}
return n.nbns
}(),
func() string {
if n.mdns == "" {
return "-"
}
return n.mdns
}(),
},
}
ret = append(ret, row)
}
return ret
}()

sort.Slice(tableRows, func(i, j int) bool {
n := 0
switch tableSortBy {
case "last seen":
n = 0
case "mac":
n = 1
case "ip":
n = 2
case "vendor":
n = 3
case "dns":
n = 4
case "nbns":
n = 5
case "mdns":
n = 6
}

if tableSortBy == "ip" {
if tableRows[i].cells[n] != tableRows[j].cells[n] {
ipa := net.ParseIP(tableRows[i].cells[n])
ipb := net.ParseIP(tableRows[j].cells[n])

if tableSortAsc {
return bytes.Compare(ipa, ipb) < 0
}
return bytes.Compare(ipa, ipb) >= 0
}
} else {
if tableRows[i].cells[n] != tableRows[j].cells[n] {
if tableSortAsc {
return tableRows[i].cells[n] < tableRows[j].cells[n]
}
return tableRows[i].cells[n] > tableRows[j].cells[n]
}
}

return tableRows[i].cells[2] < tableRows[j].cells[2]
})

type JsonResp struct {
Id string `json:"id"`
Last string `json:"last_seen"`
Mac string `json:"mac_addr"`
Ip string `json:"ip"`
Vendor string `json:"vendor"`
Dns string `json:"dns"`
Nbns string `json:"nbns"`
Mdns string `json:"mdns"`
}
Rows := []JsonResp{}
for _, node := range tableRows {
Rows = append(Rows,JsonResp{Id: node.id, Last: node.cells[0], Mac: node.cells[1], Ip: node.cells[2], Vendor: node.cells[3], Dns: node.cells[4], Nbns: node.cells[5], Mdns: node.cells[6]})
}
resp, err := json.Marshal(Rows)
if err != nil {
fmt.Printf("Unable to encode json response: %s\n",err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(resp))
})

http.ListenAndServe(":8090", nil)
}
Binary file added landiscover
Binary file not shown.
Loading