This is the simplest subnet calculator written in VBScript you will probably find. I have only found one other to this date. “What?” you say, "There are heaps of subnet calculators on the net!". Yes, but they are not written in VBScript and that is still a language of choice for many Systems Administrators.
I have been using this code snippet by okstorms to resolve subnet from IP and Subnet Mask for a number of scripts and to tell you the truth, it has worked perfectly and I had not even bothered to look at it closely to work out how it does its magic.
Recently I wrote a script to list all the hosts on the same subnet as a given IP and once again I used okstorms’ trusty code and also used Phil Calderone’s subnet table as a lookup for the number of hosts.
After doing some tests, I was not happy;
- I did not know exactly how okstorms’ subnet code worked and
- The new script worked, but I was not confident it was giving 100% reliable results.
Subsequently I discovered <shock />Phil Calderone’s subnet table is now obsolete which rocked me because I used that to pass my MCSC TCP-IP exam back in 2001.
Using the Code
Leading up to my revelations, I had decided to write my own subnet calculator from the ground up based on Phil subnet table. The script I created was quite lengthy and verbose because it performed the calculations long hand using similar logic that a human would use with the table.
The script seemed to work perfectly, it returned the first and last IP of the target subnet range and even iterated through all the addresses in that range. I was confident it worked as the results matched my subnet table but this is where my world started to fall apart. When I tested it against some on-line subnet calculators, I sometimes got different results?
Further investigation revealed that the problem was my subnet table, something that I believed solid, published and promoted by Microsoft, was now obsolete. Who would think that something like subnet range definitions would change. This page pointed me to RFC 1878 which explains that the practice of excluding subnets that contain all zeros or all ones is now obsolete. Ah, mystery solved.
Right, back to the drawing board. What I needed was a subnet calculator which was not reliant on tables or other fancy calculations with individual octets, but works on a simple binary level. I closely examined okstorms’ subnet calculator and was surprised at the simplicity in which it converted IP to binary, calculated the subnet bits and then trimmed the IP to that length returning the
Function Subnet(strAddress, strMask)
lenSN = Len(Left(str2bin(strMask), InStr(str2bin(strMask), "0") - 1))
Subnet = bin2str(Left(str2bin(strAddress), lenSN) & String(32 - lenSN, "0"))
Unfortunately I needed more than that, but after a little experimentation, I found I also could get the first address (
subnetID) of the target range by calculating
(IP AND Subnet Mask) in Binary. Further more, the last address of a range (broadcast address) could be obtained by calculating
(IP OR Subnet Mask) in binary.
for c=32 to 1 step -1
temp=(cint(mid(binIP,c, 1)) and cint(mid(binSNM,c, 1))) & temp
netwAdd=temp : temp=""
Then all I had to do, to find the number of hosts, was to subtract the first host from the last host, except VBScript does not natively do calculations in binary. So I wrote two functions
binSub() to perform 32bit binary addition and subtraction. I am sure these two functions could be written with a bit more mathematical finesse but they are quite effective.
Here in this code snippet, I add two binary numbers together. I first attempted to use fancy logic to create a slick function using mathematics but decided it would have to be a loop and decided to apply the same logic as if I was working it out with pencil and paper. (Quick code and not too dirty.)
for i=32 to 1 step-1
if a=0 and b=0 and c=0 then
add=0 : c=0
elseif a=1 and b=0 and c=0 then
add=1 : c=0
elseif a=0 and b=1 and c=0 then
add=1 : c=0
elseif a=1 and b=1 and c=0 then
add=0 : c=1
elseif a=1 and b=1 and c=1 then
add=1 : c=1
elseif a=1 and b=0 and c=1 then
add=0 : c=1
elseif a=0 and b=1 and c=1 then
add=0 : c=1
elseif a=0 and b=0 and c=1 then
add=1 : c=0
msgbox "Error this function is only for adding 2 32bit binary numbers together"
binAdd=0 : exit function
Job done, I now have a subnet calculator that works on a binary level, I fully understand how it works and am confident of the results I get.
This version of the script also outputs the binary equivalent, handy if you want to understand how it works on a binary level. IMO, this is essential to understanding IP subnets.
Points of Interest
This script writing adventure has enlightened me further to the intricacies of the world of subnetting. I sort of thought those once invalid subnet ranges were a waste of IP address space, obviously someone else thought so too and did something about it.
Attached at the top in of the article is my first attempt of a subnet calculator based on Phil Calderone’s subnet table, BTW thanks Phil I passed that TCP-IP exam.
Also you will find my final code. Thanks okstorms for your subnet calculator, it is used in our desktop management tool that my IT branch uses every day along with a number of other scripts I have written over the years. And now it has inspired this code that does the same as yours, but also calculates the number of hosts in the subnet.
- 14th April, 2010: Initial post