better device scan. less dependencies. ip regex

This commit is contained in:
Maxi Quoß
2021-09-30 00:15:41 +02:00
parent c513d68800
commit 5edf630926
6 changed files with 44 additions and 22 deletions

View File

@@ -19,10 +19,7 @@ COPY --from=builder /install /usr/local
COPY app /app
WORKDIR /app
RUN apt-get update && \
apt-get -y install iputils-ping && \
rm -rf /var/lib/apt/lists/* && \
groupadd user && useradd -M user -g user && \
chmod -R 755 /app && chown -R user:user /app
USER user
apt-get -y install iputils-ping nmap && \
rm -rf /var/lib/apt/lists/*
CMD ["./run.sh"]

View File

@@ -142,4 +142,4 @@ STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
VERSION = "v1.2.2"
VERSION = "v1.2.3"

View File

@@ -4,6 +4,7 @@ async function scan() {
const table = document.getElementById("scan-table").getElementsByTagName('tbody')[0];
table.innerHTML = "";
const tableContainer = document.getElementById("scan-table-container");
tableContainer.classList.add("is-hidden");
document.getElementById("scan-button").classList.add("is-loading");
const response = await fetch("/scan");

View File

@@ -108,7 +108,7 @@
<label class="mr-2" for="ip-range"><strong>Network address for discovering devices:</strong></label>
</div>
<div class="column is-half-mobile is-two-thirds-tablet is-three-quarters-desktop is-four-fifths-widescreen is-narrow">
<input id="ip-range" class="input" type="text" placeholder="192.168.1.0/24" name="ip_range" value="{{ settings.scan_address }}">
<input id="ip-range" class="input" type="text" placeholder="192.168.1.0/24" name="ip_range" value="{% if settings.scan_address %}{{ settings.scan_address }}{% endif %}" pattern="^([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])){2}(?:\.(?:0))(?:/[0-2]\d|/3[0-2])$">
</div>
</div>
<button class="button is-primary" type="submit" value="Submit">Save</button>
@@ -118,7 +118,16 @@
<section class="section py-3">
<div class="box no-flex">
<h2 class="title is-size-3 mb-4">Add devices</h2>
{% if settings.scan_address %}
<button id="scan-button" class="button is-primary">Scan network</button>
{% else %}
<article class="message is-danger">
<div class="message-body">
Please enter the network address above and save to use this feature. Network address should look like "192.168.1.0/24".
</div>
</article>
<button id="scan-button" class="button is-primary" disabled>Scan network</button>
{% endif %}
<div id="scan-table-container" class="table-container py-3 is-hidden">
<table id="scan-table" class="table is-fullwidth">
<thead>

View File

@@ -1,9 +1,8 @@
import json
import os
import platform
import subprocess
import arpreq
import nmap
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.http import HttpResponseRedirect
@@ -66,21 +65,39 @@ def save_settings(request):
def scan(request):
conf = Settings.objects.filter(id=1).get()
nm = nmap.PortScanner()
nm.scan(hosts=conf.scan_address, arguments='-sP')
up_hosts = nm.all_hosts()
data = {
"devices": []
}
for address in up_hosts:
mac = arpreq.arpreq(address)
if mac:
conf = Settings.objects.filter(id=1).get()
if not conf.scan_address:
return JsonResponse(data=data)
p = subprocess.Popen(["nmap", "-sP", conf.scan_address], stdout=subprocess.PIPE)
out = p.communicate()[0].decode("utf-8")
ip_line = "Nmap scan report for"
mac_line = "MAC Address:"
for line in out.splitlines():
if line.startswith(ip_line):
line_splitted = line.split()
if len(line_splitted) == 6:
name = line_splitted[4]
ip = line_splitted[5]
ip = ip.replace("(", "")
ip = ip.replace(")", "")
else:
name = None
ip = line_splitted[4]
elif line.startswith(mac_line):
line_splitted = line.split()
mac = line_splitted[2]
data["devices"].append({
"name": nm[address].hostname(),
"ip": address,
"mac": arpreq.arpreq(address)
"name": name,
"ip": ip,
"mac": mac
})
return JsonResponse(data=data)

View File

@@ -7,5 +7,3 @@ psycopg2-binary
whitenoise
gunicorn
uvicorn[standard]
python-nmap
arpreq