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:
192.168.168.100/24
, IP to check: 192.168.168.200
fe80::202:b3ff:fe1e:8329/24
, IP to check: 2001:db8::
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.
I'm not going to write code for you but:
should be enough to get you started.
Good luck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With