Testing TCP Ports with a Possible Header Response

I wrote a function a while back as a quick means to not only check for an open port, but also to see if a header is sent back on the initial connection. The reasoning behind this was to help troubleshoot an ESXi host by looking at port 902, which would return a header response if a connection was made. Typically this would be done using the Telnet client, but this is not installed by default. Enter PowerShell to provide a better solution to this issue.

Rather than dive into everything that I have done previously, I will direct you to the following blog that I wrote on scanning ports.

The part that I really haven’t talked much about is what to do if there is a response back from the server. First I will make the connection and if there is data available, begin processing it.

$Computer='DC1'
$_Port=21
$stringBuilder = New-Object Text.StringBuilder
$tcpClient = New-Object System.Net.Sockets.TCPClient
$connect = $tcpClient.BeginConnect($Computer,$_port,$null,$null) 
$wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout,$false) 
Write-Verbose "Bytes available: $($tcpClient.Available)" -Verbose

SNAGHTML66ef46d1

Looks like I have 27 bytes of some data awaiting me at this point in time, but there could be more depending on how much is buffering (there will  actually be 127 bytes in this example).

The first thing that I need to do is connect to the Stream using GetStream(). Once I have that, I want to make sure that I create a byte buffer which is  large enough to hold the data stream.

$stream = $TcpClient.GetStream()
$bindResponseBuffer = New-Object Byte[] -ArgumentList $tcpClient.Available

If I look at the $bindResponseBuffer, it will be nothing but 0s. This is because I have not added anything to it just yet, it is just an empty buffer. To make better use of this buffer, I will begin reading the data via the stream. This is done using the Read() method of the stream object and giving my empty buffer, setting the starting location to the beginning of the stream (0) and then lastly the maximum number of bytes to read from the stream.

[Int]$response = $stream.Read($bindResponseBuffer, 0, $bindResponseBuffer.count) 

Now let’s take another look at the buffer.

SNAGHTML66f769b4

That looks more like it. Although, this really doesn’t help us see what the actual data is being sent from the remote port.

I do this by casting the byte into something more readable by using [char] type accelerator. Let’s just use this on the first byte to see what we get.

[char]50

image

The 50 byte is actually a 2. Now, using my stringbuilder, I will convert all of the bytes and then display the output.

$Null = $stringBuilder.Append(($bindResponseBuffer | ForEach {
    [char]$_
}) -join '')
$stringBuilder.ToString()

SNAGHTML66fdbfa7

As you can see, the output is very similar to what you would see if you attempted to connect to an FTP server using the FTP client.

I’ve got a function which I wrote to make this process a little easier. An example of it in action is below.

Get-TCPResponse -Computername dc1 -Port 21,25 | 
Format-List

SNAGHTML66eaa073

Download Get-TCPResponse

http://gallery.technet.microsoft.com/scriptcenter/Get-TCPResponse-ba1090e9/file/113111/1/Get-TCPResponse.ps1

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s