wip
This commit is contained in:
parent
3b2f1db4ce
commit
5c16964b76
47 changed files with 2080 additions and 1053 deletions
|
@ -11,10 +11,11 @@ import concurrent.futures
|
|||
from datetime import datetime
|
||||
import platform
|
||||
|
||||
|
||||
def scan(subnet, manual_trigger=False):
|
||||
"""
|
||||
Scan a subnet for active hosts
|
||||
|
||||
|
||||
Args:
|
||||
subnet: The subnet object to scan
|
||||
manual_trigger: If False, only scan if the subnet hasn't been scanned recently
|
||||
|
@ -22,50 +23,56 @@ def scan(subnet, manual_trigger=False):
|
|||
# Skip if not auto scan and not manually triggered
|
||||
if not subnet.auto_scan and not manual_trigger:
|
||||
return False
|
||||
|
||||
|
||||
active_hosts = []
|
||||
|
||||
|
||||
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"""
|
||||
for ip in ip_list:
|
||||
if ping(ip):
|
||||
hostname = get_hostname(ip)
|
||||
results[index].append({
|
||||
'ip': str(ip),
|
||||
'hostname': hostname if hostname else str(ip),
|
||||
'status': 'up'
|
||||
})
|
||||
results[index].append(
|
||||
{
|
||||
"ip": str(ip),
|
||||
"hostname": hostname if hostname else str(ip),
|
||||
"status": "up",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
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'
|
||||
param = "-n" if platform.system().lower() == "windows" else "-c"
|
||||
# Build the command
|
||||
command = ['ping', param, '1', '-w', '1', host]
|
||||
|
||||
command = ["ping", param, "1", "-w", "1", host]
|
||||
|
||||
try:
|
||||
# Run the command and capture output
|
||||
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2)
|
||||
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:
|
||||
|
@ -73,6 +80,7 @@ def ping(host):
|
|||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def get_hostname(ip):
|
||||
"""Try to get the hostname for an IP address"""
|
||||
try:
|
||||
|
@ -81,43 +89,53 @@ def get_hostname(ip):
|
|||
except (socket.herror, socket.gaierror):
|
||||
return None
|
||||
|
||||
|
||||
def is_host_active_ping(ip):
|
||||
"""Simple ICMP ping test (platform dependent)"""
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
param = '-n' if platform.system().lower() == 'windows' else '-c'
|
||||
command = ['ping', param, '1', '-w', '1', ip]
|
||||
|
||||
|
||||
param = "-n" if platform.system().lower() == "windows" else "-c"
|
||||
command = ["ping", param, "1", "-w", "1", ip]
|
||||
|
||||
try:
|
||||
return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
|
||||
return (
|
||||
subprocess.call(
|
||||
command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||
)
|
||||
== 0
|
||||
)
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def save_scan_results(cidr, results):
|
||||
"""Save scan results to the database"""
|
||||
from flask import current_app
|
||||
|
||||
|
||||
# Need to be in application context
|
||||
if not hasattr(current_app, 'app_context'):
|
||||
if not hasattr(current_app, "app_context"):
|
||||
print("Not in Flask application context, cannot save results")
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
# Find subnet by CIDR
|
||||
subnet = Subnet.query.filter_by(cidr=cidr).first()
|
||||
if not subnet:
|
||||
print(f"Subnet {cidr} not found in database")
|
||||
return
|
||||
|
||||
|
||||
# Get existing servers in this subnet
|
||||
existing_servers = {server.ip_address: server for server in Server.query.filter_by(subnet_id=subnet.id).all()}
|
||||
|
||||
existing_servers = {
|
||||
server.ip_address: server
|
||||
for server in Server.query.filter_by(subnet_id=subnet.id).all()
|
||||
}
|
||||
|
||||
# Process scan results
|
||||
for host in results:
|
||||
ip = host['ip']
|
||||
hostname = host['hostname']
|
||||
|
||||
ip = host["ip"]
|
||||
hostname = host["hostname"]
|
||||
|
||||
# Check if server already exists
|
||||
if ip in existing_servers:
|
||||
# Update hostname if it was previously unknown
|
||||
|
@ -130,37 +148,34 @@ def save_scan_results(cidr, results):
|
|||
hostname=hostname,
|
||||
ip_address=ip,
|
||||
subnet_id=subnet.id,
|
||||
documentation=f"# {hostname}\n\nAutomatically discovered by network scan on {time.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
documentation=f"# {hostname}\n\nAutomatically discovered by network scan on {time.strftime('%Y-%m-%d %H:%M:%S')}",
|
||||
)
|
||||
db.session.add(server)
|
||||
|
||||
|
||||
db.session.commit()
|
||||
print(f"Saved scan results for {cidr}")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print(f"Error saving scan results: {e}")
|
||||
|
||||
|
||||
def schedule_subnet_scans():
|
||||
"""Schedule automatic scans for subnets marked as auto_scan"""
|
||||
from flask import current_app
|
||||
|
||||
|
||||
with current_app.app_context():
|
||||
try:
|
||||
# Find all subnets with auto_scan enabled
|
||||
subnets = Subnet.query.filter_by(auto_scan=True).all()
|
||||
|
||||
|
||||
for subnet in subnets:
|
||||
# Start a thread for each subnet
|
||||
thread = threading.Thread(
|
||||
target=scan,
|
||||
args=(subnet,),
|
||||
daemon=True
|
||||
)
|
||||
thread = threading.Thread(target=scan, args=(subnet,), daemon=True)
|
||||
thread.start()
|
||||
|
||||
|
||||
# Sleep briefly to avoid overloading
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error scheduling subnet scans: {e}")
|
||||
print(f"Error scheduling subnet scans: {e}")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue