docs: Update README and documentation for lxs multi-tool across Linux and Windows platforms.
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
<#
|
||||
LXS - Network Diagnostics (Windows)
|
||||
Description: Inspect and repair the network stack.
|
||||
Everything is read-only except option 8 (stack reset).
|
||||
Repo: https://git.hyko.cx/hykocx/lxs
|
||||
#>
|
||||
|
||||
# Load LXS common library (colors, UI helpers, spinner, loggers, guards).
|
||||
# Prefers the sibling ..\lib\common.ps1 (repo checkout or installed layout) and
|
||||
# only hits the network when this script is run standalone.
|
||||
$LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { 'https://git.hyko.cx/hykocx/lxs/raw/branch/main' }
|
||||
if (-not $env:LXS_RAW_PLATFORM_BASE) { $env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/windows" }
|
||||
$LxsLibPath = if ($PSScriptRoot) { Join-Path $PSScriptRoot '..\lib\common.ps1' } else { $null }
|
||||
if ($LxsLibPath -and (Test-Path $LxsLibPath)) {
|
||||
. $LxsLibPath
|
||||
} else {
|
||||
try {
|
||||
$LxsLibSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Error 'Failed to fetch lib/common.ps1'
|
||||
exit 1
|
||||
}
|
||||
. ([scriptblock]::Create($LxsLibSource))
|
||||
}
|
||||
|
||||
$env:LXS_LOG_FILE = Join-Path (Get-LxsTempDir) 'lxs_net_diag.log'
|
||||
|
||||
function Show-LxsIpConfiguration {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'IP CONFIGURATION'
|
||||
Write-Host ''
|
||||
try {
|
||||
Get-NetIPConfiguration -Detailed -ErrorAction Stop | ForEach-Object {
|
||||
Write-Host "$($script:Cyan)$($script:Bold)$($_.InterfaceAlias)$($script:NC) $($script:Gray)($($_.InterfaceDescription))$($script:NC)"
|
||||
Write-Host " Status : $($_.NetAdapter.Status) | MAC: $($_.NetAdapter.MacAddress) | Speed: $($_.NetAdapter.LinkSpeed)"
|
||||
Write-Host " IPv4 : $($_.IPv4Address.IPAddress -join ', ')"
|
||||
Write-Host " IPv6 : $($_.IPv6Address.IPAddress -join ', ')"
|
||||
Write-Host " Gateway : $($_.IPv4DefaultGateway.NextHop -join ', ')"
|
||||
Write-Host " DNS : $($_.DNSServer.ServerAddresses -join ', ')"
|
||||
Write-Host ''
|
||||
}
|
||||
} catch {
|
||||
Write-LxsWarn 'Get-NetIPConfiguration unavailable; falling back to ipconfig /all.'
|
||||
ipconfig /all | Out-String | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
function Show-LxsListeningPorts {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'LISTENING PORTS'
|
||||
Write-Host ''
|
||||
try {
|
||||
$rows = Get-NetTCPConnection -State Listen -ErrorAction Stop | ForEach-Object {
|
||||
$procName = try { (Get-Process -Id $_.OwningProcess -ErrorAction Stop).ProcessName } catch { 'unknown' }
|
||||
[pscustomobject]@{
|
||||
Local = "$($_.LocalAddress):$($_.LocalPort)"
|
||||
Port = $_.LocalPort
|
||||
PID = $_.OwningProcess
|
||||
Process = $procName
|
||||
}
|
||||
}
|
||||
$rows | Sort-Object Port | Format-Table -AutoSize Local, PID, Process | Out-String | Write-Host
|
||||
} catch {
|
||||
Write-LxsWarn 'Get-NetTCPConnection unavailable; falling back to netstat.'
|
||||
netstat -ano | Select-String 'LISTENING' | Out-String | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
function Clear-LxsDnsCache {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'FLUSH DNS CACHE'
|
||||
Write-Host ''
|
||||
try {
|
||||
Clear-DnsClientCache -ErrorAction Stop
|
||||
Write-LxsOk 'DNS resolver cache flushed'
|
||||
} catch {
|
||||
Write-LxsWarn 'Clear-DnsClientCache failed; falling back to ipconfig /flushdns.'
|
||||
ipconfig /flushdns | Out-String | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-LxsPing {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'PING'
|
||||
Write-Host ''
|
||||
$target = Read-Host -Prompt 'Host to ping (default: 1.1.1.1)'
|
||||
if ([string]::IsNullOrWhiteSpace($target)) { $target = '1.1.1.1' }
|
||||
Write-Host ''
|
||||
ping.exe -n 4 $target | Out-String | Write-Host
|
||||
}
|
||||
|
||||
function Invoke-LxsTraceroute {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'TRACEROUTE'
|
||||
Write-Host ''
|
||||
$target = Read-Host -Prompt 'Host to trace (default: 1.1.1.1)'
|
||||
if ([string]::IsNullOrWhiteSpace($target)) { $target = '1.1.1.1' }
|
||||
Write-Host ''
|
||||
Write-LxsInfo "Tracing route to $target (this can take a minute)..."
|
||||
tracert.exe -d -h 20 $target | Out-String | Write-Host
|
||||
}
|
||||
|
||||
function Test-LxsRemotePort {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'TEST TCP PORT'
|
||||
Write-Host ''
|
||||
$target = Read-Host -Prompt 'Host'
|
||||
if ([string]::IsNullOrWhiteSpace($target)) { Write-LxsErr 'No host given.'; return }
|
||||
$port = Read-Host -Prompt 'Port'
|
||||
if ($port -notmatch '^\d+$') { Write-LxsErr 'Port must be a number.'; return }
|
||||
Write-Host ''
|
||||
try {
|
||||
$result = Test-NetConnection -ComputerName $target -Port ([int]$port) -WarningAction SilentlyContinue -ErrorAction Stop
|
||||
if ($result.TcpTestSucceeded) {
|
||||
Write-LxsOk "${target}:${port} is reachable ($($result.RemoteAddress))"
|
||||
} else {
|
||||
Write-LxsErr "${target}:${port} is NOT reachable"
|
||||
}
|
||||
} catch {
|
||||
Write-LxsErr "Test failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Show-LxsPublicIp {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'PUBLIC IP'
|
||||
Write-Host ''
|
||||
Write-LxsInfo 'Querying...'
|
||||
Write-Host ''
|
||||
Write-Host " $($script:White)$($script:Bold)$(Get-LxsPublicIP)$($script:NC)"
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
function Reset-LxsNetworkStack {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'RESET NETWORK STACK' -Right 'DESTRUCTIVE'
|
||||
Write-Host ''
|
||||
Write-Host 'This resets the Winsock catalog and the TCP/IP stack. It clears'
|
||||
Write-Host 'third-party LSP entries, static IP settings and proxy configuration,'
|
||||
Write-Host "and $($script:Bold)requires a reboot$($script:NC) to take effect."
|
||||
Write-Host ''
|
||||
if (-not (Confirm-LxsAction -Question 'Reset the network stack now?')) {
|
||||
Write-LxsInfo 'Cancelled.'
|
||||
return
|
||||
}
|
||||
if (-not (Test-LxsAdmin)) {
|
||||
Write-LxsErr 'This action requires administrator rights. Re-run lxs from an elevated terminal.'
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
netsh winsock reset | Out-String | Write-Host
|
||||
netsh int ip reset | Out-String | Write-Host
|
||||
Clear-DnsClientCache -ErrorAction SilentlyContinue
|
||||
Write-Host ''
|
||||
Write-LxsOk 'Network stack reset'
|
||||
Write-LxsWarn 'Reboot required for the change to take effect.'
|
||||
}
|
||||
|
||||
function Show-LxsNetDiagMenu {
|
||||
while ($true) {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'NETWORK DIAG'
|
||||
Write-Host ''
|
||||
Show-LxsMenuItem '1' 'Show IP configuration'
|
||||
Show-LxsMenuItem '2' 'Show listening ports'
|
||||
Show-LxsMenuItem '3' 'Flush DNS cache'
|
||||
Show-LxsMenuItem '4' 'Ping a host'
|
||||
Show-LxsMenuItem '5' 'Traceroute a host'
|
||||
Show-LxsMenuItem '6' 'Test a TCP port'
|
||||
Show-LxsMenuItem '7' 'Show public IP'
|
||||
Show-LxsMenuItem '8' 'Reset network stack' 'needs admin + reboot'
|
||||
Show-LxsMenuItem '0' 'Back' '' -Exit
|
||||
Write-Host ''
|
||||
Show-LxsBoxBottom
|
||||
Write-Host ''
|
||||
$choice = Read-LxsChoice
|
||||
Write-Host ''
|
||||
|
||||
switch ($choice) {
|
||||
'1' { Show-LxsIpConfiguration; Read-LxsEnter }
|
||||
'2' { Show-LxsListeningPorts; Read-LxsEnter }
|
||||
'3' { Clear-LxsDnsCache; Read-LxsEnter }
|
||||
'4' { Invoke-LxsPing; Read-LxsEnter }
|
||||
'5' { Invoke-LxsTraceroute; Read-LxsEnter }
|
||||
'6' { Test-LxsRemotePort; Read-LxsEnter }
|
||||
'7' { Show-LxsPublicIp; Read-LxsEnter }
|
||||
'8' { Reset-LxsNetworkStack; Read-LxsEnter }
|
||||
'0' { return }
|
||||
default { Write-LxsErr 'Invalid protocol. Select 0-8.'; Start-Sleep -Seconds 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Assert-LxsWindows)) { exit 1 }
|
||||
Show-LxsNetDiagMenu
|
||||
exit 75
|
||||
Reference in New Issue
Block a user