lanscape 2.0.2a4__py3-none-any.whl → 2.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lanscape/core/device_alive.py +80 -13
- lanscape/core/net_tools.py +52 -2
- lanscape/core/subnet_scan.py +13 -4
- lanscape/ui/shutdown_handler.py +1 -1
- lanscape/ui/static/css/style.css +15 -15
- lanscape/ui/templates/base.html +6 -8
- lanscape/ui/templates/core/head.html +1 -1
- lanscape/ui/templates/info.html +20 -5
- lanscape/ui/templates/main.html +5 -6
- lanscape/ui/templates/scan/config.html +15 -14
- lanscape/ui/templates/scan/device-detail.html +3 -3
- lanscape/ui/templates/scan/ip-table-row.html +3 -3
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/METADATA +3 -1
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/RECORD +18 -18
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/WHEEL +0 -0
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/entry_points.txt +0 -0
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/licenses/LICENSE +0 -0
- {lanscape-2.0.2a4.dist-info → lanscape-2.1.2.dist-info}/top_level.txt +0 -0
lanscape/core/device_alive.py
CHANGED
|
@@ -12,8 +12,9 @@ import psutil
|
|
|
12
12
|
from scapy.sendrecv import srp
|
|
13
13
|
from scapy.layers.l2 import ARP, Ether
|
|
14
14
|
from icmplib import ping
|
|
15
|
+
from icmplib.exceptions import SocketPermissionError
|
|
15
16
|
|
|
16
|
-
from lanscape.core.net_tools import Device
|
|
17
|
+
from lanscape.core.net_tools import Device, DeviceError
|
|
17
18
|
from lanscape.core.scan_config import (
|
|
18
19
|
ScanConfig, ScanType, PingConfig,
|
|
19
20
|
ArpConfig, PokeConfig, ArpCacheConfig
|
|
@@ -72,18 +73,84 @@ class IcmpLookup():
|
|
|
72
73
|
Returns:
|
|
73
74
|
bool: True if the device is reachable via ICMP, False otherwise.
|
|
74
75
|
"""
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
try:
|
|
77
|
+
# Try using icmplib first
|
|
78
|
+
for _ in range(cfg.attempts):
|
|
79
|
+
result = ping(
|
|
80
|
+
device.ip,
|
|
81
|
+
count=cfg.ping_count,
|
|
82
|
+
interval=cfg.retry_delay,
|
|
83
|
+
timeout=cfg.timeout,
|
|
84
|
+
privileged=psutil.WINDOWS # Use privileged mode on Windows
|
|
85
|
+
)
|
|
86
|
+
if result.is_alive:
|
|
87
|
+
device.alive = True
|
|
88
|
+
break
|
|
89
|
+
return device.alive is True
|
|
90
|
+
except SocketPermissionError:
|
|
91
|
+
# Fallback to system ping command when raw sockets aren't available
|
|
92
|
+
return cls._ping_fallback(device, cfg)
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
def _ping_fallback(cls, device: Device, cfg: PingConfig) -> bool:
|
|
96
|
+
"""Fallback ping using system ping command via subprocess.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
device (Device): The device to ping.
|
|
100
|
+
cfg (PingConfig): The ping configuration.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
bool: True if the device responds to ping, False otherwise.
|
|
104
|
+
"""
|
|
105
|
+
cmd = []
|
|
106
|
+
|
|
107
|
+
if psutil.WINDOWS:
|
|
108
|
+
# -n count, -w timeout in ms
|
|
109
|
+
cmd = ['ping', '-n', str(cfg.ping_count), '-w', str(int(cfg.timeout * 1000)), device.ip]
|
|
110
|
+
else: # Linux, macOS, and other Unix-like systems
|
|
111
|
+
# -c count, -W timeout in s
|
|
112
|
+
cmd = ['ping', '-c', str(cfg.ping_count), '-W', str(int(cfg.timeout)), device.ip]
|
|
113
|
+
|
|
114
|
+
for r in range(cfg.attempts):
|
|
115
|
+
try:
|
|
116
|
+
# Remove check=True to handle return codes manually
|
|
117
|
+
# Add timeout to prevent hanging
|
|
118
|
+
timeout_val = cfg.timeout * cfg.ping_count + 5
|
|
119
|
+
proc = subprocess.run(
|
|
120
|
+
cmd,
|
|
121
|
+
text=True,
|
|
122
|
+
stdout=subprocess.PIPE,
|
|
123
|
+
stderr=subprocess.PIPE,
|
|
124
|
+
timeout=timeout_val,
|
|
125
|
+
check=False # Handle return codes manually
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Check if ping was successful
|
|
129
|
+
if proc.returncode == 0:
|
|
130
|
+
output = proc.stdout.lower()
|
|
131
|
+
|
|
132
|
+
# Windows/Linux both include "TTL" on a successful reply
|
|
133
|
+
if psutil.WINDOWS or psutil.LINUX:
|
|
134
|
+
if 'ttl' in output:
|
|
135
|
+
device.alive = True
|
|
136
|
+
return True # Early return on success
|
|
137
|
+
|
|
138
|
+
# some distributions of Linux and macOS
|
|
139
|
+
if psutil.MACOS or psutil.LINUX:
|
|
140
|
+
bad = '100.0% packet loss'
|
|
141
|
+
good = 'ping statistics'
|
|
142
|
+
# mac doesnt include TTL, so we check good is there, and bad is not
|
|
143
|
+
if good in output and bad not in output:
|
|
144
|
+
device.alive = True
|
|
145
|
+
return True # Early return on success
|
|
146
|
+
|
|
147
|
+
except (subprocess.CalledProcessError, subprocess.TimeoutExpired,
|
|
148
|
+
FileNotFoundError) as e:
|
|
149
|
+
device.caught_errors.append(DeviceError(e))
|
|
150
|
+
|
|
151
|
+
if r < cfg.attempts - 1:
|
|
152
|
+
time.sleep(cfg.retry_delay)
|
|
153
|
+
|
|
87
154
|
return device.alive is True
|
|
88
155
|
|
|
89
156
|
|
lanscape/core/net_tools.py
CHANGED
|
@@ -31,10 +31,10 @@ else:
|
|
|
31
31
|
|
|
32
32
|
from lanscape.core.service_scan import scan_service
|
|
33
33
|
from lanscape.core.mac_lookup import MacLookup, get_macs
|
|
34
|
-
from lanscape.core.ip_parser import get_address_count, MAX_IPS_ALLOWED
|
|
34
|
+
from lanscape.core.ip_parser import get_address_count, MAX_IPS_ALLOWED, parse_ip_input
|
|
35
35
|
from lanscape.core.errors import DeviceError
|
|
36
36
|
from lanscape.core.decorators import job_tracker, run_once, timeout_enforcer
|
|
37
|
-
from lanscape.core.scan_config import ServiceScanConfig, PortScanConfig
|
|
37
|
+
from lanscape.core.scan_config import ServiceScanConfig, PortScanConfig, ScanType
|
|
38
38
|
|
|
39
39
|
log = logging.getLogger('NetTools')
|
|
40
40
|
mac_lookup = MacLookup()
|
|
@@ -552,6 +552,56 @@ def smart_select_primary_subnet(subnets: List[dict] = None) -> str:
|
|
|
552
552
|
return selected.get("subnet", "")
|
|
553
553
|
|
|
554
554
|
|
|
555
|
+
def is_internal_block(subnet: str) -> bool:
|
|
556
|
+
"""
|
|
557
|
+
Check if a subnet contains only internal/private IP addresses.
|
|
558
|
+
|
|
559
|
+
Supports CIDR notation, IP ranges, comma-separated lists, and single IPs.
|
|
560
|
+
For ranges and complex inputs, samples representative IPs for efficiency.
|
|
561
|
+
|
|
562
|
+
Args:
|
|
563
|
+
subnet: IP subnet string in various formats
|
|
564
|
+
|
|
565
|
+
Returns:
|
|
566
|
+
bool: True if all sampled IPs are private/internal, False otherwise
|
|
567
|
+
"""
|
|
568
|
+
try:
|
|
569
|
+
# Handle comma-separated subnets recursively
|
|
570
|
+
if ',' in subnet:
|
|
571
|
+
return all(is_internal_block(part.strip()) for part in subnet.split(','))
|
|
572
|
+
|
|
573
|
+
# Handle CIDR notation directly
|
|
574
|
+
if '/' in subnet:
|
|
575
|
+
return ipaddress.IPv4Network(subnet, strict=False).is_private
|
|
576
|
+
|
|
577
|
+
# Handle ranges and single IPs by parsing and sampling
|
|
578
|
+
ip_list = parse_ip_input(subnet)
|
|
579
|
+
sample_ips = ([ip_list[0], ip_list[-1]] if len(ip_list) > 1 else ip_list)
|
|
580
|
+
return all(ipaddress.IPv4Address(ip).is_private for ip in sample_ips)
|
|
581
|
+
|
|
582
|
+
except (ValueError, ipaddress.AddressValueError):
|
|
583
|
+
return False # Assume external for unparseable input
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
def scan_config_uses_arp(config) -> bool:
|
|
587
|
+
"""
|
|
588
|
+
Check if a scan configuration uses ARP-based scanning methods.
|
|
589
|
+
|
|
590
|
+
Args:
|
|
591
|
+
config: ScanConfig instance
|
|
592
|
+
|
|
593
|
+
Returns:
|
|
594
|
+
bool: True if the configuration uses ARP scanning, False otherwise
|
|
595
|
+
"""
|
|
596
|
+
arp_scan_types = {
|
|
597
|
+
ScanType.ARP_LOOKUP,
|
|
598
|
+
ScanType.POKE_THEN_ARP,
|
|
599
|
+
ScanType.ICMP_THEN_ARP
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return any(scan_type in arp_scan_types for scan_type in config.lookup_type)
|
|
603
|
+
|
|
604
|
+
|
|
555
605
|
@run_once
|
|
556
606
|
def is_arp_supported():
|
|
557
607
|
"""
|
lanscape/core/subnet_scan.py
CHANGED
|
@@ -22,7 +22,9 @@ from tabulate import tabulate
|
|
|
22
22
|
# Local imports
|
|
23
23
|
from lanscape.core.scan_config import ScanConfig
|
|
24
24
|
from lanscape.core.decorators import job_tracker, terminator, JobStats
|
|
25
|
-
from lanscape.core.net_tools import
|
|
25
|
+
from lanscape.core.net_tools import (
|
|
26
|
+
Device, is_internal_block, scan_config_uses_arp
|
|
27
|
+
)
|
|
26
28
|
from lanscape.core.errors import SubnetScanTerminationFailure
|
|
27
29
|
from lanscape.core.device_alive import is_device_alive
|
|
28
30
|
|
|
@@ -301,11 +303,11 @@ class ScannerResults:
|
|
|
301
303
|
Calculate the runtime of the scan in seconds.
|
|
302
304
|
|
|
303
305
|
Returns:
|
|
304
|
-
|
|
306
|
+
float: Runtime in seconds
|
|
305
307
|
"""
|
|
306
308
|
if self.scan.running:
|
|
307
|
-
return
|
|
308
|
-
return
|
|
309
|
+
return time() - self.start_time
|
|
310
|
+
return self.end_time - self.start_time
|
|
309
311
|
|
|
310
312
|
def export(self, out_type=dict) -> Union[str, dict]:
|
|
311
313
|
"""
|
|
@@ -385,6 +387,13 @@ class ScanManager:
|
|
|
385
387
|
Returns:
|
|
386
388
|
SubnetScanner: The newly created scan instance
|
|
387
389
|
"""
|
|
390
|
+
if not is_internal_block(config.subnet) and scan_config_uses_arp(config):
|
|
391
|
+
self.log.warning(
|
|
392
|
+
f"ARP scanning detected for external subnet '{config.subnet}'. "
|
|
393
|
+
"ARP requests typically only work within the local network segment. "
|
|
394
|
+
"Consider using ICMP scanning for external IP ranges."
|
|
395
|
+
)
|
|
396
|
+
|
|
388
397
|
scan = SubnetScanner(config)
|
|
389
398
|
self._start(scan)
|
|
390
399
|
self.log.info(f'Scan started - {config}')
|
lanscape/ui/shutdown_handler.py
CHANGED
lanscape/ui/static/css/style.css
CHANGED
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
--danger-border-color: #922; /* Bold red for danger borders */
|
|
35
35
|
|
|
36
36
|
--footer-height: 25px;
|
|
37
|
+
|
|
38
|
+
--fa-primary-color: var(--text-accent-color);
|
|
39
|
+
--fa-secondary-color: var(--text-placeholder);
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
body {
|
|
@@ -244,7 +247,7 @@ details {
|
|
|
244
247
|
transition: all .5s ease-in-out
|
|
245
248
|
}
|
|
246
249
|
|
|
247
|
-
#app-actions a .
|
|
250
|
+
#app-actions a .fa-solid {
|
|
248
251
|
font-size: inherit
|
|
249
252
|
}
|
|
250
253
|
#app-actions {
|
|
@@ -257,9 +260,12 @@ details {
|
|
|
257
260
|
color: var(--text-color);
|
|
258
261
|
text-decoration: none;
|
|
259
262
|
cursor: pointer;
|
|
263
|
+
--fa-primary-color: var(--text-accent-color);
|
|
264
|
+
--fa-secondary-color: var(--text-placeholder);
|
|
260
265
|
}
|
|
261
|
-
#app-actions a:hover {
|
|
262
|
-
color: var(--text-
|
|
266
|
+
#app-actions a i:hover {
|
|
267
|
+
--fa-primary-color: var(--text-color);
|
|
268
|
+
--fa-secondary-color: var(--text-accent-color);
|
|
263
269
|
}
|
|
264
270
|
|
|
265
271
|
#power-button {
|
|
@@ -274,10 +280,10 @@ details {
|
|
|
274
280
|
display: flex;
|
|
275
281
|
justify-content: space-around;
|
|
276
282
|
align-items: center;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
#scan-actions i {
|
|
286
|
+
font-size: 20px;
|
|
281
287
|
}
|
|
282
288
|
|
|
283
289
|
#advanced-modal {
|
|
@@ -796,13 +802,7 @@ html {
|
|
|
796
802
|
}
|
|
797
803
|
|
|
798
804
|
|
|
799
|
-
|
|
800
|
-
font-variation-settings:
|
|
801
|
-
'FILL' 0,
|
|
802
|
-
'wght' 400,
|
|
803
|
-
'GRAD' 0,
|
|
804
|
-
'opsz' 24
|
|
805
|
-
}
|
|
805
|
+
/* FontAwesome Solid Icon Styling */
|
|
806
806
|
|
|
807
807
|
#shutdown-sub-sub {
|
|
808
808
|
color: var(--text-almost-hidden);
|
|
@@ -942,7 +942,7 @@ html {
|
|
|
942
942
|
border-radius: 999px;
|
|
943
943
|
color: var(--text-color);
|
|
944
944
|
}
|
|
945
|
-
#device-modal .chip .
|
|
945
|
+
#device-modal .chip .fa-solid {
|
|
946
946
|
font-size: 16px;
|
|
947
947
|
}
|
|
948
948
|
|
lanscape/ui/templates/base.html
CHANGED
|
@@ -24,24 +24,22 @@
|
|
|
24
24
|
|
|
25
25
|
<div id="app-actions">
|
|
26
26
|
<a href="/info">
|
|
27
|
-
<
|
|
28
|
-
class="
|
|
27
|
+
<i
|
|
28
|
+
class="fa-duotone fa-light fa-circle-info"
|
|
29
29
|
data-bs-toggle="tooltip"
|
|
30
30
|
data-bs-placement="top"
|
|
31
31
|
title="App info">
|
|
32
|
-
|
|
33
|
-
</span>
|
|
32
|
+
</i>
|
|
34
33
|
</a>
|
|
35
34
|
|
|
36
35
|
<a href="/shutdown-ui">
|
|
37
|
-
<
|
|
36
|
+
<i
|
|
38
37
|
id="power-button"
|
|
39
|
-
class="
|
|
38
|
+
class="fa-solid fa-power-off"
|
|
40
39
|
data-bs-toggle="tooltip"
|
|
41
40
|
data-bs-placement="top"
|
|
42
41
|
title="Shutdown App">
|
|
43
|
-
|
|
44
|
-
</span>
|
|
42
|
+
</i>
|
|
45
43
|
</a>
|
|
46
44
|
</div>
|
|
47
45
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<title>LANscape</title>
|
|
4
4
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
5
5
|
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
|
|
6
|
-
<
|
|
6
|
+
<script src="https://kit.fontawesome.com/d0b7f59243.js" crossorigin="anonymous"></script>
|
|
7
7
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/img/ico/apple-touch-icon.png">
|
|
8
8
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/img/ico/favicon-32x32.png">
|
|
9
9
|
<link rel="icon" type="image/png" sizes="16x16" href="/static/img/ico/favicon-16x16.png">
|
lanscape/ui/templates/info.html
CHANGED
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
<div class="scroll-container" id="content">
|
|
15
15
|
{% if update_available %}
|
|
16
16
|
<div class="container-fluid my-4">
|
|
17
|
-
<h3>
|
|
17
|
+
<h3>
|
|
18
|
+
<i class="fa-solid fa-cloud-arrow-up"></i>
|
|
19
|
+
New version available!
|
|
20
|
+
</h3>
|
|
18
21
|
<p>
|
|
19
22
|
A new version has been published to PyPi.
|
|
20
23
|
({{app_version}} -> {{latest_version}})
|
|
@@ -26,7 +29,10 @@
|
|
|
26
29
|
</div>
|
|
27
30
|
{% endif %}
|
|
28
31
|
<div class="container-fluid my-4">
|
|
29
|
-
<h3>
|
|
32
|
+
<h3>
|
|
33
|
+
<i class="fa-duotone fa-light fa-circle-question"></i>
|
|
34
|
+
About
|
|
35
|
+
</h3>
|
|
30
36
|
<p>
|
|
31
37
|
LANscape was born from my frustration with existing local network scanning tools
|
|
32
38
|
alongside my desire to dive deeper into technologies like
|
|
@@ -36,14 +42,23 @@
|
|
|
36
42
|
discover more about your network as well. Enjoy!
|
|
37
43
|
</p>
|
|
38
44
|
<a href="https://github.com/mdennis281/" class="text-decoration-none" target="_blank">
|
|
39
|
-
<button class="btn btn-primary m-2">
|
|
45
|
+
<button class="btn btn-primary m-2">
|
|
46
|
+
<i class="fa-brands fa-github"></i>
|
|
47
|
+
GitHub
|
|
48
|
+
</button>
|
|
40
49
|
</a>
|
|
41
50
|
<a href="https://github.com/mdennis281/LANscape" class="text-decoration-none" target="_blank">
|
|
42
|
-
<button class="btn btn-secondary m-2">
|
|
51
|
+
<button class="btn btn-secondary m-2">
|
|
52
|
+
<i class="fa-solid fa-code-fork"></i>
|
|
53
|
+
Project Repo
|
|
54
|
+
</button>
|
|
43
55
|
</a>
|
|
44
56
|
</div>
|
|
45
57
|
<div class="container-fluid my-4">
|
|
46
|
-
<h3>
|
|
58
|
+
<h3>
|
|
59
|
+
<i class="fa-duotone fa-light fa-sliders"></i>
|
|
60
|
+
Runtime Arguments
|
|
61
|
+
</h3>
|
|
47
62
|
<table class="table table-striped table-bordered">
|
|
48
63
|
<thead class="table-dark">
|
|
49
64
|
<tr>
|
lanscape/ui/templates/main.html
CHANGED
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
<button
|
|
24
24
|
type="button"
|
|
25
25
|
id="settings-btn"
|
|
26
|
-
class="btn btn-secondary start
|
|
26
|
+
class="btn btn-secondary start"
|
|
27
27
|
data-bs-toggle="tooltip"
|
|
28
28
|
data-bs-placement="bottom"
|
|
29
29
|
title="Advanced scan settings"
|
|
30
30
|
>
|
|
31
|
-
|
|
31
|
+
<i class="fa-solid fa-gear"></i>
|
|
32
32
|
</button>
|
|
33
33
|
<input type="text" id="subnet" name="subnet" class="form-control" value="{{ subnet }}" placeholder="Enter subnet">
|
|
34
34
|
<button class="btn btn-secondary dropdown-toggle end" type="button" id="subnet-dropdown" data-bs-toggle="dropdown" aria-expanded="false"></button>
|
|
@@ -59,13 +59,12 @@
|
|
|
59
59
|
<h2>Scan Results</h2>
|
|
60
60
|
<div id="scan-actions">
|
|
61
61
|
<a href="" id="export-link">
|
|
62
|
-
<
|
|
63
|
-
class="
|
|
62
|
+
<i
|
|
63
|
+
class="fa-solid fa-upload secondary-icon-btn"
|
|
64
64
|
data-bs-toggle="tooltip"
|
|
65
65
|
data-bs-placement="top"
|
|
66
66
|
title="Export scan to json">
|
|
67
|
-
|
|
68
|
-
</span>
|
|
67
|
+
</i>
|
|
69
68
|
</a>
|
|
70
69
|
</div>
|
|
71
70
|
</div>
|
|
@@ -8,21 +8,24 @@
|
|
|
8
8
|
<div class="modal-body">
|
|
9
9
|
<div class="d-flex gap-2 mb-3">
|
|
10
10
|
<div class="config-option p-3 flex-fill flex-wrap" id="config-fast" data-config="fast" onclick="setScanConfig('fast')">
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
11
|
+
<div class="d-flex flex-column align-items-center justify-content-center">
|
|
12
|
+
<i class="fa-solid fa-bolt mb-2" style="font-size: 1.5em;"></i>
|
|
13
|
+
<h5 class="mb-1">Fast</h5>
|
|
14
|
+
</div>
|
|
14
15
|
<p class="mb-0">Fast scan, Low accuracy</p>
|
|
15
16
|
</div>
|
|
16
17
|
<div class="config-option p-3 flex-fill" id="config-balanced" data-config="balanced" onclick="setScanConfig('balanced')">
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
18
|
+
<div class="d-flex flex-column align-items-center justify-content-center">
|
|
19
|
+
<i class="fa-solid fa-scale-balanced mb-2" style="font-size: 1.5em;"></i>
|
|
20
|
+
<h5 class="mb-1">Balanced</h5>
|
|
21
|
+
</div>
|
|
20
22
|
<p class="mb-0">Balanced scan, Moderate accuracy</p>
|
|
21
23
|
</div>
|
|
22
24
|
<div class="config-option p-3 flex-fill" id="config-accurate" data-config="accurate" onclick="setScanConfig('accurate')">
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
25
|
+
<div class="d-flex flex-column align-items-center justify-content-center">
|
|
26
|
+
<i class="fa-solid fa-bullseye mb-2" style="font-size: 1.5em;"></i>
|
|
27
|
+
<h5 class="mb-1">Accurate</h5>
|
|
28
|
+
</div>
|
|
26
29
|
<p class="mb-0">Thorough scan, High accuracy</p>
|
|
27
30
|
</div>
|
|
28
31
|
</div>
|
|
@@ -51,15 +54,13 @@
|
|
|
51
54
|
ARP Lookup
|
|
52
55
|
</label>
|
|
53
56
|
{% if not is_arp_supported %}
|
|
54
|
-
<
|
|
55
|
-
class="
|
|
57
|
+
<i
|
|
58
|
+
class="fa-solid fa-circle-question arp-help-ico"
|
|
56
59
|
data-bs-toggle="tooltip"
|
|
57
60
|
data-bs-placement="top"
|
|
58
61
|
title="ARP lookup is not supported on this system, click for more info"
|
|
59
62
|
onclick="window.open('https://github.com/mdennis281/LANscape/blob/main/docs/arp-issues.md', '_blank')"
|
|
60
|
-
>
|
|
61
|
-
help
|
|
62
|
-
</span>
|
|
63
|
+
></i>
|
|
63
64
|
{% endif %}
|
|
64
65
|
</div>
|
|
65
66
|
<div class="form-check">
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<div class="chip-group mt-1">
|
|
50
50
|
{% for p in ports %}
|
|
51
51
|
<span class="chip" title="Port {{ p }}">
|
|
52
|
-
<
|
|
52
|
+
<i class="fa-solid fa-network-wired"></i>{{ p }}
|
|
53
53
|
</span>
|
|
54
54
|
{% endfor %}
|
|
55
55
|
</div>
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
{% for svc, svc_ports in services|dictsort %}
|
|
66
66
|
<div class="service-row">
|
|
67
67
|
<div class="service-name">
|
|
68
|
-
<
|
|
68
|
+
<i class="fa-solid fa-server align-middle me-1"></i>{{ svc|default('Unknown') }}
|
|
69
69
|
</div>
|
|
70
70
|
<div class="service-ports">
|
|
71
71
|
{% set s_ports = svc_ports|default([]) %}
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
<ul class="list-unstyled error-list mt-1">
|
|
92
92
|
{% for err in errors %}
|
|
93
93
|
<li class="text-danger">
|
|
94
|
-
<
|
|
94
|
+
<i class="fa-solid fa-circle-exclamation align-middle me-1"></i>
|
|
95
95
|
{{ err }}
|
|
96
96
|
</li>
|
|
97
97
|
{% endfor %}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<tr>
|
|
2
2
|
<td>
|
|
3
3
|
<div class="info-icon-container">
|
|
4
|
-
<
|
|
5
|
-
class="
|
|
4
|
+
<i
|
|
5
|
+
class="fa-solid fa-circle-info info-icon"
|
|
6
6
|
onclick="parent.openDeviceDetail('{{ device.ip }}')"
|
|
7
|
-
>
|
|
7
|
+
></i>
|
|
8
8
|
</div>
|
|
9
9
|
</td>
|
|
10
10
|
<td>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -28,6 +28,8 @@ Requires-Dist: icmplib
|
|
|
28
28
|
Provides-Extra: dev
|
|
29
29
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
30
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-xdist>=3.0; extra == "dev"
|
|
32
|
+
Requires-Dist: openai>=1.0.0; extra == "dev"
|
|
31
33
|
Dynamic: license-file
|
|
32
34
|
|
|
33
35
|
# LANscape
|
|
@@ -3,17 +3,17 @@ lanscape/__main__.py,sha256=PuY42yuCLAwHrOREJ6u2DgVyGX5hZKRQeoE9pajkNfM,170
|
|
|
3
3
|
lanscape/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
lanscape/core/app_scope.py,sha256=qfzX8Ed4bFdxHMGjgnLlWuLZDTCBKObermz91KbGVn0,3298
|
|
5
5
|
lanscape/core/decorators.py,sha256=CZbPEfnLS1OF-uejQweetadzqf0pVo736jKko4Xs-g4,7264
|
|
6
|
-
lanscape/core/device_alive.py,sha256=
|
|
6
|
+
lanscape/core/device_alive.py,sha256=VY2dsoy6_MWUxcysZEFcsSoCtDkLMYzwqy0U_sbVWE0,9609
|
|
7
7
|
lanscape/core/errors.py,sha256=QTf42UzR9Zxj1t1mdwfLvZIp0c9a5EItELOdCR7kTmE,1322
|
|
8
8
|
lanscape/core/ip_parser.py,sha256=kn5H4ERitLnreRAqifWphwbxdjItGqwu50lsMCPDMcA,3474
|
|
9
9
|
lanscape/core/logger.py,sha256=nzo6J8UdlMdhRkOJEDOIHKztoE3Du8PQZad7ixvNgeM,2534
|
|
10
10
|
lanscape/core/mac_lookup.py,sha256=PxBSMe3wEVDtivCsh5NclSAguZz9rqdAS7QshBiuWvM,3519
|
|
11
|
-
lanscape/core/net_tools.py,sha256=
|
|
11
|
+
lanscape/core/net_tools.py,sha256=Ht8TkLnKf-f6E1_AkTCde-yuiwUNI57TCXke0nIFi0o,21303
|
|
12
12
|
lanscape/core/port_manager.py,sha256=3_ROOb6JEiB0NByZVtADuGcldFkgZwn1RKtvwgs9AIk,4479
|
|
13
13
|
lanscape/core/runtime_args.py,sha256=2vIqRrcWr-NHRSBlZGrxh1PdkPY0ytkPguu8KZqy2L8,2543
|
|
14
14
|
lanscape/core/scan_config.py,sha256=A2ZKXqXKW9nrP6yLb7b9b3XqSY_cQB3LZ5K0LVCSebE,11114
|
|
15
15
|
lanscape/core/service_scan.py,sha256=wTDxOdazOsbI0hwCBR__4UCmB2RIbl2pw3F2YUW9aaE,6428
|
|
16
|
-
lanscape/core/subnet_scan.py,sha256=
|
|
16
|
+
lanscape/core/subnet_scan.py,sha256=PtSOk92dK05-reyr8LBkOXaI15qpYnar5nDqALCX1tQ,14850
|
|
17
17
|
lanscape/core/version_manager.py,sha256=eGjyKgsv31QO0W26se9pPQ1TwmEN8qn37dHULtoocqc,2841
|
|
18
18
|
lanscape/core/web_browser.py,sha256=23MuGIrBYdGhw6ejj6OWxwReeKIlWhtWukc1dKV_3_0,6736
|
|
19
19
|
lanscape/resources/mac_addresses/convert_csv.py,sha256=hvlyLs0XmuuhBuvXBNRGP1cKJzYVRSf8VfUJ1VqROms,1189
|
|
@@ -28,7 +28,7 @@ lanscape/resources/services/definitions.jsonc,sha256=M9BDeK-mh25sEVj8xDEYbU2ix7E
|
|
|
28
28
|
lanscape/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
lanscape/ui/app.py,sha256=rg4UGHgbVHpU2jdabSwBoSqGna7WGOunPkPc5Tvds9w,4076
|
|
30
30
|
lanscape/ui/main.py,sha256=UCrhHnyFBqVmHTMus33CTp3vdNn3miT1xXJatR4N7ho,4176
|
|
31
|
-
lanscape/ui/shutdown_handler.py,sha256=
|
|
31
|
+
lanscape/ui/shutdown_handler.py,sha256=HrEnWrdYSzLDVsPgD8tf9FgtAwQrZNECDu6wnEs27EY,1704
|
|
32
32
|
lanscape/ui/blueprints/__init__.py,sha256=EjPtaR5Nh17pGiOVYTJULVNaZntpFZOiYyep8rBWAiE,265
|
|
33
33
|
lanscape/ui/blueprints/api/__init__.py,sha256=5Z4Y7B36O-bNFenpomfuNhPuJ9dW_MC0TPUU3pCFVfA,103
|
|
34
34
|
lanscape/ui/blueprints/api/port.py,sha256=KlfLrAmlTqN44I1jLVDy-mWOcor4kL-b0Cl4AcTMCys,1976
|
|
@@ -37,7 +37,7 @@ lanscape/ui/blueprints/api/tools.py,sha256=jr9gt0VhvBFgJ61MLgNIM6hin-MUmJLGdmStP
|
|
|
37
37
|
lanscape/ui/blueprints/web/__init__.py,sha256=NvgnjP0X4LwqVhSEyh5RUzoG45N44kHK1MEFlfvBxTg,118
|
|
38
38
|
lanscape/ui/blueprints/web/routes.py,sha256=f5TzfTzelJ_erslyBXTOpFr4BlIfB1Mb1ye6ioH7IL0,4534
|
|
39
39
|
lanscape/ui/static/lanscape.webmanifest,sha256=07CqA-PQsO35KJD8R96sI3Pxix6UuBjijPDCuy9vM3s,446
|
|
40
|
-
lanscape/ui/static/css/style.css,sha256=
|
|
40
|
+
lanscape/ui/static/css/style.css,sha256=9IQru_W0WUpcxNJuHbqwjfxLOC5n1EeGcxf_kDVY3jc,21232
|
|
41
41
|
lanscape/ui/static/img/ico/android-chrome-192x192.png,sha256=JmFT6KBCCuoyxMV-mLNtF9_QJbVBvfWPUizKN700fi8,18255
|
|
42
42
|
lanscape/ui/static/img/ico/android-chrome-512x512.png,sha256=88Jjx_1-4XAnZYz64KP6FdTl_kYkNG2_kQIKteQwSh4,138055
|
|
43
43
|
lanscape/ui/static/img/ico/apple-touch-icon.png,sha256=tEJlLwBZtF4v-NC90YCfRJQ2prTsF4i3VQLK_hnv2Mw,16523
|
|
@@ -54,24 +54,24 @@ lanscape/ui/static/js/scan-config.js,sha256=TiUwWWUGqqQbC3ZJnQCNQpoR492RXA3jLkAL
|
|
|
54
54
|
lanscape/ui/static/js/shutdown-server.js,sha256=Mx8UGmmktHaCK7DL8TVUxah6VEcN0wwLFfhbCId-K8U,453
|
|
55
55
|
lanscape/ui/static/js/subnet-info.js,sha256=osZM6CGs-TC5QpBJWkNWCtXNOKzjyIiWKHwKi4vlDf8,559
|
|
56
56
|
lanscape/ui/static/js/subnet-selector.js,sha256=2YKCAuKU2Ti1CmJrqi4_vNTD2LQbxx7chIDqND_1eAY,358
|
|
57
|
-
lanscape/ui/templates/base.html,sha256=
|
|
57
|
+
lanscape/ui/templates/base.html,sha256=HIHLFEUMDTGEaeuSpeNg-vkXXb9VNbZnbFWlYetVL18,1377
|
|
58
58
|
lanscape/ui/templates/error.html,sha256=bqGJbf_ix9wtpUlXk5zvz_XyFpeTbEO-4f0ImgLtUGk,1033
|
|
59
|
-
lanscape/ui/templates/info.html,sha256=
|
|
60
|
-
lanscape/ui/templates/main.html,sha256=
|
|
59
|
+
lanscape/ui/templates/info.html,sha256=SQ6RpTs9_v9HF32mr3FBsh6vTJneYqFz_WrC9diXzHg,2958
|
|
60
|
+
lanscape/ui/templates/main.html,sha256=jTFLH9xuMNayQRkDNB_8BIQopaD4YtI5MI2zMpaMsMA,3842
|
|
61
61
|
lanscape/ui/templates/scan.html,sha256=00QX2_1S_1wGzk42r00LjEkJvoioCLs6JgjOibi6r20,376
|
|
62
62
|
lanscape/ui/templates/shutdown.html,sha256=iXVCq2yl5TjZfNFl4esbDJra3gJA2VQpae0jj4ipy9w,701
|
|
63
|
-
lanscape/ui/templates/core/head.html,sha256=
|
|
63
|
+
lanscape/ui/templates/core/head.html,sha256=zP1RkTYuaKCC6RtnSEHFKPw3wKWfSyV0HZg5XsAxWik,719
|
|
64
64
|
lanscape/ui/templates/core/scripts.html,sha256=rSRi4Ut8iejajMPhOc5bzEz-Z3EHxpj_3PxwwyyhmTQ,640
|
|
65
|
-
lanscape/ui/templates/scan/config.html,sha256=
|
|
66
|
-
lanscape/ui/templates/scan/device-detail.html,sha256=
|
|
65
|
+
lanscape/ui/templates/scan/config.html,sha256=X95xayNtJrRUeGUlPbtUjd1228hH6re9BT6jcbaSnl8,14704
|
|
66
|
+
lanscape/ui/templates/scan/device-detail.html,sha256=3N0WcdnWopbSFwsnKogBaHOYsLMAfKBZdkP7HQG4vLA,4794
|
|
67
67
|
lanscape/ui/templates/scan/export.html,sha256=Nvs_unojzT3qhN_ZnEgYHou2C9wqWGr3dVr2UiLnYjY,749
|
|
68
|
-
lanscape/ui/templates/scan/ip-table-row.html,sha256=
|
|
68
|
+
lanscape/ui/templates/scan/ip-table-row.html,sha256=iSW3PYev3_k7pxTZUJUboqDUgdhsWNOrYxysYismyI0,1255
|
|
69
69
|
lanscape/ui/templates/scan/ip-table.html,sha256=AT2ZvCPYdKl-XJiAkEAawPOVuQw-w0MXumGQTr3zyKM,926
|
|
70
70
|
lanscape/ui/templates/scan/overview.html,sha256=xWj9jWDPg2KcPLvS8fnSins23_UXjKCdb2NJwNG2U2Q,1176
|
|
71
71
|
lanscape/ui/templates/scan/scan-error.html,sha256=wmAYQ13IJHUoO8fAGNDjMvNml7tu4rsIU3Vav71ETlA,999
|
|
72
|
-
lanscape-2.
|
|
73
|
-
lanscape-2.
|
|
74
|
-
lanscape-2.
|
|
75
|
-
lanscape-2.
|
|
76
|
-
lanscape-2.
|
|
77
|
-
lanscape-2.
|
|
72
|
+
lanscape-2.1.2.dist-info/licenses/LICENSE,sha256=VLoE0IrNTIc09dFm7hMN0qzk4T3q8V0NaPcFQqMemDs,1070
|
|
73
|
+
lanscape-2.1.2.dist-info/METADATA,sha256=oxHxoHbAYnhTnSIgsMyzzgqevSrWmF5Fzti1bqjLAao,3578
|
|
74
|
+
lanscape-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
75
|
+
lanscape-2.1.2.dist-info/entry_points.txt,sha256=evxSxUikFa1OEd4e0Boky9sLH87HdgM0YqB_AbB2HYc,51
|
|
76
|
+
lanscape-2.1.2.dist-info/top_level.txt,sha256=E9D4sjPz_6H7c85Ycy_pOS2xuv1Wm-ilKhxEprln2ps,9
|
|
77
|
+
lanscape-2.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|