Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Getting all the ip-addresses on subnet and filtering by availability

5.00/5 (8 votes)
11 Oct 2014CPOL 21.8K  
How to calculate subnet fast and get active ip-addresses

Introduction

Image 1
About a year ago I was looking for a way to get all active ip-addresses on subnet. It was a little part of the management LAN project.

Step 1. Calculating subnet

First of questions was how to "calculate" a network having just ip and mask values.  This task was a good reason to optimize a huge amount of collected examples and manuals. That's what i finally got:
VB.NET
Dim mask() As Byte = IPAddress.Parse("255.255.255.0").GetAddressBytes
Dim iprev() As Byte = IPAddress.Parse("172.16.5.102").GetAddressBytes
' Network id - network address
Dim netid() As Byte = BitConverter.GetBytes(BitConverter.ToUInt32(iprev, 0) And BitConverter.ToUInt32(mask, 0))
' Binary inverted netmask
Dim inv_mask() As Byte = mask.Select(Function(r) Not r).ToArray
' Broadcast address
Dim brCast() As Byte = BitConverter.GetBytes(BitConverter.ToUInt32(netid, 0) Xor BitConverter.ToUInt32(inv_mask, 0))

Step 2. Collecting

Let's fill our subnet with ip-addresses:
VB.NET
' ip1 - subnet address
' ip2 - subnet broadcast address
' lv1 - standard ListView control placed on a Form
Private Sub fillIPs(ByVal ip1() As Byte, ByVal ip2() As Byte)
    Dim tmpip As New Collection(Of ListViewItem)
    For n As UInt32 = BitConverter.ToUInt32(ip1.Reverse.ToArray, 0) + 1 To BitConverter.ToUInt32(ip2.Reverse.ToArray, 0) - 1
        tmpip.Add(New ListViewItem With {.Text = New Net.IPAddress(BitConverter.GetBytes(n).Reverse.ToArray).ToString,
                                         .ImageIndex = 0})
    Next
    lv1.Items.Clear()
    lv1.Items.AddRange(tmpip.ToArray)
End Sub

 

Step 3. Cleaning

Now remove inactive items using ping:

VB.NET
Private d As New Dictionary(of String, Ping)

Private Sub removeInactive(sender As Object, e As EventArgs) Handles Button2.Click
    For Each item As ListViewItem In lv1.Items
        Dim p As New Ping
        d.Add(item.Text, p)
        AddHandler p.PingCompleted, AddressOf p_pingCompleted
        p.SendAsync(item.Text, 200, item.Text)
    Next
End Sub

Private Sub p_pingCompleted(ByVal sender As Object, ByVal e As System.Net.NetworkInformation.PingCompletedEventArgs)
    Dim server As String = e.UserState
    Dim lvi As ListViewItem = lv1.FindItemWithText(server)
    If e.Reply.Status = IPStatus.Success Then
        lvi.ImageIndex = 1
    Else
        lvi.Remove()
    End If
    DirectCast(d(server), IDisposable).Dispose()
    d.Remove(server)
End Sub

Note: Any EndPoints in subnet that are blocking ICMP-requests will be removed as inactive (This method works only for ip-addresses that can be pinged)

That's all.

Now we have very simple and very-very fast solution. Look again at image at the top of page. It was captured from sample project in real time. Great performance, isn't it? But it's just a project executed in IDE. Binary file will some faster of course.

Enjoy!
 
to be continued

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)