wip
This commit is contained in:
parent
6dd38036e7
commit
097b3dbf09
34 changed files with 1719 additions and 520 deletions
|
@ -7,63 +7,41 @@ from app.core.extensions import db
|
|||
from app.core.models import Subnet, Server
|
||||
import json
|
||||
import subprocess
|
||||
import concurrent.futures
|
||||
from datetime import datetime
|
||||
import platform
|
||||
|
||||
def scan(cidr, max_threads=10, save_results=False):
|
||||
def scan(subnet, manual_trigger=False):
|
||||
"""
|
||||
Scan a subnet for active hosts
|
||||
|
||||
Args:
|
||||
cidr: The subnet in CIDR notation (e.g. "192.168.1.0/24")
|
||||
max_threads: Maximum number of threads to use
|
||||
save_results: Whether to save results to the database
|
||||
|
||||
Returns:
|
||||
A list of dictionaries with IP, hostname, and status
|
||||
subnet: The subnet object to scan
|
||||
manual_trigger: If False, only scan if the subnet hasn't been scanned recently
|
||||
"""
|
||||
print(f"Starting scan of {cidr}")
|
||||
network = ipaddress.ip_network(cidr)
|
||||
# Skip if not auto scan and not manually triggered
|
||||
if not subnet.auto_scan and not manual_trigger:
|
||||
return False
|
||||
|
||||
# Skip network and broadcast addresses for IPv4
|
||||
if network.version == 4:
|
||||
hosts = list(network.hosts())
|
||||
else:
|
||||
# For IPv6, just take the first 100 addresses to avoid scanning too many
|
||||
hosts = list(network.hosts())[:100]
|
||||
active_hosts = []
|
||||
|
||||
# Split the hosts into chunks for multithreading
|
||||
chunks = [[] for _ in range(max_threads)]
|
||||
for i, host in enumerate(hosts):
|
||||
chunks[i % max_threads].append(host)
|
||||
|
||||
# Initialize results
|
||||
results = [[] for _ in range(max_threads)]
|
||||
|
||||
# Create and start threads
|
||||
threads = []
|
||||
for i in range(max_threads):
|
||||
if chunks[i]: # Only start a thread if there are IPs to scan
|
||||
t = threading.Thread(target=scan_worker, args=(chunks[i], results, i))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
|
||||
# Wait for all threads to complete
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
# Combine results
|
||||
all_results = []
|
||||
for r in results:
|
||||
all_results.extend(r)
|
||||
|
||||
# Save results to database if requested
|
||||
if save_results:
|
||||
try:
|
||||
save_scan_results(cidr, all_results)
|
||||
except Exception as e:
|
||||
print(f"Error saving scan results: {e}")
|
||||
|
||||
print(f"Scan completed. Found {len(all_results)} active hosts.")
|
||||
return all_results
|
||||
try:
|
||||
# Parse the CIDR notation
|
||||
network = ipaddress.ip_network(subnet.cidr, strict=False)
|
||||
|
||||
# For each address in this network, ping it
|
||||
for ip in network.hosts():
|
||||
if ping(str(ip)):
|
||||
active_hosts.append(str(ip))
|
||||
|
||||
# Update subnet with scan results
|
||||
subnet.active_hosts = json.dumps(active_hosts)
|
||||
subnet.last_scanned = datetime.utcnow()
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error scanning subnet {subnet.cidr}: {str(e)}")
|
||||
return False
|
||||
|
||||
def scan_worker(ip_list, results, index):
|
||||
"""Worker function for threading"""
|
||||
|
@ -76,13 +54,23 @@ def scan_worker(ip_list, results, index):
|
|||
'status': 'up'
|
||||
})
|
||||
|
||||
def ping(ip):
|
||||
"""Ping an IP address and return True if it responds"""
|
||||
def ping(host):
|
||||
"""
|
||||
Returns True if host responds to a ping request
|
||||
"""
|
||||
# Ping parameters based on OS
|
||||
param = '-n' if platform.system().lower() == 'windows' else '-c'
|
||||
# Build the command
|
||||
command = ['ping', param, '1', '-w', '1', host]
|
||||
|
||||
try:
|
||||
# Faster timeout (1 second)
|
||||
subprocess.check_output(['ping', '-c', '1', '-W', '1', str(ip)], stderr=subprocess.STDOUT)
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
# Run the command and capture output
|
||||
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2)
|
||||
# Return True if ping was successful
|
||||
return output.returncode == 0
|
||||
except subprocess.TimeoutExpired:
|
||||
return False
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def get_hostname(ip):
|
||||
|
@ -166,7 +154,7 @@ def schedule_subnet_scans():
|
|||
# Start a thread for each subnet
|
||||
thread = threading.Thread(
|
||||
target=scan,
|
||||
args=(subnet.cidr,),
|
||||
args=(subnet,),
|
||||
daemon=True
|
||||
)
|
||||
thread.start()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue