Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare IP address range in C#?

Tags:

c#

ipv6

ipv4

cidr

If I have an IP address range (CIDR notation) and I need to know if some arbitrary IP address is within that range -- both presented as strings -- what is the easiest way to do this with C#?

Examples:

  • IPv4 Range: 192.168.168.100/24, IP to check: 192.168.168.200
  • IPv6 Range: fe80::202:b3ff:fe1e:8329/24, IP to check: 2001:db8::
like image 373
ahmd0 Avatar asked May 09 '12 23:05

ahmd0


2 Answers

Here's a simple class:

public class IPSubnet
{
    private readonly byte[] _address;
    private readonly int _prefixLength;

    public IPSubnet(string value)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        string[] parts = value.Split('/');
        if (parts.Length != 2)
            throw new ArgumentException("Invalid CIDR notation.", "value");

        _address = IPAddress.Parse(parts[0]).GetAddressBytes();
        _prefixLength = Convert.ToInt32(parts[1], 10);
    }

    public bool Contains(string address)
    {
        return this.Contains(IPAddress.Parse(address).GetAddressBytes());
    }

    public bool Contains(byte[] address)
    {
        if (address == null)
            throw new ArgumentNullException("address");

        if (address.Length != _address.Length)
            return false; // IPv4/IPv6 mismatch

        int index = 0;
        int bits = _prefixLength;

        for (; bits >= 8; bits -= 8)
        {
            if (address[index] != _address[index])
                return false;
            ++index;
        }

        if (bits > 0)
        {
            int mask = (byte)~(255 >> bits);
            if ((address[index] & mask) != (_address[index] & mask))
                return false;
        }

        return true;
    }
}

Sample usage:

Console.WriteLine(new IPSubnet("192.168.168.100/24").Contains("192.168.168.200")); // True
Console.WriteLine(new IPSubnet("fe80::202:b3ff:fe1e:8329/24").Contains("2001:db8::")); // False

This class treats all IPv4 addresses as distinct from all IPv6 addresses, making no attempt to translate between IPv4 and IPv6.

like image 88
Michael Liu Avatar answered Oct 24 '22 07:10

Michael Liu


I'm not going to write code for you but:

  • http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx
  • http://blogs.msdn.com/b/knom/archive/2008/12/31/ip-address-calculations-with-c-subnetmasks-networks.aspx
  • Is IP address on the same subnet as the local machine (with IPv6 support)
  • Calculating all addresses within a subnet...for IPv6

should be enough to get you started.

Good luck

like image 39
LukeP Avatar answered Oct 24 '22 06:10

LukeP