'place this code in a separate module
'originally written by Dewayne Basnett in VBA - 1997
'converted to VB .Net - 2007
Option Strict On : Option Explicit On : Option Infer Off
Imports System.Net, System.Text
Module IP4Stuff
Const IPbrdcst As Long = 4294967295 '255.255.255.255 FF.FF.FF.FF
Dim aIP, aMSK As IPAddress
Dim nIP, nMSK, nNET, nHOST, addrs As Long 'numeric equivalents
Dim nCIDR, CIDR, x, y As Integer
Const shBits As Boolean = True 'True = show debug with bits using showBits function
Public Function ipRange(ByVal ipAddr As String, _
ByVal ipMask As String) As List(Of String)
'returns a list of all ip addresse on a given network
'
'ipRange("192.168.3.133", "255.255.254.0") '512 hosts - octet crossing
'
'255.255.254.0 is /23
'List(Of String) - partial output
'192.168.2.0
'192.168.2.1
'192.168.2.2
'...
'192.168.2.254
'192.168.2.255
'192.168.3.0
'192.168.3.1
'...
'192.168.3.253
'192.168.3.254
'192.168.3.255
'note
'first entry in list is THE network number
'last entry in list is the directed broadcast
'
nMSK = IPasNum(ipMask) 'get the Mask as number
CIDR = nCIDR 'get CIDR
nIP = IPasNum(ipAddr) 'get the IP address as number
nNET = IPnetAsNum(nIP, nMSK) 'get THE network number as number
addrs = nNET 'addrs = THE network number as number
nHOST = IPnumOfHosts(nMSK) 'get the number of hosts
If shBits Then
Debug.WriteLine("")
Debug.WriteLine("IP".PadRight(10, " "c) & showBits(nIP) & " " & ipAddr)
Debug.WriteLine("Mask".PadRight(10, " "c) & showBits(nMSK) & " " & ipMask)
Debug.WriteLine("Net".PadRight(10, " "c) & showBits(nNET) & " " & NumToIp(nNET))
Debug.WriteLine("Hosts".PadRight(10, " "c) & showBits(nHOST) & " " & nHOST.ToString)
Debug.WriteLine("CIDR".PadRight(10, " "c) & CIDR.ToString)
'Stop
End If
If nIP < 0 OrElse nMSK < 0 OrElse nNET = 0 OrElse nHOST = 0 Then
Return New List(Of String) 'error
End If
ipRange = New List(Of String)
For x As Long = 0 To nHOST
ipRange.Add(NumToIp(addrs)) 'add host to list
addrs += 1 'increment it
Next
End Function
Public Function IPnets(ByVal ipAddr As String, _
ByVal curCIDR As Integer, _
ByVal newCIDR As Integer) As List(Of String)
'returns a list of sub-nets using any IP in the current network,
'the current mask as CIDR and new mask as CIDR.
'192.168.3.? /23 to /25 - octet crossing
'
'IPnets("192.168.3.128", 23, 25)
'
'List(Of String)
'255.255.255.128
'192.168.2.0
'192.168.2.128
'192.168.3.0
'192.168.3.128
'
Dim curMASK, newMASK, netPlus1 As Long, numOfNets As Integer
nIP = IPasNum(ipAddr) 'get the IP address as number
If nIP < 0 OrElse curCIDR < 2 OrElse curCIDR > newCIDR OrElse newCIDR > 30 Then
Return New List(Of String) 'error
End If
IPnets = New List(Of String)
curMASK = MaskFromCidr(curCIDR) 'convert CIDR's to mask as number
newMASK = MaskFromCidr(newCIDR)
nHOST = IPnumOfHosts(newMASK)
netPlus1 = nHOST + 1 'used to add 1 to the network portion of the ip address
nNET = IPnetAsNum(nIP, curMASK) 'get THE network number as number
numOfNets = CInt(2 ^ (newCIDR - curCIDR)) 'number of networks
IPnets.Add(NumToIp(newMASK)) '<<<<<<<<<<<<<<<<<<<<< first entry in list is the new mask
If shBits Then
Debug.WriteLine("")
Debug.WriteLine("IP".PadRight(10, " "c) & showBits(nIP) & " " & ipAddr)
Debug.WriteLine("Network".PadRight(10, " "c) & showBits(nNET) & " " & NumToIp(nNET))
Debug.WriteLine("Cur. Mask".PadRight(10, " "c) & showBits(curMASK) & " " & NumToIp(curMASK))
Debug.WriteLine("New Mask".PadRight(10, " "c) & showBits(newMASK) & " " & NumToIp(newMASK))
Debug.WriteLine("Plus 1".PadRight(10, " "c) & showBits(netPlus1) & " " & NumToIp(netPlus1))
Debug.WriteLine("Num. Nets".PadRight(10, " "c) & numOfNets.ToString)
'Stop
End If
For x As Integer = 0 To numOfNets - 1
IPnets.Add(NumToIp(nNET))
'to get last address(broadcast) Dim BrdCst as long = nNET Or nHOST
nNET += netPlus1 'add one network number
Next
End Function
Private Function MaskFromCidr(ByVal CIDR As Integer) As Long
'x = 32 - CIDR
'z = (2^x)-1
'return z xor 255.255.255.255
MaskFromCidr = CLng(2 ^ ((32 - CIDR)) - 1) Xor IPbrdcst
End Function
Private Function IPnumOfHosts(ByVal IPmsk As Long) As Long 'a mask for the host portion
'255.255.255.0 XOR 255.255.255.255 = 255 so 0 to 255 is 256 hosts
IPnumOfHosts = IPmsk Xor IPbrdcst 'cacluate the number of hosts
End Function
Private Function IPnetAsNum(ByVal IPnum As Long, ByVal IPmsk As Long) As Long 'extract network from ip address
'192.168.2.113 AND 255.255.255.0 = 192.168.2.0
IPnetAsNum = IPnum And IPmsk 'calculate THE network number
End Function
Private Function IPasNum(ByVal AipAddr As String) As Long 'return -1 on error
If Not IPAddress.TryParse(AipAddr, aIP) Then 'convert string to IP
Return -1 'error
Else
IPasNum = IPtoNum(aIP) 'convert IP to number
If IPasNum = 0 Then
Return -1 'error
End If
End If
End Function
Private Function IPtoNum(ByVal theIP As IPAddress) As Long 'convert IP to number
Dim IPb() As Byte = theIP.GetAddressBytes 'get the octets
Dim theBit As Integer = 31 'work MSb to LSb
Dim addr As Long 'accumulator for address
nCIDR = 0
For x = 0 To 3 'four octets
For y = 7 To 0 Step -1 'with 8 bits each - duh
If (IPb(x) And CByte(2 ^ y)) = CByte(2 ^ y) Then 'if the bit is on
addr += CLng(2 ^ theBit) 'accumulate
nCIDR += 1 'count bits
End If
theBit -= 1 'decrement bit pos
Next
Next
Return addr
End Function
Private Function NumToIp(ByVal theIP As Long) As String 'convert number back to IP
Dim IPb(3) As Byte '4 octets
Dim theBit As Integer = 31 'work MSb to LSb
Dim addr As String 'accumulator for address
For x = 0 To 3 'four octets
For y = 7 To 0 Step -1 '8 bits
If (theIP And CLng(2 ^ theBit)) = CLng(2 ^ theBit) Then 'if the bit is on
IPb(x) += CByte(2 ^ y) 'accumulate
End If
theBit -= 1
Next
addr &= IPb(x).ToString & "." 'add current octet to string
Next
Return addr.TrimEnd("."c)
End Function
Private Function showBits(ByVal aNum As Long) As String
Dim strObits As New StringBuilder
strObits.Append(Convert.ToString(aNum, 2).PadLeft(32, "0"c))
For ix As Integer = 24 To 0 Step -8
strObits.Insert(ix, " ")
Next
showBits = strObits.ToString.Trim
End Function
End Module