# Latency probe v2 (IPv6): UDP DNS RTT + ICMP RTT to 2606:4700:4700::1111, v4/v6 packet rates, plus NIC throughput, every ~200 ms. # Read-only. Stops when stop.flag appears next to this script. $dir = Split-Path -Parent $MyInvocation.MyCommand.Path $out = Join-Path $dir 'probe6.csv' $stop = Join-Path $dir 'stop.flag' if (Test-Path $stop) { Remove-Item $stop } 'ts,udp_ms,icmp_ms,tx_mbps,rx_mbps,v4_pps,v6_pps' | Out-File $out -Encoding ascii $nic = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Where-Object { $_.Name -eq 'Ethernet' } $ping = New-Object System.Net.NetworkInformation.Ping $udp = New-Object System.Net.Sockets.UdpClient([System.Net.Sockets.AddressFamily]::InterNetworkV6) $udp.Client.ReceiveTimeout = 1000 $udp.Connect([System.Net.IPAddress]::Parse('2606:4700:4700::1111'), 53) $q = [byte[]](0,0, 1,0, 0,1, 0,0, 0,0, 0,0, 7) + [Text.Encoding]::ASCII.GetBytes('example') + [byte[]](3) + [Text.Encoding]::ASCII.GetBytes('com') + [byte[]](0, 0,1, 0,1) $ep = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::IPv6Any, 0) $sw = New-Object System.Diagnostics.Stopwatch $gp = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties() $p4 = $gp.GetIPv4GlobalStatistics().ReceivedPackets + $gp.GetIPv4GlobalStatistics().OutputPacketRequests $p6 = $gp.GetIPv6GlobalStatistics().ReceivedPackets + $gp.GetIPv6GlobalStatistics().OutputPacketRequests $s0 = $nic.GetIPStatistics(); $t0 = [DateTime]::UtcNow $id = 0 while (-not (Test-Path $stop)) { $id = ($id + 1) % 65536; $q[0] = [byte]($id -shr 8); $q[1] = [byte]($id -band 255) $udpMs = -1 try { $sw.Restart(); [void]$udp.Send($q, $q.Length) do { $r = $udp.Receive([ref]$ep) } while ($r[0] -ne $q[0] -or $r[1] -ne $q[1]) $sw.Stop(); $udpMs = [math]::Round($sw.Elapsed.TotalMilliseconds, 1) } catch { $udpMs = -1 } $icmpMs = -1 try { $p = $ping.Send('2606:4700:4700::1111', 1000); if ($p.Status -eq 'Success') { $icmpMs = $p.RoundtripTime } } catch {} $s1 = $nic.GetIPStatistics(); $t1 = [DateTime]::UtcNow $dt = ($t1 - $t0).TotalSeconds $tx = [math]::Round(($s1.BytesSent - $s0.BytesSent) * 8 / 1e6 / $dt, 1) $rx = [math]::Round(($s1.BytesReceived - $s0.BytesReceived) * 8 / 1e6 / $dt, 1) $q4 = $gp.GetIPv4GlobalStatistics().ReceivedPackets + $gp.GetIPv4GlobalStatistics().OutputPacketRequests $q6 = $gp.GetIPv6GlobalStatistics().ReceivedPackets + $gp.GetIPv6GlobalStatistics().OutputPacketRequests $v4 = [math]::Round(($q4 - $p4) / $dt); $v6 = [math]::Round(($q6 - $p6) / $dt); $p4 = $q4; $p6 = $q6 $s0 = $s1; $t0 = $t1 "{0},{1},{2},{3},{4},{5},{6}" -f (Get-Date -Format 'HH:mm:ss.fff'), $udpMs, $icmpMs, $tx, $rx, $v4, $v6 | Out-File $out -Append -Encoding ascii $wait = 200 - [int]$sw.Elapsed.TotalMilliseconds if ($wait -gt 0) { Start-Sleep -Milliseconds $wait } } $udp.Close()