Hi Everybody,
Network administrators, sometimes, need to calculate netmasks. For this kind of task exists a lot of IP Calculators over Internet. I like so much this:
http://jodies.de/ipcalc In this kind of application, you post the Ip address and the netmask and it returns the IP range of the network.
But sometimes, we need to calculate the netmask from a given IP range. This kind of app exists on Internet only at
http://apps.csc.fi/laskin2.html It is an excellent netmask calculator and I use it a lot. Recently, the site of CSC (where this app is hosted) was upgraded and the app stayed offline about 15 days or more.
In this period of time I was needing to use the app and looking for another similar app over Internet I cannot found anyone.
So I decide to write this code. It can be used as Script (preferably with CSCRIPT engine) or as an ASP app (changing the WScript.Echo to Response.Write.
The results are equal of Network Aggregation Calculator above.
The code can be used by anyone since I create it, because, I ask for the code to
webmaster@csc.fi, when the app was offline, and he doesn't answer me.
I decide to use VBScript for the code, since it simple to understand than JAVA (language that I belive the Online Net Aggregation Calculator was written).
So let's go to the code (below there's an explanation about it):
Option Explicit
Function Ip2Num(ByVal Ip)
'Presets the return of function
Ip2Num = Null
'Evaluates the parameter
If Len(Ip) = 0 Then Exit Function
Ip = Split(Ip, ".", -1, 1)
If UBound(Ip) <> 3 Then Exit Function
'Starts the calc
Dim Num
For Each Num In Ip
If Not IsNumeric(Num) Then Exit Function
If CDbl(Num) < 0 Or CDbl(Num) > 255 Then Exit Function
Next
'Returns the result
Ip2Num = (CByte(Ip(0)) * 16777216) + (CByte(Ip(1)) * 65536) + (CByte(Ip(2)) * 256) + CByte(Ip(3))
End Function
Function Num2Ip(ByVal Num)
'Presets the return of function
Num2Ip = Null
'Evaluates the parameter
If Len(Num) = 0 Then Exit Function
If Not IsNumeric(Num) Then Exit Function
Num = CDbl(Num)
If Num < 0 Or Num > 4294967295 Then Exit Function
'Starts the calc
Num = Num / 16777216
Num2Ip = Fix(Num) & "."
Num = ((Num - Fix(Num)) * 16777216) / 65536
Num2Ip = Num2Ip & Fix(Num) & "."
Num = ((Num - Fix(Num)) * 65536) / 256
Num2Ip = Num2Ip & Fix(Num) & "."
Num = (Num - Fix(Num)) * 256
'Returns the sum
Num2Ip = Num2Ip & Fix(Num)
End Function
Function Num2Mask(ByVal Num)
'Presets the return of function
Num2Mask = Null
'Evaluates the parameter
If Len(Num) = 0 Then Exit Function
If Not IsNumeric(Num) Then Exit Function
Num = CDbl(Num) - 1
If Num < 0 Or Num > 4294967295 Then Exit Function
'Starts the calc and returns the value
Num = Num / 16777216
Dim Pat
Pat = 255 - Fix(Num)
If Pat < 255 Then
Num2Mask = Pat & ".0.0.0"
Else
Num2Mask = Pat & "."
Num = ((Num - Fix(Num)) * 16777216) / 65536
Pat = 255 - Fix(Num)
If Pat < 255 Then
Num2Mask = Num2Mask & Pat & ".0.0"
Else
Num2Mask = Num2Mask & Pat & "."
Num = ((Num - Fix(Num)) * 65536) / 256
Pat = 255 - Fix(Num)
If Pat < 255 Then
Num2Mask = Num2Mask & Pat & ".0"
Else
Num2Mask = Num2Mask & Pat & "."
Num = (Num - Fix(Num)) * 256
Num2Mask = Num2Mask & (255 - Fix(Num))
End If
End If
End If
End Function
Function NetNums(ByVal Valor)
'Evaluates the parameter
If Valor < 0 Or Valor > 255 Then Exit Function
'Starts the calc
NetNums = 256
While Valor <> 0
While NetNums > Valor
NetNums = NetNums / 2
WEnd
Valor = Valor Xor NetNums
WEnd
End Function
'Main procedure
Dim Ipi, Ipf, IpiNum, IpfNum, x, Nts
'Start IP
'Ipi = "189.3.64.0"
'End IP
'Ipf = "189.3.74.255"
'Evaluates IPs
If Len(Ipi) = 0 Then
WScript.Echo "Start IP not present"
WScript.Quit(1)
End If
If Len(Ipf) = 0 Then
WScript.Echo "End IP not present"
WScript.Quit(2)
End If
IpiNum = Ip2Num(Ipi)
IpfNum = Ip2Num(Ipf)
If IsNull(IpiNum) Then
WScript.Echo "Invalid Start IP"
WScript.Quit(3)
End If
If IsNull(IpfNum) Then
WScript.Echo "Invalid End IP"
WScript.Quit(4)
End If
'Starts calc
x = 3
'Do the calc while it lower or equal to End IP
While IpiNum <= IpfNum
'Transforms IP to Num
Ipi = Num2Ip(IpiNum)
Ipi = Split(Ipi, ".", -1, 1)
'Decreases X if IP is 0
While Ipi(x) = 0 And x > 0
x = x - 1
WEnd
'Returns number of subnets of the number
Nts = NetNums(Ipi(x))
'Increases X if the number of subnets is 0
While Nts = 0 And x < 3
x = x + 1
Nts = NetNums(Ipi(x))
WEnd
'Decreases number of Nets to fit the value lower of end IP
Do While IpiNum + (Nts * (256 ^ (3 - x))) > IpfNum + 1
Nts = Nts \ 2
While Nts = 0 And x < 3
x = x + 1
Nts = NetNums(Ipi(x))
WEnd
Loop
'Calculates number of IPs by number of nets
Nts = Nts * (256 ^ (3 - x))
'Writes the initial IP and the its netmask
WScript.Echo Num2Ip(IpiNum) & ": " & Num2Mask(Nts)
'Adds the number of IPs to the current IP
IpiNum = IpiNum + Nts
WEnd
Explanation:
First, we need to create a function to transform Ip addresses format (xxx.xxx.xxx.xxx) to a sequential number, so we can manipulate the numbers easily. This function is named IP2Num
So, after this, we need to write a function to convert the sequential number back to IP format (Num2IP).
The function Num2Mask calculates the Netmask of the number of IPs.
The function NetNums returns the number of nets a given IP number can have.
Finally, the main procedure evaluates if the current IP sum is lower or equal to the end IP and make the calcs to return the max IP address and its netmask that fits in the range until hit the end IP.
So that is it.
See ya.
<message edited by Ilanio on Friday, February 09, 2007 2:12 AM>