UNPKG

wifi-radar

Version:

Comprehensive WiFi network analysis & performance testing tool for macOS - speed tests, latency analysis, health diagnostics, QoS analysis & more

595 lines 26.6 kB
#!/usr/bin/env node import { Command } from 'commander'; import chalk from 'chalk'; import figlet from 'figlet'; import ora from 'ora'; import boxen from 'boxen'; import Table from 'cli-table3'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { WiFiScanner } from './scanner.js'; import { TopologyMapper } from './topology.js'; import { SecurityAuditor } from './security.js'; import { SignalAnalyzer } from './analyzer.js'; import { Dashboard } from './dashboard.js'; import { NetworkTester } from './network-tester.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8')); const program = new Command(); const scanner = new WiFiScanner(); const topology = new TopologyMapper(); const security = new SecurityAuditor(); const analyzer = new SignalAnalyzer(); const dashboard = new Dashboard(); const networkTester = new NetworkTester(); function showBanner() { console.log(chalk.cyan(figlet.textSync('WiFi Radar', { font: 'Small', horizontalLayout: 'fitted' }))); console.log(chalk.gray('The Ultimate Network Analysis & Performance Testing Tool')); console.log(''); } program .name('wifi-radar') .description('Comprehensive WiFi network scanner and performance testing tool for macOS') .version(packageJson.version); program .command('scan') .description('Scan for nearby WiFi networks') .option('-v, --verbose', 'Show detailed information') .action(async (options) => { showBanner(); const spinner = ora('Scanning for WiFi networks...').start(); try { const networks = await scanner.scanNetworks(); spinner.succeed(`Found ${networks.length} networks`); if (networks.length === 0) { console.log(chalk.yellow('No networks found. Make sure WiFi is enabled.')); return; } const table = new Table({ head: ['SSID', 'Signal', 'Channel', 'Frequency', 'Security', 'Connected'], colWidths: [20, 12, 10, 12, 20, 12] }); networks .sort((a, b) => b.signal - a.signal) .forEach(network => { const signalColor = network.signal >= -50 ? chalk.green : network.signal >= -70 ? chalk.yellow : chalk.red; const connectedIcon = network.isConnected ? chalk.green('✓') : ''; const frequency = network.frequency < 3000 ? '2.4 GHz' : '5 GHz'; table.push([ network.ssid, signalColor(`${network.signal} dBm`), network.channel.toString(), frequency, network.security.join(', '), connectedIcon ]); }); console.log(table.toString()); if (options.verbose) { console.log('\n' + chalk.bold('Detailed Information:')); networks.forEach(network => { const snr = network.signal - network.noise; console.log(boxen(`SSID: ${network.ssid}\n` + `BSSID: ${network.bssid}\n` + `Channel: ${network.channel} (${network.frequency} MHz)\n` + `Signal: ${network.signal} dBm\n` + `Noise: ${network.noise} dBm\n` + `SNR: ${snr} dB\n` + `Security: ${network.security.join(', ')}\n` + `PHY Mode: ${network.phyMode}\n` + `Network Type: ${network.networkType}\n` + `Country: ${network.countryCode}`, { title: network.isConnected ? chalk.green('✓ Connected') : 'Available', padding: 1, margin: 1, borderStyle: 'round' })); }); } } catch (error) { spinner.fail('Failed to scan networks'); console.error(chalk.red('Error:'), error); } }); program .command('speed') .description('Run comprehensive internet speed test') .option('-s, --size <size>', 'Test size: small, medium, large', 'medium') .action(async (options) => { showBanner(); console.log(chalk.blue.bold('🚀 COMPREHENSIVE SPEED TEST')); console.log(chalk.gray('Testing download, upload, latency, and jitter...')); console.log(''); try { const result = await networkTester.runSpeedTest(options.size); console.log(chalk.green.bold('📊 SPEED TEST RESULTS')); console.log(chalk.gray('─'.repeat(50))); const downloadColor = result.download.speed >= 25 ? chalk.green : result.download.speed >= 5 ? chalk.yellow : chalk.red; const uploadColor = result.upload.speed >= 10 ? chalk.green : result.upload.speed >= 3 ? chalk.yellow : chalk.red; const latencyColor = result.ping.latency <= 50 ? chalk.green : result.ping.latency <= 100 ? chalk.yellow : chalk.red; console.log(`📥 Download: ${downloadColor.bold(result.download.speed + ' Mbps')}`); console.log(`📤 Upload: ${uploadColor.bold(result.upload.speed + ' Mbps')}`); console.log(`🏓 Latency: ${latencyColor.bold(result.ping.latency + ' ms')}`); console.log(`📊 Jitter: ${result.ping.jitter.toFixed(2)} ms`); console.log(`📉 Loss: ${result.ping.packetLoss.toFixed(1)}%`); console.log(''); console.log(chalk.gray(`Server: ${result.server.name}`)); console.log(chalk.gray(`ISP: ${result.isp}`)); console.log(chalk.gray(`Public IP: ${result.publicIP}`)); console.log(chalk.gray(`Timestamp: ${result.timestamp.toLocaleString()}`)); // Performance rating const rating = getSpeedRating(result.download.speed, result.ping.latency); console.log(''); console.log(chalk.blue.bold('📈 PERFORMANCE RATING')); console.log(getRatingDisplay(rating)); } catch (error) { console.error(chalk.red('Speed test failed:'), error); } }); program .command('ping') .description('Test network latency and jitter') .option('-h, --host <host>', 'Target host', '8.8.8.8') .option('-c, --count <count>', 'Number of ping packets', '10') .action(async (options) => { showBanner(); const count = parseInt(options.count); const spinner = ora(`Testing latency to ${options.host} (${count} packets)...`).start(); try { const result = await networkTester.testLatency(options.host, count); spinner.succeed('Latency test completed'); console.log(chalk.blue.bold(`🏓 LATENCY TEST RESULTS - ${options.host}`)); console.log(chalk.gray('─'.repeat(50))); const avgColor = result.avg <= 50 ? chalk.green : result.avg <= 100 ? chalk.yellow : chalk.red; const jitterColor = result.jitter <= 10 ? chalk.green : result.jitter <= 20 ? chalk.yellow : chalk.red; console.log(chalk.white(`📊 Statistics:`)); console.log(` Min: ${result.min} ms`); console.log(` Max: ${result.max} ms`); console.log(` Average: ${avgColor.bold(result.avg + ' ms')}`); console.log(` Jitter: ${jitterColor.bold(result.jitter.toFixed(2) + ' ms')}`); console.log(` Loss: ${result.loss}%`); console.log(''); if (result.times.length > 0) { console.log(chalk.white('📈 Individual Times:')); const timeDisplay = result.times.map((time, i) => `${i + 1}: ${time}ms`).join(' '); console.log(` ${timeDisplay}`); } // Quality assessment const quality = getLatencyQuality(result.avg, result.jitter, result.loss); console.log(''); console.log(chalk.blue.bold('🎯 CONNECTION QUALITY')); console.log(getQualityDisplay(quality)); } catch (error) { spinner.fail('Latency test failed'); console.error(chalk.red('Error:'), error); } }); program .command('diagnostics') .description('Run comprehensive network diagnostics') .action(async () => { showBanner(); try { const diagnostics = await networkTester.runNetworkDiagnostics(); console.log(chalk.blue.bold('🔍 NETWORK DIAGNOSTICS REPORT')); console.log(chalk.gray('═'.repeat(60))); console.log(''); // Interface Information console.log(chalk.green.bold('🌐 NETWORK INTERFACE')); console.log(`Interface: ${diagnostics.interface.name}`); console.log(`IP Address: ${diagnostics.interface.ip}`); console.log(`MAC Address: ${diagnostics.interface.mac}`); console.log(`MTU: ${diagnostics.interface.mtu}`); console.log(`Status: ${diagnostics.interface.status === 'up' ? chalk.green('UP') : chalk.red('DOWN')}`); console.log(''); // Connectivity Tests console.log(chalk.cyan.bold('🔗 CONNECTIVITY TESTS')); console.log(`Internet: ${diagnostics.connectivity.internet ? chalk.green('✓ Connected') : chalk.red('✗ Failed')}`); console.log(`Gateway: ${diagnostics.connectivity.gateway ? chalk.green('✓ Reachable') : chalk.red('✗ Unreachable')}`); console.log(`Local Network: ${diagnostics.connectivity.localNetwork ? chalk.green('✓ Connected') : chalk.red('✗ Failed')}`); console.log(`DNS: ${diagnostics.connectivity.dns ? chalk.green('✓ Working') : chalk.red('✗ Failed')}`); console.log(''); // DNS Information console.log(chalk.magenta.bold('🔍 DNS CONFIGURATION')); console.log(`DNS Servers: ${diagnostics.dns.servers.join(', ')}`); console.log('DNS Resolution Tests:'); diagnostics.dns.resolution.forEach(test => { const status = test.resolved ? chalk.green(`✓ ${test.time}ms`) : chalk.red('✗ Failed'); console.log(` ${test.domain}: ${status}${test.ip ? ` → ${test.ip}` : ''}`); }); console.log(''); // Routing Information console.log(chalk.yellow.bold('🛤️ ROUTING INFORMATION')); console.log(`Default Gateway: ${diagnostics.routing.gateway}`); if (diagnostics.routing.routes.length > 0) { console.log('Routes:'); diagnostics.routing.routes.slice(0, 5).forEach(route => { console.log(` ${route.destination}${route.gateway} (${route.interface})`); }); } console.log(''); // Performance Summary console.log(chalk.red.bold('⚡ PERFORMANCE SUMMARY')); const latency = diagnostics.performance.latency; const latencyColor = latency.avg <= 50 ? chalk.green : latency.avg <= 100 ? chalk.yellow : chalk.red; console.log(`Latency: ${latencyColor.bold(latency.avg + ' ms')} (jitter: ${latency.jitter.toFixed(1)}ms)`); if (diagnostics.performance.bandwidth.download > 0) { console.log(`Bandwidth: ${diagnostics.performance.bandwidth.download} Mbps`); } } catch (error) { console.error(chalk.red('Diagnostics failed:'), error); } }); program .command('health') .description('Analyze overall WiFi network health') .action(async () => { showBanner(); const spinner = ora('Analyzing WiFi network health...').start(); try { const networks = await scanner.scanNetworks(); const currentNetwork = networks.find(n => n.isConnected); if (!currentNetwork) { spinner.fail('No connected network found'); console.log(chalk.yellow('Please connect to a WiFi network first.')); return; } const health = await networkTester.analyzeWiFiHealth(networks, currentNetwork); spinner.succeed('WiFi health analysis completed'); console.log(chalk.blue.bold('🏥 WIFI HEALTH REPORT')); console.log(chalk.gray('═'.repeat(50))); console.log(''); // Overall Health const overallColor = getHealthColor(health.overall); console.log(chalk.white.bold('📊 OVERALL HEALTH')); console.log(` Status: ${overallColor.bold(health.overall.toUpperCase())}`); console.log(''); // Signal Analysis console.log(chalk.green.bold('📶 SIGNAL ANALYSIS')); console.log(` Strength: ${health.signal.strength} dBm (${getSignalQualityDisplay(health.signal.quality)})`); console.log(` Quality: ${getQualityColorDisplay(health.signal.quality)}`); console.log(` Stability: ${health.signal.stability === 'stable' ? chalk.green('Stable') : chalk.yellow('Unstable')}`); console.log(''); // Speed Analysis console.log(chalk.cyan.bold('🚀 SPEED ANALYSIS')); console.log(` Download: ${health.speed.download} Mbps (${getQualityColorDisplay(health.speed.rating)})`); console.log(` Upload: ${health.speed.upload} Mbps`); console.log(''); // Latency Analysis console.log(chalk.yellow.bold('🏓 LATENCY ANALYSIS')); console.log(` Ping: ${health.latency.ping} ms (${getQualityColorDisplay(health.latency.rating)})`); console.log(` Jitter: ${health.latency.jitter} ms`); console.log(''); // Congestion Analysis console.log(chalk.magenta.bold('📊 CONGESTION ANALYSIS')); const congestionColor = health.congestion.level === 'low' ? chalk.green : health.congestion.level === 'medium' ? chalk.yellow : chalk.red; console.log(` Level: ${congestionColor.bold(health.congestion.level.toUpperCase())}`); console.log(` Channel Utilization: ${health.congestion.channelUtilization}%`); console.log(''); // Security Analysis console.log(chalk.red.bold('🔒 SECURITY ANALYSIS')); const securityColor = health.security.level === 'secure' ? chalk.green : health.security.level === 'warning' ? chalk.yellow : chalk.red; console.log(` Level: ${securityColor.bold(health.security.level.toUpperCase())}`); if (health.security.issues.length > 0) { console.log(' Issues:'); health.security.issues.forEach(issue => { console.log(chalk.red(` • ${issue}`)); }); } console.log(''); // Recommendations if (health.recommendations.length > 0) { console.log(chalk.blue.bold('💡 RECOMMENDATIONS')); health.recommendations.forEach(rec => { console.log(chalk.blue(`• ${rec}`)); }); console.log(''); } } catch (error) { spinner.fail('Health analysis failed'); console.error(chalk.red('Error:'), error); } }); program .command('qos') .description('Analyze Quality of Service for different applications') .action(async () => { showBanner(); const spinner = ora('Analyzing Quality of Service...').start(); try { const qos = await networkTester.calculateQualityOfService(); spinner.succeed('QoS analysis completed'); console.log(chalk.blue.bold('🎯 QUALITY OF SERVICE ANALYSIS')); console.log(chalk.gray('═'.repeat(50))); console.log(''); // Overall Classification const classColor = getQualityColor(qos.classification); console.log(chalk.white.bold('📊 OVERALL CLASSIFICATION')); console.log(` ${classColor.bold(qos.classification.toUpperCase())}`); console.log(''); // Network Metrics console.log(chalk.cyan.bold('📈 NETWORK METRICS')); console.log(` Latency: ${qos.metrics.latency} ms`); console.log(` Jitter: ${qos.metrics.jitter.toFixed(2)} ms`); console.log(` Packet Loss: ${qos.metrics.packetLoss.toFixed(1)}%`); console.log(` Throughput: ${qos.metrics.throughput} Mbps`); console.log(''); // Application Performance console.log(chalk.green.bold('🎮 APPLICATION PERFORMANCE')); console.log(` 📹 Video Streaming: ${getQualityColorDisplay(qos.applications.video)}`); console.log(` 📞 Voice Calls: ${getQualityColorDisplay(qos.applications.voice)}`); console.log(` 🎯 Gaming: ${getQualityColorDisplay(qos.applications.gaming)}`); console.log(` 🌐 Web Browsing: ${getQualityColorDisplay(qos.applications.browsing)}`); } catch (error) { spinner.fail('QoS analysis failed'); console.error(chalk.red('Error:'), error); } }); program .command('topology') .description('Show network topology map') .option('-i, --interactive', 'Show interactive topology map') .action(async (options) => { showBanner(); const spinner = ora('Mapping network topology...').start(); try { const [networks, devices] = await Promise.all([ scanner.scanNetworks(), scanner.scanDevices() ]); spinner.succeed('Network topology mapped'); const networkTopology = topology.generateTopology(networks, devices); if (options.interactive) { console.log(topology.renderInteractiveMap(networkTopology)); } else { console.log(topology.renderTopologyASCII(networkTopology)); } } catch (error) { spinner.fail('Failed to map topology'); console.error(chalk.red('Error:'), error); } }); program .command('devices') .description('Identify connected devices') .action(async () => { showBanner(); const spinner = ora('Scanning for connected devices...').start(); try { const devices = await scanner.scanDevices(); spinner.succeed(`Found ${devices.length} connected devices`); if (devices.length === 0) { console.log(chalk.yellow('No connected devices found.')); return; } const table = new Table({ head: ['Device', 'IP Address', 'MAC Address', 'Vendor', 'Type'], colWidths: [20, 15, 18, 15, 10] }); devices.forEach(device => { const deviceIcon = topology['getDeviceIcon'](device.deviceType); table.push([ `${deviceIcon} ${device.hostname || 'Unknown'}`, device.ip || 'Unknown', device.mac, device.vendor || 'Unknown', device.deviceType || 'unknown' ]); }); console.log(table.toString()); } catch (error) { spinner.fail('Failed to scan devices'); console.error(chalk.red('Error:'), error); } }); program .command('signal') .description('Analyze signal strength and quality') .action(async () => { showBanner(); const spinner = ora('Analyzing signal quality...').start(); try { const networks = await scanner.scanNetworks(); const analysis = await analyzer.analyzeSignal(networks); spinner.succeed('Signal analysis complete'); console.log(analyzer.renderSignalAnalysis(analysis)); } catch (error) { spinner.fail('Failed to analyze signal'); console.error(chalk.red('Error:'), error); } }); program .command('security') .description('Perform security audit') .action(async () => { showBanner(); const spinner = ora('Running security audit...').start(); try { const networks = await scanner.scanNetworks(); const audits = await security.auditNetworks(networks); spinner.succeed('Security audit complete'); console.log(security.renderSecurityReport(audits)); } catch (error) { spinner.fail('Failed to run security audit'); console.error(chalk.red('Error:'), error); } }); program .command('dashboard') .description('Launch interactive real-time dashboard') .action(async () => { showBanner(); console.log(chalk.yellow('Launching interactive dashboard...')); console.log(chalk.gray('Press Ctrl+C to exit')); console.log(''); try { await dashboard.start(); } catch (error) { console.error(chalk.red('Dashboard error:'), error); } }); program .command('help-extended') .description('Show comprehensive help with all available features') .action(() => { showBanner(); console.log(chalk.blue.bold('🚀 WIFI RADAR - COMPREHENSIVE NETWORK ANALYSIS TOOL')); console.log(chalk.gray('═'.repeat(70))); console.log(''); console.log(chalk.green.bold('📊 NETWORK SCANNING & ANALYSIS')); console.log(chalk.cyan(' scan ') + 'Scan for nearby WiFi networks with detailed info'); console.log(chalk.cyan(' signal ') + 'Analyze signal strength and quality'); console.log(chalk.cyan(' devices ') + 'Identify all connected devices on network'); console.log(chalk.cyan(' topology ') + 'Generate network topology map'); console.log(''); console.log(chalk.green.bold('⚡ PERFORMANCE TESTING')); console.log(chalk.cyan(' speed ') + 'Run comprehensive internet speed test'); console.log(chalk.cyan(' ping ') + 'Test network latency and jitter analysis'); console.log(chalk.cyan(' diagnostics ') + 'Complete network diagnostics report'); console.log(''); console.log(chalk.green.bold('🏥 HEALTH & QUALITY ANALYSIS')); console.log(chalk.cyan(' health ') + 'Comprehensive WiFi network health analysis'); console.log(chalk.cyan(' qos ') + 'Quality of Service for different applications'); console.log(''); console.log(chalk.green.bold('🔒 SECURITY AUDITING')); console.log(chalk.cyan(' security ') + 'Perform comprehensive security audit'); console.log(''); console.log(chalk.green.bold('📱 LIVE MONITORING')); console.log(chalk.cyan(' dashboard ') + 'Launch real-time interactive dashboard'); console.log(''); console.log(chalk.yellow.bold('🎯 EXAMPLE USAGE')); console.log(chalk.white(' wifi-radar scan -v ') + chalk.gray('# Detailed network scan')); console.log(chalk.white(' wifi-radar speed --size large ') + chalk.gray('# Large speed test')); console.log(chalk.white(' wifi-radar ping -h 1.1.1.1 -c 20') + chalk.gray('# Test Cloudflare DNS')); console.log(chalk.white(' wifi-radar health ') + chalk.gray('# Complete health analysis')); console.log(chalk.white(' wifi-radar diagnostics ') + chalk.gray('# Network troubleshooting')); console.log(chalk.white(' wifi-radar qos ') + chalk.gray('# Check app performance')); console.log(chalk.white(' wifi-radar dashboard ') + chalk.gray('# Live monitoring')); console.log(''); console.log(chalk.magenta.bold('✨ KEY FEATURES')); console.log(chalk.white('• Real-time network monitoring and analysis')); console.log(chalk.white('• Internet speed testing (download/upload/latency/jitter)')); console.log(chalk.white('• Device discovery and identification')); console.log(chalk.white('• Signal quality and interference analysis')); console.log(chalk.white('• Security vulnerability assessment')); console.log(chalk.white('• Network performance diagnostics')); console.log(chalk.white('• Quality of Service analysis for different apps')); console.log(chalk.white('• Interactive topology mapping')); console.log(chalk.white('• WiFi health scoring and recommendations')); console.log(''); console.log(chalk.red.bold('💡 PRO TIPS')); console.log(chalk.yellow('• Run "health" command first for overall network status')); console.log(chalk.yellow('• Use "diagnostics" for troubleshooting connection issues')); console.log(chalk.yellow('• "qos" helps determine if network is suitable for specific apps')); console.log(chalk.yellow('• "dashboard" provides continuous monitoring')); console.log(chalk.yellow('• Regular "security" audits help maintain network safety')); }); // Utility functions for display formatting function getSpeedRating(downloadSpeed, latency) { if (downloadSpeed >= 100 && latency <= 20) return 'excellent'; if (downloadSpeed >= 25 && latency <= 50) return 'good'; if (downloadSpeed >= 5 && latency <= 100) return 'fair'; return 'poor'; } function getLatencyQuality(avg, jitter, loss) { if (avg <= 20 && jitter <= 5 && loss <= 0.1) return 'excellent'; if (avg <= 50 && jitter <= 10 && loss <= 1) return 'good'; if (avg <= 100 && jitter <= 20 && loss <= 3) return 'fair'; return 'poor'; } function getRatingDisplay(rating) { const colors = { excellent: chalk.green, good: chalk.blue, fair: chalk.yellow, poor: chalk.red }; const bars = { excellent: '▰▰▰▰▰', good: '▰▰▰▰▱', fair: '▰▰▱▱▱', poor: '▰▱▱▱▱' }; const color = colors[rating] || chalk.gray; const bar = bars[rating] || '▱▱▱▱▱'; return `${color(bar)} ${color.bold(rating.toUpperCase())}`; } function getQualityDisplay(quality) { return getRatingDisplay(quality); } function getHealthColor(health) { const colors = { excellent: chalk.green, good: chalk.blue, fair: chalk.yellow, poor: chalk.red, critical: chalk.red }; return colors[health] || chalk.gray; } function getQualityColor(quality) { const colors = { excellent: chalk.green, good: chalk.blue, fair: chalk.yellow, poor: chalk.red, unusable: chalk.red }; return colors[quality] || chalk.gray; } function getSignalQualityDisplay(quality) { const displays = { excellent: chalk.green('Excellent'), good: chalk.blue('Good'), fair: chalk.yellow('Fair'), poor: chalk.red('Poor') }; return displays[quality] || chalk.gray('Unknown'); } function getQualityColorDisplay(quality) { const color = getQualityColor(quality); return color.bold(quality.toUpperCase()); } // Handle uncaught errors process.on('uncaughtException', (error) => { console.error(chalk.red('Uncaught error:'), error); process.exit(1); }); process.on('unhandledRejection', (error) => { console.error(chalk.red('Unhandled rejection:'), error); process.exit(1); }); program.parse(); //# sourceMappingURL=cli.js.map