Autarch Will Control The Internet
This commit is contained in:
363
modules/nettest.py
Normal file
363
modules/nettest.py
Normal file
@@ -0,0 +1,363 @@
|
||||
"""
|
||||
AUTARCH Network Test Module
|
||||
Test network speed and connectivity
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from core.banner import Colors
|
||||
|
||||
# Module metadata
|
||||
NAME = "Network Test"
|
||||
DESCRIPTION = "Test network speed and connectivity"
|
||||
AUTHOR = "darkHal Security Group"
|
||||
VERSION = "1.0"
|
||||
CATEGORY = "utility"
|
||||
|
||||
# Try to import optional dependencies
|
||||
try:
|
||||
import speedtest
|
||||
HAS_SPEEDTEST = True
|
||||
except ImportError:
|
||||
HAS_SPEEDTEST = False
|
||||
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
HAS_REQUESTS = False
|
||||
|
||||
|
||||
class NetworkTester:
|
||||
"""Network testing utility."""
|
||||
|
||||
def __init__(self):
|
||||
self.test_urls = [
|
||||
("Google", "https://www.google.com"),
|
||||
("Cloudflare", "https://1.1.1.1"),
|
||||
("GitHub", "https://github.com"),
|
||||
("Amazon", "https://aws.amazon.com"),
|
||||
]
|
||||
|
||||
def test_connectivity(self) -> dict:
|
||||
"""Test basic internet connectivity.
|
||||
|
||||
Returns:
|
||||
Dict with connectivity results.
|
||||
"""
|
||||
if not HAS_REQUESTS:
|
||||
return {'error': 'requests library not available'}
|
||||
|
||||
print(f"{Colors.CYAN}[*] Testing connectivity...{Colors.RESET}")
|
||||
|
||||
results = {
|
||||
'tests': [],
|
||||
'success_count': 0,
|
||||
'fail_count': 0,
|
||||
}
|
||||
|
||||
for name, url in self.test_urls:
|
||||
try:
|
||||
start = time.time()
|
||||
response = requests.get(url, timeout=10)
|
||||
elapsed = round((time.time() - start) * 1000)
|
||||
|
||||
success = response.status_code == 200
|
||||
results['tests'].append({
|
||||
'name': name,
|
||||
'url': url,
|
||||
'success': success,
|
||||
'status': response.status_code,
|
||||
'time_ms': elapsed,
|
||||
})
|
||||
|
||||
if success:
|
||||
results['success_count'] += 1
|
||||
print(f" {Colors.GREEN}[+]{Colors.RESET} {name}: {elapsed}ms")
|
||||
else:
|
||||
results['fail_count'] += 1
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} {name}: HTTP {response.status_code}")
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
results['fail_count'] += 1
|
||||
results['tests'].append({
|
||||
'name': name,
|
||||
'url': url,
|
||||
'success': False,
|
||||
'error': 'Timeout',
|
||||
})
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} {name}: Timeout")
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
results['fail_count'] += 1
|
||||
results['tests'].append({
|
||||
'name': name,
|
||||
'url': url,
|
||||
'success': False,
|
||||
'error': 'Connection failed',
|
||||
})
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} {name}: Connection failed")
|
||||
|
||||
except Exception as e:
|
||||
results['fail_count'] += 1
|
||||
results['tests'].append({
|
||||
'name': name,
|
||||
'url': url,
|
||||
'success': False,
|
||||
'error': str(e),
|
||||
})
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} {name}: {str(e)}")
|
||||
|
||||
return results
|
||||
|
||||
def test_speed(self) -> dict:
|
||||
"""Test network speed using speedtest.
|
||||
|
||||
Returns:
|
||||
Dict with speed test results.
|
||||
"""
|
||||
if not HAS_SPEEDTEST:
|
||||
return {'error': 'speedtest-cli library not available'}
|
||||
|
||||
print(f"{Colors.CYAN}[*] Running speed test (this may take a minute)...{Colors.RESET}")
|
||||
|
||||
try:
|
||||
st = speedtest.Speedtest(secure=True)
|
||||
|
||||
print(f" {Colors.DIM}Finding best server...{Colors.RESET}")
|
||||
st.get_best_server()
|
||||
|
||||
print(f" {Colors.DIM}Testing download speed...{Colors.RESET}")
|
||||
st.download(threads=None)
|
||||
|
||||
print(f" {Colors.DIM}Testing upload speed...{Colors.RESET}")
|
||||
st.upload(threads=None)
|
||||
|
||||
results = st.results.dict()
|
||||
|
||||
return {
|
||||
'download_mbps': round(results['download'] / 1_000_000, 2),
|
||||
'upload_mbps': round(results['upload'] / 1_000_000, 2),
|
||||
'ping_ms': round(results['ping']),
|
||||
'client': {
|
||||
'ip': results.get('client', {}).get('ip'),
|
||||
'isp': results.get('client', {}).get('isp'),
|
||||
'country': results.get('client', {}).get('country'),
|
||||
},
|
||||
'server': {
|
||||
'name': results.get('server', {}).get('name'),
|
||||
'country': results.get('server', {}).get('country'),
|
||||
'sponsor': results.get('server', {}).get('sponsor'),
|
||||
},
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {'error': f'Speed test failed: {str(e)}'}
|
||||
|
||||
def test_dns(self, domain: str = "google.com") -> dict:
|
||||
"""Test DNS resolution.
|
||||
|
||||
Args:
|
||||
domain: Domain to resolve.
|
||||
|
||||
Returns:
|
||||
Dict with DNS test results.
|
||||
"""
|
||||
import socket
|
||||
|
||||
print(f"{Colors.CYAN}[*] Testing DNS resolution...{Colors.RESET}")
|
||||
|
||||
results = {
|
||||
'domain': domain,
|
||||
'resolved': False,
|
||||
'addresses': [],
|
||||
}
|
||||
|
||||
try:
|
||||
start = time.time()
|
||||
addrs = socket.getaddrinfo(domain, 80)
|
||||
elapsed = round((time.time() - start) * 1000)
|
||||
|
||||
results['resolved'] = True
|
||||
results['time_ms'] = elapsed
|
||||
results['addresses'] = list(set(addr[4][0] for addr in addrs))
|
||||
|
||||
print(f" {Colors.GREEN}[+]{Colors.RESET} Resolved {domain} in {elapsed}ms")
|
||||
for addr in results['addresses'][:3]:
|
||||
print(f" {Colors.DIM}{addr}{Colors.RESET}")
|
||||
|
||||
except socket.gaierror as e:
|
||||
results['error'] = f"DNS resolution failed: {e}"
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} DNS resolution failed")
|
||||
|
||||
except Exception as e:
|
||||
results['error'] = str(e)
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} Error: {e}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def color_speed(value: float, thresholds: tuple) -> str:
|
||||
"""Color code speed values.
|
||||
|
||||
Args:
|
||||
value: Speed value.
|
||||
thresholds: (low, medium) thresholds.
|
||||
|
||||
Returns:
|
||||
Colored string.
|
||||
"""
|
||||
low, medium = thresholds
|
||||
if value < low:
|
||||
return f"{Colors.RED}{value}{Colors.RESET}"
|
||||
elif value < medium:
|
||||
return f"{Colors.YELLOW}{value}{Colors.RESET}"
|
||||
else:
|
||||
return f"{Colors.GREEN}{value}{Colors.RESET}"
|
||||
|
||||
|
||||
def display_speed_result(result: dict):
|
||||
"""Display speed test results nicely."""
|
||||
if 'error' in result:
|
||||
print(f"\n{Colors.RED}[X] {result['error']}{Colors.RESET}")
|
||||
return
|
||||
|
||||
print(f"\n{Colors.CYAN}{'=' * 50}{Colors.RESET}")
|
||||
print(f"{Colors.GREEN}{Colors.BOLD} NETWORK SPEED TEST RESULTS{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}{'=' * 50}{Colors.RESET}")
|
||||
|
||||
# Download speed (low < 5 Mbps, medium < 25 Mbps)
|
||||
download = result['download_mbps']
|
||||
download_colored = color_speed(download, (5, 25))
|
||||
print(f" {Colors.GREEN}Download:{Colors.RESET} {download_colored} Mbps")
|
||||
|
||||
# Upload speed (low < 2 Mbps, medium < 10 Mbps)
|
||||
upload = result['upload_mbps']
|
||||
upload_colored = color_speed(upload, (2, 10))
|
||||
print(f" {Colors.GREEN}Upload:{Colors.RESET} {upload_colored} Mbps")
|
||||
|
||||
# Ping (low > 100ms, medium > 50ms, inverted)
|
||||
ping = result['ping_ms']
|
||||
if ping > 100:
|
||||
ping_colored = f"{Colors.RED}{ping}{Colors.RESET}"
|
||||
elif ping > 50:
|
||||
ping_colored = f"{Colors.YELLOW}{ping}{Colors.RESET}"
|
||||
else:
|
||||
ping_colored = f"{Colors.GREEN}{ping}{Colors.RESET}"
|
||||
print(f" {Colors.GREEN}Ping:{Colors.RESET} {ping_colored} ms")
|
||||
|
||||
# Client info
|
||||
client = result.get('client', {})
|
||||
if client:
|
||||
print(f"\n {Colors.CYAN}Your Connection:{Colors.RESET}")
|
||||
if client.get('ip'):
|
||||
print(f" IP: {client['ip']}")
|
||||
if client.get('isp'):
|
||||
print(f" ISP: {client['isp']}")
|
||||
if client.get('country'):
|
||||
print(f" Country: {client['country']}")
|
||||
|
||||
# Server info
|
||||
server = result.get('server', {})
|
||||
if server:
|
||||
print(f"\n {Colors.CYAN}Test Server:{Colors.RESET}")
|
||||
if server.get('sponsor'):
|
||||
print(f" {server['sponsor']}")
|
||||
if server.get('name'):
|
||||
print(f" {server['name']}, {server.get('country', '')}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def display_menu():
|
||||
"""Display the network test module menu."""
|
||||
speedtest_status = f"{Colors.GREEN}Available{Colors.RESET}" if HAS_SPEEDTEST else f"{Colors.RED}Not installed{Colors.RESET}"
|
||||
|
||||
print(f"""
|
||||
{Colors.CYAN} Network Test{Colors.RESET}
|
||||
{Colors.DIM} Test network speed and connectivity{Colors.RESET}
|
||||
{Colors.DIM}{'─' * 50}{Colors.RESET}
|
||||
|
||||
{Colors.GREEN}[1]{Colors.RESET} Test Connectivity (ping websites)
|
||||
{Colors.GREEN}[2]{Colors.RESET} Full Speed Test [{speedtest_status}]
|
||||
{Colors.GREEN}[3]{Colors.RESET} Test DNS Resolution
|
||||
{Colors.GREEN}[4]{Colors.RESET} Run All Tests
|
||||
|
||||
{Colors.RED}[0]{Colors.RESET} Back
|
||||
""")
|
||||
|
||||
|
||||
def run():
|
||||
"""Main entry point for the module."""
|
||||
if not HAS_REQUESTS:
|
||||
print(f"{Colors.RED}[X] This module requires 'requests' library{Colors.RESET}")
|
||||
print(f"{Colors.DIM} Install with: pip install requests{Colors.RESET}")
|
||||
input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}")
|
||||
return
|
||||
|
||||
tester = NetworkTester()
|
||||
|
||||
while True:
|
||||
display_menu()
|
||||
choice = input(f"{Colors.GREEN}Select option: {Colors.RESET}").strip()
|
||||
|
||||
if choice == '0':
|
||||
break
|
||||
|
||||
elif choice == '1':
|
||||
results = tester.test_connectivity()
|
||||
if 'error' not in results:
|
||||
total = results['success_count'] + results['fail_count']
|
||||
print(f"\n{Colors.GREEN}[+] Connectivity: {results['success_count']}/{total} tests passed{Colors.RESET}")
|
||||
input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}")
|
||||
|
||||
elif choice == '2':
|
||||
if not HAS_SPEEDTEST:
|
||||
print(f"\n{Colors.RED}[X] speedtest-cli library not installed{Colors.RESET}")
|
||||
print(f"{Colors.DIM} Install with: pip install speedtest-cli{Colors.RESET}")
|
||||
else:
|
||||
results = tester.test_speed()
|
||||
display_speed_result(results)
|
||||
input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}")
|
||||
|
||||
elif choice == '3':
|
||||
print(f"\n{Colors.CYAN}Enter domain to resolve (default: google.com):{Colors.RESET}")
|
||||
domain = input(f"{Colors.GREEN}Domain: {Colors.RESET}").strip() or "google.com"
|
||||
tester.test_dns(domain)
|
||||
input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}")
|
||||
|
||||
elif choice == '4':
|
||||
print(f"\n{Colors.CYAN}{'=' * 50}{Colors.RESET}")
|
||||
print(f"{Colors.GREEN}{Colors.BOLD} RUNNING ALL NETWORK TESTS{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}{'=' * 50}{Colors.RESET}\n")
|
||||
|
||||
# Connectivity
|
||||
print(f"{Colors.BOLD}1. Connectivity Test{Colors.RESET}")
|
||||
conn_results = tester.test_connectivity()
|
||||
|
||||
# DNS
|
||||
print(f"\n{Colors.BOLD}2. DNS Resolution{Colors.RESET}")
|
||||
tester.test_dns()
|
||||
|
||||
# Speed test
|
||||
if HAS_SPEEDTEST:
|
||||
print(f"\n{Colors.BOLD}3. Speed Test{Colors.RESET}")
|
||||
speed_results = tester.test_speed()
|
||||
display_speed_result(speed_results)
|
||||
else:
|
||||
print(f"\n{Colors.BOLD}3. Speed Test{Colors.RESET}")
|
||||
print(f" {Colors.RED}[-]{Colors.RESET} Skipped (speedtest-cli not installed)")
|
||||
|
||||
input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}")
|
||||
|
||||
else:
|
||||
print(f"{Colors.RED}[!] Invalid option{Colors.RESET}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user