Private/IPAX-IPv4Math.ps1
function Convert-V4DottedToInt { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidatePattern('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}')] [string]$InputString ) $power = 3 $value = 0 $InputString.Split('.').ForEach({ $value += ([int]$_ * [math]::Pow(256,$power)); $power = $power - 1}) $value } function Convert-IntToV4Dotted { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidateRange(0,4294967295)] [int64]$InputValue ) $binval = ([convert]::ToString($InputValue,2)).PadLeft(32,'0') $valbytes = @() (0..3).ForEach({$valbytes += ([convert]::ToByte($binval.Substring($_ * 8,8),2)).ToString()}) $valbytes -join '.' } function Get-IPAX4SubnetMask { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidateRange(1,32)] [int]$SubnetMaskLength ) $binmask = '1' * $SubnetMaskLength + '0' * (32 - $SubnetMaskLength) $maskbytes = @() (0..3).ForEach({$maskbytes += ([convert]::ToByte($binmask.Substring($_ * 8,8),2)).ToString()}) $maskbytes -join '.' } function Get-IPAX4SubnetMaskLength { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidatePattern('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}')] [string]$SubnetMask ) if (Test-IPAX4SubnetMask -SubnetMask $SubnetMask) { $mask = Convert-V4DottedToInt -InputString $SubnetMask $binmask = [convert]::ToString($mask,2) $binmask.Trim('0').Length } else { 0 } } function Test-IPAX4SubnetMask { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidatePattern('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}')] [string]$SubnetMask ) $mask = Convert-V4DottedToInt -InputString $SubnetMask $binmask = [convert]::ToString($mask,2) if ($binmask -match '^1+0*$') { $true } else { $false } } function Get-IPAX4Classification { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidatePattern('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}')] [string]$IPAddress ) $addressValue = Convert-V4DottedToInt $IPAddress $addressClassification = 'Public' # initial list from https://ipinfo.io/bogon if ($addressValue -eq 4294967295) { # 255.255.255.255 $addressClassification = 'Limited Broadcast' } elseif ($addressValue -ge 4026531840) { # 240.0.0.0/4 $addressClassification = 'Reserved for future use' } elseif ($addressValue -ge 3758096384) { # 224.0.0.0/4 $addressClassification = 'Multicast' } elseif (($addressValue -ge 3405803776) -and ($addressValue -le 3405804030)) { # 203.0.113.0/24 $addressClassification = 'TEST-NET-3' } elseif (($addressValue -ge 3325256704) -and ($addressValue -le 3325256958)) { # 192.51.100.0/24 $addressClassification = 'TEST-NET-2' } elseif (($addressValue -ge 3323068416) -and ($addressValue -le 3323199487)) { # 192.18.0.0/15 $addressClassification = 'Network interconnect device benchmark testing' } elseif (($addressValue -ge 3232235520) -and ($addressValue -le 3232301055)) { # 192.168.0.0/16 $addressClassification = 'Private' } elseif (($addressValue -ge 3221225984) -and ($addressValue -le 3221226239)) { # 192.0.2.0/24 $addressClassification = 'TEST-NET-1' } elseif (($addressValue -ge 3221225472) -and ($addressValue -le 3221225727)) { # 192.0.0.0/24 $addressClassification = 'IETF protocol assignments' } elseif (($addressValue -ge 2886729728) -and ($addressValue -le 2886795263)) { # 172.16.0.0/12 $addressClassification = 'Private' } elseif (($addressValue -ge 2851995648) -and ($addressValue -le 2852061183)) { # 169.254.0.0/16 $addressClassification = 'Link-Local' } elseif ($addressValue -eq 2130720053) { # 127.0.53.53 $addressClassification = 'Name collision occurrence' } elseif (($addressValue -ge 2130706432) -and ($addressValue -le 2147483647)) { # 127.0.0.0/8 $addressClassification = 'Loopback' } elseif (($addressValue -ge 171966464) -and ($addressValue -le 176160767)) { # 100.64.0.0/10 $addressClassification = 'Carrier-grade NAT' } elseif (($addressValue -ge 167772160) -and ($addressValue -le 184549375)) { # 10.0.0.0/8 $addressClassification = 'Private' } elseif ($addressValue -le 16777215) { # 0.0.0.0/8 $addressClassification = 'This network' } return $addressClassification } |