
'*************************************************************************
'
'      Author       : Esben Laursen (hyber@hyber.dk)
'      
'      Webpage      : http://www.hyber.dk or http://netsmsgw.sf.net
'
'      Notes        :
'
'      License      : This program is free software; you can redistribute
'                     it and/or modify it under the terms of the GNU
'                     General Public License as published by the Free
'                     Software Foundation version 2 of the License.
'
'*************************************************************************

Public Class ipUtils


    Public Function GetNetworkAdr(ByVal pstrIPadr As String, ByVal pintCIDR As Integer) As String

        Dim strBinIP As String
        Dim strNetIP As String

        strBinIP = GetBinaryIPadr(pstrIPadr)

        strNetIP = Microsoft.VisualBasic.Left(strBinIP, pintCIDR)
        strNetIP = strNetIP & "000000000000000000000000000000000000"
        strNetIP = Microsoft.VisualBasic.Left(strNetIP, 32)

        strNetIP = GetIPadrFromBinary(strNetIP)

        Return strNetIP

    End Function

    Public Function GetBroadCastAdr(ByVal pstrIPadr As String, ByVal pintCIDR As Integer) As String

        Dim strBinIP As String
        Dim strNetIP As String

        strBinIP = GetBinaryIPadr(pstrIPadr)

        strNetIP = Microsoft.VisualBasic.Left(strBinIP, pintCIDR)
        strNetIP = strNetIP & "11111111111111111111111111111111111"
        strNetIP = Microsoft.VisualBasic.Left(strNetIP, 32)

        strNetIP = GetIPadrFromBinary(strNetIP)

        Return strNetIP

    End Function

    Public Function GetIPadrFromBinary(ByVal pstrBinIP As String) As String
        Dim binIP(3) As String
        Dim i As Integer
        Dim str(3) As String
        Dim strReturn As String


        For i = 0 To 3
            binIP(i) = Microsoft.VisualBasic.Left(pstrBinIP, 8)
            pstrBinIP = pstrBinIP.Remove(0, 8)

            str(i) = Convert.ToInt16(binIP(i), 2)


        Next

        strReturn = str(0) & "." & str(1) & "." & str(2) & "." & str(3)

        Return strReturn

    End Function

    Public Function MatchIpInRange(ByVal pstrNetworkIP As String, ByVal pintCIDR As Integer, ByVal pstrClientIP As String) As Boolean
        Dim strBinNetIpStart As String
        Dim strBinNetIpEnd As String
        Dim strBinClientIP As String
        Dim strStartIP(3) As String
        Dim strEndIP(3) As String
        Dim strClientIP(3) As String
        Dim i As Integer
        Dim intStartIP As Integer
        Dim intEndIP As Integer
        Dim intClientIP As Integer

        'get start and end addresses in network range
        strBinNetIpStart = GetNetworkAdr(pstrNetworkIP, pintCIDR)
        strBinNetIpEnd = GetBroadCastAdr(pstrNetworkIP, pintCIDR)

        'get binary IP
        strBinNetIpStart = GetBinaryIPadr(strBinNetIpStart)
        strBinNetIpEnd = GetBinaryIPadr(strBinNetIpEnd)
        strBinClientIP = GetBinaryIPadr(pstrClientIP)

        'split binary ip addresses, to compare it
        strStartIP = SplitBinaryIPAdr(strBinNetIpStart)
        strEndIP = SplitBinaryIPAdr(strBinNetIpEnd)
        strClientIP = SplitBinaryIPAdr(strBinClientIP)

        'checks every segment in IP adr. 
        For i = 0 To 3
            intStartIP = Convert.ToInt16(strStartIP(i), 2)
            intEndIP = Convert.ToInt16(strEndIP(i), 2)
            intClientIP = Convert.ToInt16(strClientIP(i), 2)

            'check if start/end segment is the same
            If intStartIP = intEndIP Then
                If intClientIP = intStartIP Then
                    'if we match the IP aegment to start/end IP check next segment
                    GoTo NextSegment
                Else
                    Return False
                End If
            End If

            'if the start/end segment is not the same we need to check if the client ip adr is in between.
            'I know it could have been done with the else statement, but its done like this for easier overview 
            If Not intStartIP = intEndIP Then

                'if client ip segment is higher than startip and lower that endip goto nextsegment
                If intClientIP >= intStartIP And intClientIP <= intEndIP Then
                    GoTo NextSegment
                Else
                    Return False
                End If
            End If



            'we should never end up here, just to make sure, we "deny" the match
            Return False

NextSegment:
            'if this is the fourth time we goto next segment, then we have matched every IP and we return true
            If i = 3 Then
                Return True
            End If
        Next


    End Function



    Private Function SplitBinaryIPAdr(ByVal pstrBinaryIP As String) As String()
        Dim strSplit(3) As String
        Dim strTmp As String
        Dim i As Integer

        strTmp = pstrBinaryIP

        For i = 0 To 3
            strSplit(i) = Microsoft.VisualBasic.Left(strTmp, 8)
            strTmp = strTmp.Remove(0, 8)

        Next

        Return strSplit

    End Function

    Public Function GetBinaryIPadr(ByVal pstrIPadr As String) As String

        Dim strIParr(3) As String
        Dim i As Integer
        Dim binIP(3) As String
        Dim str As String


        strIParr = Split(Trim(pstrIPadr), ".", 4)


        For i = 0 To 3

            'convert to binary format
            binIP(i) = Convert.ToString(CInt(strIParr(i)), 2)

            'make sure there are 8 chifers
            binIP(i) = "00000000" & binIP(i)
            binIP(i) = Microsoft.VisualBasic.Right(binIP(i), 8)

        Next

        str = binIP(0) & binIP(1) & binIP(2) & binIP(3)

        Return str

    End Function

End Class
