I needed a powershell script today with which i can check if two given IP addresses match or if a given IP address belongs to a subnet or if a smaller subnet belongs to a larger one (or vise vursa). I found a nice script written by Sava from http://www.padisetty.com/ which had part of the functionality i required so i took and modified it to suit my needs. Below you will be able to find the modified script i hope it helps somebody :). The script will return an array of two values, one to indicate true or false and the second the direction. The direction is important as you may want to compare values for a firewall and as such you want to fit one in the other in a particular direction.
Usage example:
- checkSubnet ‘10.185.255.128/26’ ‘10.165.255.166/32’
- checkSubnet ‘10.125.255.128’ ‘10.125.255.166′
- checkSubnet ‘10.140.20.0/21’ ‘10.140.20.0/27’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# Please note i took inspiration form www.padisetty.com
# The function will check ip to ip, ip to subnet, subnet to ip or subnet to subnet belong to each other and return true or false and the direction of the check
#////////////////////////////////////////////////////////////////////////
function checkSubnet ([string]$addr1, [string]$addr2)
{
# Separate the network address and lenght
$network1, [int]$subnetlen1 = $addr1.Split('/')
$network2, [int]$subnetlen2 = $addr2.Split('/')
#Convert network address to binary
[uint32] $unetwork1 = NetworkToBinary $network1
[uint32] $unetwork2 = NetworkToBinary $network2
#Check if subnet length exists and is less then 32(/32 is host, single ip so no calculation needed) if so convert to binary
if($subnetlen1 -lt 32){
[uint32] $mask1 = SubToBinary $subnetlen1
}
if($subnetlen2 -lt 32){
[uint32] $mask2 = SubToBinary $subnetlen2
}
#Compare the results
if($mask1 -and $mask2){
# If both inputs are subnets check which is smaller and check if it belongs in the larger one
if($mask1 -lt $mask2){
return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2
}else{
return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1
}
}ElseIf($mask1){
# If second input is address and first input is subnet check if it belongs
return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2
}ElseIf($mask2){
# If first input is address and second input is subnet check if it belongs
return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1
}Else{
# If both inputs are ip check if they match
CheckNetworkToNetwork $unetwork1 $unetwork2
}
}
function CheckNetworkToSubnet ([uint32]$un2, [uint32]$ma2, [uint32]$un1)
{
$ReturnArray = "" | Select-Object -Property Condition,Direction
if($un2 -eq ($ma2 -band $un1)){
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}else{
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}
}
function CheckSubnetToNetwork ([uint32]$un1, [uint32]$ma1, [uint32]$un2)
{
$ReturnArray = "" | Select-Object -Property Condition,Direction
if($un1 -eq ($ma1 -band $un2)){
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr2ToAddr1"
return $ReturnArray
}else{
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr2ToAddr1"
return $ReturnArray
}
}
function CheckNetworkToNetwork ([uint32]$un1, [uint32]$un2)
{
$ReturnArray = "" | Select-Object -Property Condition,Direction
if($un1 -eq $un2){
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}else{
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}
}
function SubToBinary ([int]$sub)
{
return ((-bnot [uint32]0) -shl (32 - $sub))
}
function NetworkToBinary ($network)
{
$a = [uint32[]]$network.split('.')
return ($a[0] -shl 24) + ($a[1] -shl 16) + ($a[2] -shl 8) + $a[3]
}
#////////////////////////////////////////////////////////////////////////
|