Sunday, April 03, 2011

Check is IP in range

You can find countless examples how to check is IP in range. I would like to offer my way for solution with LINQ:

using System.Collections.Generic;
using System.Net;
using System.Linq;


 public class IPRange
    {
        public byte[] StartAddressBytes { get; private set; }
        public byte[] EndAddressBytes { get; private set; }

        public IPRange(IPAddress startAddress, IPAddress endAddress)
        {
            StartAddressBytes = startAddress.GetAddressBytes();
            EndAddressBytes = endAddress.GetAddressBytes();
        }
        public IPRange(string strartIp, string endIp)
        {
            IPAddress startAddress, endAddress;
            if (IPAddress.TryParse(strartIp, out startAddress) 

                && IPAddress.TryParse(endIp, out endAddress))
            {
                StartAddressBytes = startAddress.GetAddressBytes();
                EndAddressBytes = endAddress.GetAddressBytes();
            }
        }
    }

//--------------------------
public class IPRangeUtil
    {
        public static bool IsInRange(List<
IPRange> ipRange , string clientIp)
        {
            IPAddress clientAddress;
            if (!IPAddress.TryParse(clientIp, out clientAddress))
            {
                return false;
            }
            return IsInRange(ipRange, clientAddress);
        }
        public static bool IsInRange(
List<IPRange> ipRange, IPAddress clientAddress)
        {
            int clientIpSum = clientAddress.GetAddressBytes().Sum(item => item);
            return ipRange.Where(range =>
                clientIpSum >= range.StartAddressBytes.Sum(item => item)
                && clientIpSum <= range.EndAddressBytes.Sum(item => item)).Any() ;
        }
    }



A using is very easy:
 List ranges = new List
                    {
                        //You can replace "xxx.xxx.xxx.xxx" to IPAddress typed variable 
                          new IPRange("192.168.10.68", "192.168.10.255"),
                          new IPRange("192.168.0.68h", "192.168.10.68")
                    };


bool isInRange = IPRangeUtil.IsInRange(ranges, "192.168.10.70");





Enjoy!





kick it on DotNetKicks.com

2 comments:

Dudu said...

It does not work - it returns true on IP addresses outside of the ranges scope...

Nicolas Boucher said...

Nice approach, but this can't work since you sum the bytes ignoring their bases. So with your method, 192.168.1.1=192.168.0.2=191.169.1.1

The IPAddress class already has a property "Address" which gives you a "long" conversion of IP bytes representation, here's a corrected version of your script:

public class IPRange
{
public IPAddress StartAddress { get; private set; }
public IPAddress EndAddress { get; private set; }

public IPRange(IPAddress startAddress, IPAddress endAddress)
{
StartAddress = startAddress;
EndAddress = endAddress;
}
public IPRange(string strartIp, string endIp)
{
IPAddress startAddress, endAddress;
if (IPAddress.TryParse(strartIp, out startAddress)
&& IPAddress.TryParse(endIp, out endAddress))
{
StartAddress = startAddress;
EndAddress = endAddress;
}
}
}
//--------------------------
public class IPRangeUtil
{
public static bool IsInRange(List ipRange , string clientIp)
{
IPAddress clientAddress;
if (!IPAddress.TryParse(clientIp, out clientAddress))
{
return false;
}
return IsInRange(ipRange, clientAddress);
}
public static bool IsInRange(List ipRange, IPAddress clientAddress)
{

return ipRange.Where(range =>
clientAddress.Address >= range.StartAddress.Address
&& clientAddress.Address <= range.EndAddress.Address).Any() ;
}
}