workbuddy.xpcool.com/hotspot-ipv6-test.ps1

105 lines
3.7 KiB
PowerShell

# ============================================================
# Hotspot IPv6 readiness test (pure ASCII -- safe to copy/paste)
#
# Purpose:
# 1) After connecting this laptop to a PHONE HOTSPOT,
# check whether the laptop receives a global IPv6 address.
# 2) Check whether the HOME host can be reached directly over IPv6.
#
# Output: Desktop\hotspot-ipv6-result.txt
# ============================================================
# --- change these two lines if the home IPv6 address changes ---
$HOME_V6 = '240e:338:263:3600:29f1:e63f:d476:597e'
$HOME_PORT = 38443
# ---------------------------------------------------------------
$desk = [Environment]::GetFolderPath('Desktop')
if (-not $desk) { $desk = $env:TEMP }
$o = Join-Path $desk 'hotspot-ipv6-result.txt'
$L = New-Object System.Collections.Generic.List[string]
function A($s) { $L.Add([string]$s) }
function Flush() { $L -join "`r`n" | Set-Content -Path $o -Encoding UTF8 }
$okOut = $false
$okHome = $false
A ('TIME ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))
A ('HOST ' + [System.Net.Dns]::GetHostName())
A ('RESULT FILE: ' + $o)
A ''
A '[1] Global IPv6 addresses on this machine'
$ga = @(Get-NetIPAddress -AddressFamily IPv6 -ErrorAction SilentlyContinue |
Where-Object { $_.IPAddress -notlike 'fe80*' -and $_.IPAddress -ne '::1' })
if ($ga.Count -eq 0) {
A ' NONE <-- this network gives NO global IPv6'
} else {
foreach ($a in $ga) {
A (" {0} :: {1}/{2} :: Pref={3} Suffix={4} State={5}" -f `
$a.InterfaceAlias, $a.IPAddress, $a.PrefixLength, `
$a.PrefixOrigin, $a.SuffixOrigin, $a.AddressState)
}
}
Flush
A ''
A '[2] IPv6 default route'
$r = @(Get-NetRoute -AddressFamily IPv6 -DestinationPrefix '::/0' -ErrorAction SilentlyContinue)
if ($r.Count -eq 0) { A ' NONE' } else {
foreach ($x in $r) { A (" {0} -> {1}" -f $x.InterfaceAlias, $x.NextHop) }
}
Flush
function Tcp6([string]$h, [int]$port, [int]$ms) {
try {
$a = @([System.Net.Dns]::GetHostAddresses($h) |
Where-Object { $_.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6 })
if ($a.Count -eq 0) { return 'NO-AAAA' }
$ad = $a[0]
$c = New-Object System.Net.Sockets.TcpClient($ad.AddressFamily)
$iar = $c.BeginConnect($ad, $port, $null, $null)
if (-not $iar.AsyncWaitHandle.WaitOne($ms, $false)) { $c.Close(); return 'TIMEOUT' }
try { $c.EndConnect($iar); $c.Close(); return ('OK ' + $ad.IPAddressToString) }
catch { $c.Close(); return ('FAIL ' + $_.Exception.Message) }
} catch { return ('ERR ' + $_.Exception.Message) }
}
A ''
A '[3] Outbound IPv6 test (decisive for the whole route)'
foreach ($h in @('ipv6.icanhazip.com', 'www.taobao.com')) {
$res = Tcp6 $h 443 4000
A (" {0}:443 -> {1}" -f $h, $res)
if ($res -like 'OK*') { $okOut = $true }
}
Flush
A ''
A '[4] Direct reach to HOME host over IPv6 (the real goal)'
$u = 'http://[' + $HOME_V6 + ']:' + $HOME_PORT + '/'
A (' target = ' + $u)
try {
$r2 = Invoke-WebRequest -Uri $u -UseBasicParsing -TimeoutSec 6
A (' HTTP status = ' + $r2.StatusCode)
A (' body line 1 = ' + (($r2.Content -split '\r?\n')[0]))
if ($r2.StatusCode -eq 200) { $okHome = $true }
} catch {
A (' FAILED: ' + $_.Exception.Message)
}
Flush
A ''
A '===== SUMMARY ====='
if ($okOut -and $okHome) {
A ' PASS: hotspot gives IPv6 AND home host is reachable.'
A ' -> The IPv6 direct route is viable from this laptop.'
} elseif ($okOut -and -not $okHome) {
A ' PARTIAL: IPv6 outbound OK, but home host unreachable.'
A ' -> Most likely the home gateway blocks inbound IPv6,'
A ' or the home IPv6 address/prefix has changed.'
} else {
A ' FAIL: no usable IPv6 outbound on this network.'
A ' -> The hotspot handed out no IPv6 (IPv6 sharing may be off).'
}
Flush