Port scan
This commit is contained in:
parent
409274759f
commit
54513cddd9
8 changed files with 151 additions and 14 deletions
|
|
@ -33,7 +33,7 @@ type Host struct {
|
||||||
// GuiData - all data sent to html page
|
// GuiData - all data sent to html page
|
||||||
type GuiData struct {
|
type GuiData struct {
|
||||||
Config Conf
|
Config Conf
|
||||||
Hosts []Host
|
Host Host
|
||||||
Themes []string
|
Themes []string
|
||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
internal/portscan/scan.go
Normal file
26
internal/portscan/scan.go
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
package portscan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsOpen - check one tcp port
|
||||||
|
func IsOpen(host, port string) bool {
|
||||||
|
|
||||||
|
timeout := 3 * time.Second
|
||||||
|
target := fmt.Sprintf("%s:%s", host, port)
|
||||||
|
|
||||||
|
conn, err := net.DialTimeout("tcp", target, timeout)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn != nil {
|
||||||
|
conn.Close()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,11 @@ package web
|
||||||
import (
|
import (
|
||||||
// "log"
|
// "log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||||
|
"github.com/aceberg/WatchYourLAN/internal/portscan"
|
||||||
)
|
)
|
||||||
|
|
||||||
func apiAll(c *gin.Context) {
|
func apiAll(c *gin.Context) {
|
||||||
|
|
@ -25,21 +25,28 @@ func apiHistory(c *gin.Context) {
|
||||||
func apiHost(c *gin.Context) {
|
func apiHost(c *gin.Context) {
|
||||||
|
|
||||||
idStr := c.Param("id")
|
idStr := c.Param("id")
|
||||||
id, _ := strconv.Atoi(idStr)
|
|
||||||
host := getHostByID(id, allHosts) // functions.go
|
host := getHostByID(idStr, allHosts) // functions.go
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusOK, host)
|
c.IndentedJSON(http.StatusOK, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func apiPort(c *gin.Context) {
|
||||||
|
|
||||||
|
addr := c.Param("addr")
|
||||||
|
port := c.Param("port")
|
||||||
|
state := portscan.IsOpen(addr, port)
|
||||||
|
|
||||||
|
c.IndentedJSON(http.StatusOK, state)
|
||||||
|
}
|
||||||
|
|
||||||
func apiEdit(c *gin.Context) {
|
func apiEdit(c *gin.Context) {
|
||||||
|
|
||||||
idStr := c.Param("id")
|
idStr := c.Param("id")
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
toggleKnown := c.Param("known")
|
toggleKnown := c.Param("known")
|
||||||
|
|
||||||
id, _ := strconv.Atoi(idStr)
|
host := getHostByID(idStr, allHosts) // functions.go
|
||||||
|
|
||||||
host := getHostByID(id, allHosts) // functions.go
|
|
||||||
if host.Date != "" {
|
if host.Date != "" {
|
||||||
host.Name = name
|
host.Name = name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getHostByID(id int, hosts []models.Host) (oneHost models.Host) {
|
func getHostByID(idStr string, hosts []models.Host) (oneHost models.Host) {
|
||||||
|
|
||||||
|
id, _ := strconv.Atoi(idStr)
|
||||||
|
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
if host.ID == id {
|
if host.ID == id {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
@ -14,9 +13,8 @@ func hostHandler(c *gin.Context) {
|
||||||
guiData.Config = appConfig
|
guiData.Config = appConfig
|
||||||
|
|
||||||
idStr := c.Param("id")
|
idStr := c.Param("id")
|
||||||
log.Println("ID =", idStr)
|
|
||||||
|
|
||||||
guiData.Version = idStr
|
guiData.Host = getHostByID(idStr, allHosts)
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "header.html", guiData)
|
c.HTML(http.StatusOK, "header.html", guiData)
|
||||||
c.HTML(http.StatusOK, "host.html", guiData)
|
c.HTML(http.StatusOK, "host.html", guiData)
|
||||||
|
|
|
||||||
46
internal/web/public/js/scan.js
Normal file
46
internal/web/public/js/scan.js
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
let stop = false;
|
||||||
|
|
||||||
|
function stopScan() {
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function scanAddr() {
|
||||||
|
const addr = document.getElementById("hostIP").value;
|
||||||
|
let begin = document.getElementById("begin").value;
|
||||||
|
let end = document.getElementById("end").value;
|
||||||
|
|
||||||
|
if (begin == "") {
|
||||||
|
begin = 1
|
||||||
|
}
|
||||||
|
if (end == "") {
|
||||||
|
end = 65535
|
||||||
|
}
|
||||||
|
let portOpen = false;
|
||||||
|
stop = false;
|
||||||
|
|
||||||
|
document.getElementById('stopBtn').style.visibility = "visible";
|
||||||
|
|
||||||
|
for (let i = begin ; i <= end; i++) {
|
||||||
|
|
||||||
|
if (stop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = '/api/port/'+addr+'/'+i;
|
||||||
|
portOpen = await (await fetch(url)).json();
|
||||||
|
|
||||||
|
document.getElementById("curPort").innerHTML = "Scanning port "+i;
|
||||||
|
|
||||||
|
if (portOpen) {
|
||||||
|
let html = genHTML(addr, i);
|
||||||
|
document.getElementById('foundPorts').insertAdjacentHTML('beforeend', html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('stopBtn').style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
|
||||||
|
function genHTML(addr, port) {
|
||||||
|
html = `<a href="http://${addr}:${port}">${port}</a> `;
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{{ define "host.html" }}
|
{{ define "host.html" }}
|
||||||
|
|
||||||
|
<script src="/fs/public/js/scan.js"></script>
|
||||||
<body>
|
<body>
|
||||||
<div class="container-lg">
|
<div class="container-lg">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -8,7 +9,47 @@
|
||||||
<div class="card-header">Host</div>
|
<div class="card-header">Host</div>
|
||||||
<div class="card-body table-responsive">
|
<div class="card-body table-responsive">
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>{{ .Host.ID }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>{{ .Host.Name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Iface</td>
|
||||||
|
<td>{{ .Host.Iface }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>IP</td>
|
||||||
|
<td><a href="http://{{ .Host.IP }}">{{ .Host.IP }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>MAC</td>
|
||||||
|
<td>{{ .Host.Mac }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Hardware</td>
|
||||||
|
<td>{{ .Host.Hw }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>{{ .Host.Date }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Known</td>
|
||||||
|
<td>{{ .Host.Known }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Online</td>
|
||||||
|
<td>{{ if eq .Host.Now 0 }}
|
||||||
|
<i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>
|
||||||
|
{{ else }}
|
||||||
|
<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,6 +59,20 @@
|
||||||
<div class="card border-primary">
|
<div class="card border-primary">
|
||||||
<div class="card-header">Port scan</div>
|
<div class="card-header">Port scan</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<form class="input-group">
|
||||||
|
<input id="begin" type="text" class="form-control" placeholder="1">
|
||||||
|
<input id="end" type="text" class="form-control" placeholder="65535">
|
||||||
|
<!-- To get from JS -->
|
||||||
|
<input type="hidden" id="hostIP" value="{{ .Host.IP }}">
|
||||||
|
<button onclick="scanAddr()" type="button" class="btn btn-primary">Scan</button>
|
||||||
|
</form>
|
||||||
|
<div style="display: flex; justify-content: space-between; visibility: hidden;" id="stopBtn" class="mt-2">
|
||||||
|
<button onclick="stopScan()" type="button" class="btn btn-warning">Stop</button>
|
||||||
|
<div id="curPort"></div>
|
||||||
|
</div>
|
||||||
|
<div id="foundPorts" class="mt-2">
|
||||||
|
<!-- JS here -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,10 @@ func Gui(dirPath, nodePath string) {
|
||||||
router.StaticFS("/fs/", http.FS(pubFS)) // public
|
router.StaticFS("/fs/", http.FS(pubFS)) // public
|
||||||
|
|
||||||
router.GET("/api/all", apiAll) // api.go
|
router.GET("/api/all", apiAll) // api.go
|
||||||
router.GET("/api/history", apiHistory) // api.go
|
|
||||||
router.GET("/api/host", apiHost) // api.go
|
|
||||||
router.GET("/api/edit/:id/:name/*known", apiEdit) // api.go
|
router.GET("/api/edit/:id/:name/*known", apiEdit) // api.go
|
||||||
|
router.GET("/api/history", apiHistory) // api.go
|
||||||
|
router.GET("/api/host", apiHost) // api.go
|
||||||
|
router.GET("/api/port/:addr/:port", apiPort) // api.go
|
||||||
|
|
||||||
router.GET("/", indexHandler) // index.go
|
router.GET("/", indexHandler) // index.go
|
||||||
router.GET("/history/", historyHandler) // index.go
|
router.GET("/history/", historyHandler) // index.go
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue