Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address
Incrementing an IP Address Incrementing an IP Address
Incrementing an IP Address
Go Back  Xtreme Visual Basic Talk > > > Incrementing an IP Address


Reply
 
Thread Tools Display Modes
  #1  
Old 07-11-2011, 10:02 PM
Skater Kid Skater Kid is offline
Newcomer
 
Join Date: Jul 2011
Posts: 2
Default Incrementing an IP Address


Hey so I am trying to make a simple port scanner to scan a rang of IP's so like 192.168.4.245 to 192.168.5.100. I am using Visual Basic.Net 2010 and am having trouble converting the IP from a String to a Long so that I can increment it and convert it back to a String. For some reason VB.Net 2010 doesn't include the winsock controller and therefore I am having problems finding a method that works similar to inet_addr() which makes conversion much easier. I found an example on one of the forms here: Increment and IP Address but it too uses the inet_addr(). I tried to convert the code to a VB.Net 2010 compatible version but had no luck. Here is the code I have now followed by the output:

Code:
 Private Sub Command1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
        Dim ipAddr As IPAddress
        Dim lonAddr As Long
        Dim strAddr As String
        Dim ipArray() As String
        Dim x As Long

        strAddr = "192.168.1.201"

        For x = 1 To 1000

            ipArray = Split(strAddr, ".")
            strAddr = ipArray(3) & "." & _
            ipArray(2) & "." & _
            ipArray(1) & "." & _
            ipArray(0)

            ipAddr = IPAddress.Parse(strAddr)
            lonAddr = ipAddr.Address + 1

            ipAddr = IPAddress.Parse(lonAddr)
            strAddr = ipAddr.ToString

            ipArray = Split(strAddr, ".")
            strAddr = ipArray(3) & "." & _
            ipArray(2) & "." & _
            ipArray(1) & "." & _
            ipArray(0)

            List1.Items.Add(strAddr)

        Next
Which produces the following output (just a snipit not all 1000 combinations)

Code:
202.1.168.192
193.168.1.202
203.1.168.193
194.168.1.203
204.1.168.194
195.168.1.204
205.1.168.195
196.168.1.205

'program starts at "192.168.1.201"
I am guessing it has something to do with the fact that the Long produces by using ipAddr.Address attribute is different than the one produced by using the inet_addr() method. Thanks for the help.
Reply With Quote
  #2  
Old 07-12-2011, 10:49 AM
AtmaWeapon's Avatar
AtmaWeaponIncrementing an IP Address AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Long story short: if you're not using the code you're used to, don't assume the new code works the same way as the old code.

The part that gets confusing is it seems there's a second reversal in there. There's a reason. .NET (and windows in general) is little-endian.The IP protocol uses big-endian: this is called "network byte order". If you're not familiar with endian-ness, here's a quick illustration. The 32-bit integer 255 can be represented two ways:
Code:
big-endian:    00 00 00 FF
little-endian: FF 00 00 00
In little-endian, the least significant bits of a number come first; to humans this is backwards but it can be more efficient for certain computer architectures. Endian-ness is why you get weird results.

If you use the debugger you can verify that for 192.168.1.1, Address is 16885952. In hex, this is 0x0101A8C0. Write out the bytes and you'll get { 1, 1, 168, 192 }. Little endian. I'd call this an error and it's probably why Address is deprecated: I'd expect IPAddress to use network byte order. Anyway, if you increment this number you'll have bytes for { 1, 1, 168, 193 }. Whoops, you wanted { 2, 1, 168, 192 } because our minds work in big endian. So when you convert everything back you get 193.168.1.1. But it gets more interesting.

IPAddress.Parse() seems to expect little endian as well. So when you reverse the first time and pass "201.1.168.192" to this method, it spits out an address with bytes { 192, 168, 1, 201 }. That gets incremented to { 192, 168, 1, 202 }. Then you call IPAddress.Parse() on the number; this is neat. Parsing a Long is undocumented and assumes network byte order even though everything else uses little endian! So the IP parses to 192.168.1.202, which you reverse to 202.1.168.192. The next time around you flip-flop again.

Two things would have prevented this:
  • When you use Address, VS marks it and warns you it's deprecated. Using deprecated members is usually a bad idea. In this case, MS deprecated it for IPv6 support but it's also got this bizarre byte order malfunction.
  • If you had Option Strict On, you would not have been able to use IPAddress.Parse() on the Long value.

The right way to approach it with no deprecated members is still a little tricky. Documentation recommends IPAddress.GetAddressBytes(). This will return bytes in network byte order (and also supports IPv6 addresses.) We could worry about swapping the array back and forth between big and little endian, but IPAddress.NetworkToHost() and IPAddress.HostToNetwork() do the trick for us: "host" network order represents the endian-ness of the current machine. You can convert byte arrays to values and back using the BitConverter class. Put all these pieces together and you get something that works:
Code:
Imports System.Net

Module Module1

    Sub Main()
        ' Use Parse() to convert from the starting address string to an IPAddress.
        Dim startAddress As IPAddress = IPAddress.Parse("192.168.1.1")

        ' This is a loop variable that will be updated each pass.
        Dim currentAddress As IPAddress = startAddress
        For i As Integer = 1 To 10
            ' We need the integral value of the IP. The Address property is deprecated. Use GetAddressBytes() and
            ' convert the bytes to a value. If you are using IPv4, this should be 4 bytes, 32 bits, only Integer is needed.
            Dim addressBytes() As Byte = currentAddress.GetAddressBytes()
            Dim addressValue As Integer = BitConverter.ToInt32(addressBytes, 0)

            ' The bytes come out in network order; we don't want to figure out if that's backwards or not. Use this method
            ' to convert to whatever the host machine uses.
            addressValue = IPAddress.NetworkToHostOrder(addressValue)

            ' Incrmeent to the next IP; probably want to turn off overflow checking!
            addressValue += 1

            ' We're ready to go back to bytes; convert the number back to network order
            addressValue = IPAddress.HostToNetworkOrder(addressValue)

            ' Turn it back into bytes, create the new IP, and print it.
            addressBytes = BitConverter.GetBytes(addressValue)
            currentAddress = New IPAddress(addressBytes)
            Console.WriteLine(currentAddress)
        Next
    End Sub

End Module
Fair warning: using signed integers for this is bound to produce an overflow at some point. UInt32 would be a smarter data type for Int32, but there's no convenient way to convert between byte orders for that data type. You could also turn off overflow checking in your project settings; that's probably the easiest solution.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.

Last edited by passel; 07-13-2011 at 04:44 PM.
Reply With Quote
  #3  
Old 07-12-2011, 08:05 PM
Skater Kid Skater Kid is offline
Newcomer
 
Join Date: Jul 2011
Posts: 2
Default

Cool I got my original code to work by deleting the second reversal. How ever I preferred your code as it seemed less buggy and didn't rely on parsing a Long which according to you is undocumented. Now for some reason the code throws an exception when I try to connect to a port on the system with the current IP address.

Code:
client.Connect(currentAddress, port)

client.BeginConnect(currentAddress, port)

'Both throw a System.NullReferenceException
Reply With Quote
  #4  
Old 07-12-2011, 09:26 PM
AtmaWeapon's Avatar
AtmaWeaponIncrementing an IP Address AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

There's three variables that could be Nothing in that code, and no other information for me to go on. Use the debugger to figure out which one is Nothing, then fix it.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address Incrementing an IP Address
Incrementing an IP Address
Incrementing an IP Address
 
Incrementing an IP Address
Incrementing an IP Address
 
-->