Search code examples
c#ip-addressrange

How to use IPAddress and IPv4Mask to obtain IP address range?


I'm trying to accomplish the following in C#/.NET 2.0:

Given an IPAddress object (say, 192.168.127.100) and another IPAddress object containing the IPv4Mask / subnet mask (say, 255.255.248.0), I should be able calculate the start and end of the IP Address range.

(Yes, I'm trying to do a for-loop thru a range of addresses on a subnet.)

Theoretically, I should be able to bitwise AND on the IPAddress and the SubnetMask to get the IPStart. Then I should be able to perform a bitwise XOR on the IPStart and the inverted (NOT'd) SubnetMask, to get the IPEnd.

The IPAddress object provides methods to output the address as a "long" or as "byte[]" (array of bytes).

Performing the bitwise operation on the long (because it is signed?) produces invalid results. And I can't seem to perform bitwise operation on the IPAddresses as an array of bytes.

EDIT-1: Okay, looping thru each byte in the array and performing bitwise AND, NOT, and XOR (in each respective situation) gets the right results.

The next problem I am running into is that I cannot perform the for-loop easily after converting the byte[] arrays into UInt32 or long. So, the first value works properly, but incrementing the uint/long by one makes the IPaddress increase from 192.168.127.0 to 193.168.127.0 -- It seems that after the byte[] array is transformed to uint/long, the order of the bytes gets reversed. So there is no easy way to increment from IPStart to IPEnd.

Any have any suggestions?


Solution

  • Crawl through the two byte[] arrays together, for each byte pair perform the bitwise comparison and place the result into a third byte[] array for the range start. You can crawl through the network address byte[] array and invert each bit to generate the wildcard mask (as you called it, inverted subnetmask), and then repeat the process as before using the wildcard mask in place of the subnet mask to calculate the range end. Remember also that the first value in the range is the subnet network address and the last value is the broadcast address, so those two addresses are not in the actual host address range. Here is your example in a step-by-step summary:

    Address:   192.168.127.100       11000000.10101000.01111 111.01100100
    Netmask:   255.255.248.0 = 21    11111111.11111111.11111 000.00000000
    Wildcard:  0.0.7.255             00000000.00000000.00000 111.11111111
    =>
    Network:   192.168.120.0/21      11000000.10101000.01111 000.00000000
    Broadcast: 192.168.127.255       11000000.10101000.01111 111.11111111
    HostMin:   192.168.120.1         11000000.10101000.01111 000.00000001
    HostMax:   192.168.127.254       11000000.10101000.01111 111.11111110