Last active
October 4, 2021 18:17
-
-
Save indented-automation/f059a269d55a1a3051e782ad1aba56d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-WhoIs { | |
<# | |
.SYNOPSIS | |
Get a WhoIs record using servers published via whois-servers.net. | |
.DESCRIPTION | |
For IP lookups, Get-WhoIs uses whois.arin.net as a starting point, chasing referrals within the record to get to an authoritative answer. | |
For name lookups, Get-WhoIs uses the whois-servers.net service to attempt to locate a whois server for the top level domain (TLD). | |
Get-WhoIs connects directly to whois servers using TCP/43. | |
.INPUTS | |
System.String | |
.EXAMPLE | |
Get-WhoIs indented.co.uk | |
.EXAMPLE | |
Get-WhoIs 10.0.0.1 | |
#> | |
[CmdletBinding()] | |
[OutputType([String])] | |
param ( | |
# The name or IP address to locate the WhoIs record for. | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[String]$Name, | |
# A WhoIs server to use for the query. Discovered, but can be overridden. | |
[String]$WhoIsServer, | |
# A command to execute on the WhoIs server if the server requires a command prefixing before the query. | |
[String]$Command | |
) | |
process { | |
if (-not $WhoIsServer) { | |
if ([IPAddress]::TryParse($Name, [Ref]$null) -or $Name.EndsWith("arpa")) { | |
$WhoIsServer = $whoIsServerName = "whois.arin.net" | |
$Command = "n " | |
} else { | |
$WhoIsServer = $whoIsServerName = '{0}.whois-servers.net' -f $Name.Split('.')[-1] | |
} | |
} | |
if (-not ([IPAddress]::TryParse($WhoIsServer, [Ref]$null))) { | |
$whoIsServerRecord = [System.Net.Dns]::GetHostEntry($WhoIsServer) | | |
Select-Object -Expand AddressList | | |
Select-Object -First 1 | |
$WhoIsServer = $whoIsServerRecord | |
} | |
if ($WhoIsServer) { | |
Write-Debug ('Get-WhoIs: Asking {0} ({1}) for {2} using command {3}{4}' -f $whoIsServerName, $WhoIsServer, $Name, $Command, $Name) | |
$socket = [System.Net.Sockets.Socket]::new('Stream', 'Tcp') | |
try { | |
$socket.Connect($WhoIsServer, 43) | |
} catch [System.Net.Sockets.SocketException] { | |
$errorRecord = [System.Management.Automation.ErrorRecord]::new( | |
[System.Net.Sockets.SocketException]::new($_.Exception.InnerException.NativeErrorCode), | |
'ConnectionFailed', | |
[System.Management.Automation.ErrorCategory]::ConnectionError, | |
$WhoIsServer | |
) | |
Write-Error -ErrorRecord $errorRecord | |
} | |
[Byte[]]$buffer = [System.Text.Encoding]::UTF8.GetBytes("$Command$Name`r`n") | |
$null = $socket.Send($buffer) | |
$receivedBytes = do { | |
$buffer = [Byte[]]::new(4096) | |
$receivedCount = $socket.Receive($buffer) | |
if ($receivedCount -gt 0) { | |
[Array]::Resize([Ref]$buffer, $receivedCount - 1) | |
$buffer | |
} | |
Write-Debug ('Get-WhoIs: Received {0} bytes from {1}' -f $receivedCount, $socket.RemoteEndPoint.Address) | |
} until ($receivedCount -eq 0) | |
$socket.Close() | |
$whoIsRecord = [System.Text.Encoding]::UTF8.GetString($receivedBytes) | |
if ($whoIsRecord -match 'ReferralServer: whois://(.+):') { | |
Write-Debug ('Get-WhoIs: Following referral for {0} to {1}' -f $Name, $matches[1]) | |
Get-WhoIs $Name -WhoIsServer $matches[1] | |
} else { | |
$whoIsRecord | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment