65.9K
CodeProject is changing. Read more.
Home

Convert CIDR formatted string to its IPAddress Range representation

starIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

1.00/5 (1 vote)

Dec 29, 2009

CPOL
viewsIcon

14890

''' ''' Converts a CIDR formatted string to the IPAddress-range it represents. (Function handles IPv4 only). ''' ''' CIDR formatted string, example: "209.85.134.0/23" ''' A List(Of IPAddress): (0)=StartIP,...


    ''' <summary>
    ''' Converts a CIDR formatted string to the IPAddress-range it represents. (Function handles IPv4 only).
    ''' </summary>
    ''' <param name="zCIDR">CIDR formatted string, example: "209.85.134.0/23"</param>
    ''' <returns>A List(Of IPAddress): (0)=StartIP, (1)=EndIP</returns>
    ''' <remarks>the machine's endianness is not considered by this function! Little Endian is assumed here.</remarks>
    Private Function CIDR_to_IPRange(ByVal zCIDR As String) As List(Of IPAddress)

        '   zReturn will contain:  zReturn(0) = StartIP, zReturn(1) = EndIP
        Dim zReturn As New List(Of IPAddress)

        '   Split out the StartIP and /suffix from zCIDR = "255.255.255.255/32"
        '   zSAP(0) should then contain the IP prefix = "255.255.255.255" 
        '   zSAP(1) will contain the suffix = "32"
        Dim zSAP As New List(Of String) _
                (zCIDR.Trim.Split("/".ToCharArray, 2, StringSplitOptions.RemoveEmptyEntries))


        '   Add the StartIP
        Try
            zReturn.Add(IPAddress.Parse(zSAP(0)))

        Catch ex As Exception
            '   No StartIP found, so return Nothing
            Return Nothing

        End Try


        '   Calculate and add the EndIP
        Try
            '   NOTE :: the wildcard bits calculation =  2^(32-zSuffix) - 1 
            '   zPrefix must be in the 0-32 range (a suffix of 32 means the StartIP is the same as EndIP)
            Dim zSuffix As Long = Math.Min(32, Math.Max(0, CLng(zSAP(1))))
            zReturn.Add(New IPAddress( _
                            IP_to_Long(zReturn(0).GetAddressBytes, True) _
                            + IP_to_Long(New IPAddress(2 ^ (32 - zSuffix) - 1).GetAddressBytes, False)))

        Catch ex As Exception
            '   Either the /suffix wasn't given, or the IPAddress is out of range (maximum: 4294967295)
            '   I'm choosing to set the EndIP = StartIP if an error happens
            zReturn.Add(zReturn(0))

        End Try


        Return zReturn
        
    End Function

    ''' <summary>
    ''' Converts an IPv4 IPAddress, which is just a 32bit Unsigned Integer, to a Long
    ''' </summary>
    ''' <param name="zAddressBytes">IPAddress in Byte array form.</param>
    ''' <param name="zReverse">This allows you to consider the order of the given Byte array.</param>
    ''' <returns>A Long representing an IPAddress</returns>
    ''' <remarks></remarks>
    Public Function IP_to_Long(ByVal zAddressBytes() As Byte, _
                               Optional ByRef zReverse As Boolean = False) As Long

        If zReverse Then
            Return CLng( _
                    CUInt(zAddressBytes(3)) << 24) _
                    + (CUInt(zAddressBytes(2)) << 16) _
                    + (CUInt(zAddressBytes(1)) << 8) _
                    + (CUInt(zAddressBytes(0)))

        Else
            Return CLng( _
                    CUInt(zAddressBytes(0)) << 24) _
                    + (CUInt(zAddressBytes(1)) << 16) _
                    + (CUInt(zAddressBytes(2)) << 8) _
                    + (CUInt(zAddressBytes(3)))

        End If

    End Function