Private/Packet.ps1
|
function New-OspfPacketBytes { param( [Parameter(Mandatory)][int]$Type, [Parameter(Mandatory)][ipaddress]$RouterId, [ipaddress]$AreaId = '0.0.0.0', [byte[]]$Body = @(), [ValidateSet('None', 'Simple', 'Md5')][string]$AuthType = 'None', [string]$AuthKey = '', [int]$KeyId = 1, [long]$CryptoSequence = 0, [switch]$CorruptChecksum ) $total = 24 + $Body.Length $au = $script:AuthTypeNumbers[$AuthType] $pkt = [byte[]](Join-OspfBytes (ConvertTo-OspfBytes 2 1) (ConvertTo-OspfBytes $Type 1) (ConvertTo-OspfBytes $total 2) ` $RouterId.GetAddressBytes() $AreaId.GetAddressBytes() (ConvertTo-OspfBytes 0 2) (ConvertTo-OspfBytes $au 2) ` (ConvertTo-OspfBytes 0 8) $Body) switch ($AuthType) { 'None' { $ck = Get-InternetChecksum $pkt if ($CorruptChecksum) { $ck = $ck -bxor 0xFFFF } $pkt[12] = [byte]($ck -shr 8); $pkt[13] = [byte]($ck -band 0xFF) } 'Simple' { $ck = Get-InternetChecksum $pkt if ($CorruptChecksum) { $ck = $ck -bxor 0xFFFF } $pkt[12] = [byte]($ck -shr 8); $pkt[13] = [byte]($ck -band 0xFF) $kb = [System.Text.Encoding]::ASCII.GetBytes($AuthKey) for ($i = 0; $i -lt 8 -and $i -lt $kb.Length; $i++) { $pkt[16 + $i] = $kb[$i] } } 'Md5' { $pkt[18] = [byte]$KeyId $pkt[19] = 16 $sb = ConvertTo-OspfBytes $CryptoSequence 4 for ($i = 0; $i -lt 4; $i++) { $pkt[20 + $i] = $sb[$i] } $digest = Get-OspfMd5Digest -Packet $pkt -Key $AuthKey if ($CorruptChecksum) { $digest[0] = $digest[0] -bxor 0xFF } $pkt = [byte[]](Join-OspfBytes $pkt $digest) } } , $pkt } function Get-OspfMd5Digest { param([byte[]]$Packet, [string]$Key) $k = [byte[]]::new(16) $kb = [System.Text.Encoding]::ASCII.GetBytes($Key) for ($i = 0; $i -lt 16 -and $i -lt $kb.Length; $i++) { $k[$i] = $kb[$i] } , [byte[]][System.Security.Cryptography.MD5]::HashData([byte[]](Join-OspfBytes $Packet $k)) } function Test-OspfPacketChecksum { param([byte[]]$Data) if ($Data.Length -lt 24) { return $false } $len = [int](Get-OspfUInt $Data 2 2) if ($len -lt 24 -or $len -gt $Data.Length) { return $false } $copy = [byte[]]$Data[0..($len - 1)] $stored = Get-OspfUInt $copy 12 2 $copy[12] = 0; $copy[13] = 0 for ($i = 16; $i -lt 24; $i++) { $copy[$i] = 0 } (Get-InternetChecksum $copy) -eq $stored } function Test-OspfPacketAuth { param([byte[]]$Data, [string]$AuthKey) $au = [int](Get-OspfUInt $Data 14 2) $len = [int](Get-OspfUInt $Data 2 2) switch ($au) { 0 { return $true } 1 { $kb = [byte[]]::new(8) $ab = [System.Text.Encoding]::ASCII.GetBytes($AuthKey) for ($i = 0; $i -lt 8 -and $i -lt $ab.Length; $i++) { $kb[$i] = $ab[$i] } return ([System.Convert]::ToHexString($kb) -eq [System.Convert]::ToHexString([byte[]]$Data[16..23])) } 2 { if ($Data.Length -lt $len + 16) { return $false } $d = Get-OspfMd5Digest -Packet ([byte[]]$Data[0..($len - 1)]) -Key $AuthKey return ([System.Convert]::ToHexString($d) -eq [System.Convert]::ToHexString([byte[]]$Data[$len..($len + 15)])) } default { return $false } } } function Get-OspfHelloBody { param([ipaddress]$Mask, [int]$HelloInterval, [int]$Options, [int]$Priority, [long]$DeadInterval, [long]$Dr, [long]$Bdr, [long[]]$Neighbors = @()) $parts = @($Mask.GetAddressBytes(), (ConvertTo-OspfBytes $HelloInterval 2), (ConvertTo-OspfBytes $Options 1), (ConvertTo-OspfBytes $Priority 1), (ConvertTo-OspfBytes $DeadInterval 4), (ConvertTo-OspfBytes $Dr 4), (ConvertTo-OspfBytes $Bdr 4)) foreach ($n in $Neighbors) { $parts += , (ConvertTo-OspfBytes $n 4) } Join-OspfBytes @parts } function Get-OspfDbdBody { param([int]$InterfaceMtu, [int]$Options, [int]$Flags, [long]$Sequence, $Headers = @()) $l = [System.Collections.Generic.List[byte]]::new() $l.AddRange([byte[]](ConvertTo-OspfBytes $InterfaceMtu 2)) $l.AddRange([byte[]](ConvertTo-OspfBytes $Options 1)) $l.AddRange([byte[]](ConvertTo-OspfBytes $Flags 1)) $l.AddRange([byte[]](ConvertTo-OspfBytes $Sequence 4)) foreach ($h in (ConvertTo-OspfByteList $Headers)) { $l.AddRange([byte[]]$h[0..19]) } , $l.ToArray() } function Get-OspfLsrBody { param($Requests) $l = [System.Collections.Generic.List[byte]]::new() foreach ($r in $Requests) { $t = $r.Type if ($t -is [string]) { $t = $script:LsaTypeNumbers[$t] } $l.AddRange([byte[]](ConvertTo-OspfBytes $t 4)) $l.AddRange([byte[]]([ipaddress]$r.LinkStateId).GetAddressBytes()) $l.AddRange([byte[]]([ipaddress]$r.AdvertisingRouter).GetAddressBytes()) } , $l.ToArray() } function Get-OspfLsuBody { param($Lsas) $list = ConvertTo-OspfByteList $Lsas $l = [System.Collections.Generic.List[byte]]::new() $l.AddRange([byte[]](ConvertTo-OspfBytes $list.Count 4)) foreach ($x in $list) { $l.AddRange($x) } , $l.ToArray() } function Get-OspfLsAckBody { param($Headers) $l = [System.Collections.Generic.List[byte]]::new() foreach ($h in (ConvertTo-OspfByteList $Headers)) { $l.AddRange([byte[]]$h[0..19]) } , $l.ToArray() } |