65.9K
CodeProject is changing. Read more.
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (8 votes)

Oct 12, 2014

CPOL
viewsIcon

21803

How to calculate subnet fast and get active ip-addresses

Introduction

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:

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:
' 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:

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