Determining if IP addresses are on the same subnet

This is actually a fairly simple task that many people have done in many different languages. However, I thought it would be useful to share for the sake of showing how .NET can do a lot of tedious work for us.

IP Addresses are made up of 32 bits. Subnet masks are 32 bits as well. The subnet mask is what is used to determine where the Network ID ends and the host ID begins. Masks must have contiguous 1’s. If there is a 1 in the mask, then the corresponding bit in the IP Address is part of the Network ID. If there is 0 in the mask, the corresponding bit in the IP Address is part of the host ID.

So obviously there is going to be a lot of binary math, which any good network engineer can do. However, if you can get it for free, even better!

There is a type in .NET called System.Net.IPAddress that has several useful properties. The one I will focus on is Address.

image

Using the Address property and some bitwise operators in PowerShell, we can come up with a function pretty quickly. The –and and –or operators are pretty commonplace in the world of PowerShell but there is occasionally a need to do a compare of two numbers at the bit level. This is done with the –band and –bor operators. I may be off but if memory serves, using –bor and –band you can build any other bit function like xor. I won’t event think about K-maps.

So with all that, here is some code:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
Function Test-SameSubnet {
param (
[parameter(Mandatory=$true)]
[Net.IPAddress]
$ip1,

[parameter(Mandatory=$true)]
[Net.IPAddress]
$ip2,

[parameter()]
[alias("SubnetMask")]
[Net.IPAddress]
$mask ="255.255.255.0"
)

if (($ip1.address -band $mask.address) -eq ($ip2.address -band $mask.address)) {$true}
else {$false}

}

The Address property is the binary number that represents the IP Address. Doing a bitwise AND with a mask will tell us if they are in the same subnet. I have a default value of 255.255.255.0 for the mask, or /24 if you prefer CIDR notation, but you can specify it as a parameter if you like.

 image

Comments (1) -

Cool function just like to clarify that IPv4 IPs are 32bit but IPv6 Ips are 128bit but either way .NET IPAddress class works. IPAddress is IP agnostic

Comments are closed