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
|
||||
type GuiData struct {
|
||||
Config Conf
|
||||
Hosts []Host
|
||||
Host Host
|
||||
Themes []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 (
|
||||
// "log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/portscan"
|
||||
)
|
||||
|
||||
func apiAll(c *gin.Context) {
|
||||
|
|
@ -25,21 +25,28 @@ func apiHistory(c *gin.Context) {
|
|||
func apiHost(c *gin.Context) {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
idStr := c.Param("id")
|
||||
name := c.Param("name")
|
||||
toggleKnown := c.Param("known")
|
||||
|
||||
id, _ := strconv.Atoi(idStr)
|
||||
|
||||
host := getHostByID(id, allHosts) // functions.go
|
||||
host := getHostByID(idStr, allHosts) // functions.go
|
||||
if host.Date != "" {
|
||||
host.Name = name
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"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 {
|
||||
if host.ID == id {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
|
@ -14,9 +13,8 @@ func hostHandler(c *gin.Context) {
|
|||
guiData.Config = appConfig
|
||||
|
||||
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, "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" }}
|
||||
|
||||
<script src="/fs/public/js/scan.js"></script>
|
||||
<body>
|
||||
<div class="container-lg">
|
||||
<div class="row">
|
||||
|
|
@ -8,7 +9,47 @@
|
|||
<div class="card-header">Host</div>
|
||||
<div class="card-body table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -18,6 +59,20 @@
|
|||
<div class="card border-primary">
|
||||
<div class="card-header">Port scan</div>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -43,9 +43,10 @@ func Gui(dirPath, nodePath string) {
|
|||
router.StaticFS("/fs/", http.FS(pubFS)) // public
|
||||
|
||||
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/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("/history/", historyHandler) // index.go
|
||||
|
|
|
|||
Loading…
Reference in a new issue