IPv4 subnet math with VbScript
At times it can be very convenient to be able to work with IP Addresses and subnetting in VbScript. This collection of functions handles subnet math in VbScript.
A PowerShell version of these functions can be found here.
Convert an IP to binary
This function performs a bitwise comparison (AND) with each octet in the original IP to determine if each power of two is present starting with the highest, 128 returning the binary version of any IP address.
Function ConvertIPToBinary(strIP)
' Converts an IP Address into Binary
Dim arrOctets : arrOctets = Split(strIP, ".")
Dim i
For i = 0 to UBound(arrOctets)
Dim intOctet : intOctet = CInt(arrOctets(i))
Dim strBinOctet : strBinOctet = ""
Dim j
For j = 0 To 7
If intOctet And (2^(7 - j)) Then
strBinOctet = strBinOctet & "1"
Else
strBinOctet = strBinOctet & "0"
End If
Next
arrOctets(i) = strBinOctet
Next
ConvertIPToBinary = Join(arrOctets, ".")
End Function
Convert a binary IP to a decimal IP
It is important to be able to convert back into the familiar form of the IP address, this calculates the decimal form of an IP address based on the binary.
Function ConvertBinIPToDecimal(strBinIP)
' Convert binary form of an IP back to decimal
Dim arrOctets : arrOctets = Split(strBinIP, ".")
Dim i
For i = 0 to UBound(arrOctets)
Dim intOctet : intOctet = 0
Dim j
For j = 0 to 7
Dim intBit : intBit = CInt(Mid(arrOctets(i), j + 1, 1))
If intBit = 1 Then
intOctet = intOctet + 2^(7 - j)
End If
Next
arrOctets(i) = CStr(intOctet)
Next
ConvertBinIPToDecimal = Join(arrOctets, ".")
End Function
Convert a subnet mask to a mask length
Occasionally it is desirable to calculate the subnet mask bit length. This can be done using the following.
Function MaskLength(strMask)
' Converts an subnet mask into a mask length in bits
Dim arrOctets : arrOctets = Split(strMask, ".")
Dim i
For i = 0 to UBound(arrOctets)
Dim intOctet : intOctet = CInt(arrOctets(i))
Dim j, intMaskLength
For j = 0 To 7
If intOctet And (2^(7 -j)) Then
intMaskLength = intMaskLength + 1
End If
Next
Next
MaskLength = intMaskLength
End Function
Convert a mask length to a subnet mask
Function MaskLengthToIP(intMask)
' Converts a mask length to the decimal format mask
Dim arrOctets(3)
Dim intFullOctets : intFullOctets = (intMask - (intMask Mod 8)) / 8
Dim i
For i = 0 To (intFullOctets - 1)
arrOctets(i) = "255"
Next
Dim intPartialOctetLen : intPartialOctetLen = intMask Mod 8
Dim j
If intPartialOctetLen > 0 Then
Dim intOctet
For j = 0 To (intPartialOctetLen - 1)
intOctet = intOctet + 2^(7 - j)
Next
arrOctets(i) = intOctet : i = i + 1
End If
For j = i To 3
arrOctets(j) = "0"
Next
MaskLengthToIP = Join(arrOctets, ".")
End Function
Calculate the subnet network address
The functions above can be used with along with a bitwise AND operation against an IP address and subnet mask to calculate the network address.
Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.
Function CalcNetworkAddress(strIP, strMask)
' Generates the Network Address from the IP and Mask
' Conversion of IP and Mask to binary
Dim strBinIP : strBinIP = ConvertIPToBinary(strIP)
Dim strBinMask : strBinMask = ConvertIPToBinary(strMask)
' Bitwise AND operation (except for the dot)
Dim i, strBinNetwork
For i = 1 to Len(strBinIP)
Dim strIPBit : strIPBit = Mid(strBinIP, i, 1)
Dim strMaskBit : strMaskBit = Mid(strBinMask, i, 1)
If strIPBit = "1" And strMaskBit = "1" Then
strBinNetwork = strBinNetwork & "1"
ElseIf strIPBit = "." Then
strBinNetwork = strBinNetwork & strIPBit
Else
strBinNetwork = strBinNetwork & "0"
End If
Next
' Conversion of Binary IP to Decimal
CalcNetworkAddress= ConvertBinIPToDecimal(strBinNetwork)
End Function
Calculate the subnet broadcast address
To calculate the broadcast address requires a modification of the CalcNetworkAddress function above. This time, it sets anything that is not covered by the mask to 1.
Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.
Function CalcBroadcastAddress(strIP, strMask)
' Generates the Broadcast Address from the IP and Mask
' Conversion of IP and Mask to binary
Dim strBinIP : strBinIP = ConvertIPToBinary(strIP)
Dim strBinMask : strBinMask = ConvertIPToBinary(strMask)
' Set each unmasked bit to 1
Dim i, strBinBroadcast
For i = 1 to Len(strBinIP)
Dim strIPBit : strIPBit = Mid(strBinIP, i, 1)
Dim strMaskBit : strMaskBit = Mid(strBinMask, i, 1)
If strIPBit = "1" Or strMaskBit = "0" Then
strBinBroadcast = strBinBroadcast & "1"
ElseIf strIPBit = "." Then
strBinBroadcast = strBinBroadcast & strIPBit
Else
strBinBroadcast = strBinBroadcast & "0"
End If
Next
' Conversion of Binary IP to Decimal
CalcBroadcastAddress = ConvertBinIPToDecimal(strBinBroadcast)
End Function
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.
Posted by Jon Lundfelt on 21.10.08 at 1:23 pm
This is all very impressive. I am able to get most of these to work for what I need, which is fantastic. However, I cannot for the life of me get the ‘Calculate the subnet network address’ function(s) to work.
It just returns a string like so;
00001010.00011110.00110011.00111110 11111111.11111111.11111111.00000000 0 0 00001010.00011110.00110011.00000000
I am trying to get the network address (e.g. 192.168.0/24) from the IP address and Subnet mask;
strIP = “192.168.0.100″
strMask = “255.255.255.0″
CalcNetworkAddress strIP, strMask
I am sure I am missing something.
TIA !
Jon
Posted by Franklin Piat on 21.10.08 at 1:23 pm
Thanks a lot for these scripts. I them in one of my script.
I have written two extra functions (based on yours), which returns the first and last IP address of a subnet. (usefull for some tools).
I place my contribution in public domain.
BTW, Could you clarify the license of your script (typically Public domain, BSD license, or GPL license).
' **** Calculate the first usable address of a subnet **** ' ' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal. Function CalcRangeStart(strIP, strMask) ' Generates the Network Address from the IP and Mask Dim arrOctets Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinStart Dim intOctet, i, j ' Conversion of IP and Mask to binary strBinIP = ConvertIPToBinary(strIP) strBinMask = ConvertIPToBinary(strMask) ' Bitwise AND operation (except for the dot) For i = 1 to Len(strBinIP) strIPBit = Mid(strBinIP, i, 1) strMaskBit = Mid(strBinMask, i, 1) If strIPBit = "1" And strMaskBit = "1" Then strBinStart = strBinStart & "1" ElseIf strIPBit = "." Then strBinStart = strBinStart & strIPBit Else If i = Len(strBinIP) Then strBinStart = strBinStart & "1" Else strBinStart = strBinStart & "0" End If End If Next ' Conversion of Binary IP to Decimal CalcRangeStart = ConvertBinIPToDecimal(strBinStart) End Function ' **** Calculate the last usable address of a subnet **** ' ' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal. Function CalcRangeEnd(strIP, strMask) ' Generates the Network Address from the IP and Mask Dim arrOctets Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinEnd Dim intOctet, i, j ' Conversion of IP and Mask to binary strBinIP = ConvertIPToBinary(strIP) strBinMask = ConvertIPToBinary(strMask) ' Bitwise AND operation (except for the dot) For i = 1 to Len(strBinIP) strIPBit = Mid(strBinIP, i, 1) strMaskBit = Mid(strBinMask, i, 1) If strMaskBit = "1" Then strBinEnd = strBinEnd & strIPBit ElseIf strIPBit = "." Then strBinEnd = strBinEnd & strIPBit Else If i = Len(strBinIP) Then strBinEnd = strBinEnd & "0" Else strBinEnd = strBinEnd & "1" End If End If Next ' Conversion of Binary IP to Decimal CalcRangeEnd = ConvertBinIPToDecimal(strBinEnd) End FunctionPosted by Chris on 21.10.08 at 1:23 pm
Hey Franklin,
Thanks for the contribution :)
All code is intended to be public domain, I’ll post an explicit statement to that effect somewhere.
Chris
Posted by Chris on 21.10.08 at 1:23 pm
Hi Jon,
Sorry for the delay in getting back to you, I’ve been on holiday so a bit out of touch.
The functions return the correct value for me, did you also include the ConvertIPToBinary and ConvertBinIPToDecimal?
Normally you would use the function something like this:
strNetAddr = CalcNetworkAddress(strIP, strMask)
Or
WScript.Echo CalcNetworkAddress(strIP, strMask)
Chris
Posted by Craig on 21.10.08 at 1:23 pm
Thanks for these functions. I used them, and the information on some of your other pages to write the following functions:
Function GetNumberOfAvailableHostAddresses(nMaskLength) Dim nHosts, nAvailableBits nHosts = -1 'wscript.echo nAvailableBits = 32 - nMaskLength 'wscript.echo nAvailableBits 'Number of Addresses Available for Hosts in Subnet = 2(32 - Number of Masked Bits) - 2 nHosts = (2 ^ nAvailableBits) - 2 GetNumberOfAvailableHostAddresses = nHosts End Function Function GetAllHostAddresses(sNetAddress, sMaskLength) Dim oAllIPs Dim sBroadcast, sNetwork Dim arrOctets Dim nIndexOct4, nIndexOct3, nIndexOct2, nIndexOct1 'Add all IPS to dictionary object Set oAllIPs = CreateObject("Scripting.Dictionary") 'Network address is low address, Broadcast address is high address sNetwork = CalcNetworkAddress(sNetAddress, sMaskLength) sBroadcast = CalcBroadcastAddress(strIP, strMask) arrNetwork = Split(sNetwork, ".") arrBroadcast = Split(sBroadcast, ".") For nIndexOct1 = arrNetwork(0) To arrBroadcast(0) For nIndexOct2 = arrNetwork(1) To arrBroadcast(1) For nIndexOct3 = arrNetwork(2) To arrBroadcast(2) For nIndexOct4 = arrNetwork(3) To arrBroadcast(3) 'Wscript.echo nIndexOct1 & "." & nIndexOct2 & "." & nIndexOct3 & "." & nIndexOct4 oAllIPs.add nIndexOct1 & "." & nIndexOct2 & "." & nIndexOct3 & "." & nIndexOct4, "" Next Next Next Next Set GetAllHostAddresses = oAllIPs End FunctionPosted by Michael on 21.10.08 at 1:23 pm
Realy great collection of scripts.
Right the scripts I was looking for.
Thanks.
Posted by Gavin Mackenzie on 21.10.08 at 1:23 pm
Great work. functions work perfectly and have saved me a heap of work.
Awesome :)
Posted by Robin on 21.10.08 at 1:23 pm
Beautiful functions!
Thumbs up!
:)