Private/BgpHelpers.ps1
|
$script:BgpNotifyErrors = @{ 1 = 'Message Header Error'; 2 = 'OPEN Message Error'; 3 = 'UPDATE Message Error' 4 = 'Hold Timer Expired'; 5 = 'Finite State Machine Error'; 6 = 'Cease' } $script:BgpCapNames = @{ 1 = 'Multiprotocol Extensions'; 2 = 'Route Refresh'; 64 = 'Graceful Restart' 65 = '4-octet AS'; 69 = 'ADD-PATH'; 70 = 'Enhanced Route Refresh' } $script:BgpOrigins = @{ 0 = 'IGP'; 1 = 'EGP'; 2 = 'Incomplete' } function Get-BgpPeerGracefulRestart { param($PeerOpen) $cap = @($PeerOpen.Capabilities) | Where-Object Code -EQ 64 | Select-Object -First 1 if (-not $cap -or $cap.Value.Length -lt 4) { return $null } $flags = [Convert]::ToInt32($cap.Value.Substring(0, 4), 16) [pscustomobject]@{ RestartTime = $flags -band 0x0FFF; RestartFlag = [bool]($flags -band 0x8000) } } # Drops stale routes: all of a family after its End-of-RIB, everything once Restart Time has passed function Remove-BgpStaleRoute { param($State, [ValidateSet('IPv4', 'IPv6')][string]$Family) $dummy = $null $expired = $State.StaleExpires -and (Get-Date) -ge $State.StaleExpires foreach ($kv in @($State.Learned.GetEnumerator())) { if (-not $kv.Value.Stale) { continue } if ($expired -or ($Family -and (($kv.Key -match ':') -eq ($Family -eq 'IPv6')))) { $null = $State.Learned.TryRemove($kv.Key, [ref]$dummy) } } if (-not @($State.Learned.Values | Where-Object Stale)) { $State.StaleExpires = $null } } function Get-NetUInt { param([byte[]]$Bytes, [int]$Offset, [int]$Count) $v = [long]0 for ($i = 0; $i -lt $Count; $i++) { $v = $v * 256 + $Bytes[$Offset + $i] } $v } function Read-BgpPrefix { param([byte[]]$Bytes, [int]$Start, [int]$End, [int]$Afi = 1) $size = if ($Afi -eq 2) { 16 } else { 4 } $i = $Start while ($i -lt $End) { $len = $Bytes[$i] $n = [int][Math]::Ceiling($len / 8) if ($len -gt ($size * 8) -or ($i + 1 + $n) -gt $End) { throw 'Malformed prefix in UPDATE.' } $a = [byte[]]::new($size) for ($k = 0; $k -lt $n; $k++) { $a[$k] = $Bytes[$i + 1 + $k] } '{0}/{1}' -f ([ipaddress]::new($a)), $len $i += 1 + $n } } |