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.

8 Responses to this post.

  1. 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

  2. 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 Function
    
  3. Posted 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

  4. 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

  5. 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 Function
    
  6. Posted by Michael on 21.10.08 at 1:23 pm

    Realy great collection of scripts.
    Right the scripts I was looking for.
    Thanks.

  7. 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 :)

  8. Posted by Robin on 21.10.08 at 1:23 pm

    Beautiful functions!
    Thumbs up!

    :)

Respond to this post