How to check a input IP fall in a specific IP range

C#asp.net

C# Problem Overview


If we let users input a couple of ip ranges, e.g., 172.16.11.5 - 100, how could I write a function to check if a IP (172.16.11.50) falls in the ranges?

Is there any existing library in .NET to leverage?

C# Solutions


Solution 1 - C#

There's nothing built into the framework, but it wouldn't take much effort to create an IPAddressRange class.

You'd compare the ranges by calling IPAddress.GetAddressBytes on the lower address, upper address and comparison address. Starting at the first byte, check if the comparison address is in the range of the upper/lower address.

This method works for both IPv4 and IPv6 addresses.

public class IPAddressRange
{
    readonly AddressFamily addressFamily;
    readonly byte[] lowerBytes;
    readonly byte[] upperBytes;

    public IPAddressRange(IPAddress lowerInclusive, IPAddress upperInclusive)
    {
        // Assert that lower.AddressFamily == upper.AddressFamily

        this.addressFamily = lowerInclusive.AddressFamily;
        this.lowerBytes = lowerInclusive.GetAddressBytes();
        this.upperBytes = upperInclusive.GetAddressBytes();
    }

    public bool IsInRange(IPAddress address)
    {
        if (address.AddressFamily != addressFamily)
        {
            return false;
        }

        byte[] addressBytes = address.GetAddressBytes();

        bool lowerBoundary = true, upperBoundary = true;

        for (int i = 0; i < this.lowerBytes.Length && 
            (lowerBoundary || upperBoundary); i++)
        {
            if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
                (upperBoundary && addressBytes[i] > upperBytes[i]))
            {
                return false;
            }

            lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
            upperBoundary &= (addressBytes[i] == upperBytes[i]);
        }

        return true;
    }
}

NB: The above code could be extended to add public static factory methods FromCidr(IPAddress address, int bits)

Solution 2 - C#

You might want to consider this library by @jsakamoto, which allows you to parse range of IP address string such as "192.168.0.0/24" and "192.168.0.0/255.255.255.0" and "192.168.0.0-192.168.0.255", and can conatins check. This library supports both IPv4 and IPv6.

https://github.com/jsakamoto/ipaddressrange

It can also be installed via NuGet:

http://www.nuget.org/packages/IPAddressRange/

using NetTools;
...
// rangeA.Begin is "192.168.0.0", and rangeA.End is "192.168.0.255".
var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0");
rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.
rangeA.ToCidrString(); // is 192.168.0.0/24

// rangeB.Begin is "192.168.0.10", and rangeB.End is "192.168.10.20".
var rangeB1 = IPAddressRange.Parse("192.168.0.10 - 192.168.10.20");
rangeB1.Contains(IPAddress.Parse("192.168.3.45")); // is True.
rangeB1.Contains(IPAddress.Parse("192.168.0.9")); // is False.

// Support shortcut range description. 
// ("192.168.10.10-20" means range of begin:192.168.10.10 to end:192.168.10.20.)
var rangeB2 = IPAddressRange.Parse("192.168.10.10-20");

// Support CIDR expression and IPv6.
var rangeC = IPAddressRange.Parse("fe80::/10"); 
rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
rangeC.Contains(IPAddress.Parse("::1")); // is False.

Solution 3 - C#

public static bool IsInRange(string startIpAddr, string endIpAddr, string address)
{
    long ipStart = BitConverter.ToInt32(IPAddress.Parse(startIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ipEnd = BitConverter.ToInt32(IPAddress.Parse(endIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ip = BitConverter.ToInt32(IPAddress.Parse(address).GetAddressBytes().Reverse().ToArray(), 0);

    return ip >= ipStart && ip <= ipEnd; //edited
}

Console.WriteLine(IsInRange("100.0.0.1", "110.0.0.255", "102.0.0.4"));//true

Solution 4 - C#

The best is to convert these addresses to an integer and then perform comparisons.

Example from here: IP to Integer

To convert an IP address to integer, break it into four octets. For example, the ip address you provided can be broken into:

First Octet: 	217
Second Octet: 	110
Third Octet: 	18
Fourth Octet: 	206

To calculate the decimal address from a dotted string, perform the following calculation.

	(first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)
= 	(first octet * 16777216) + (second octet * 65536) + (third octet * 256) + (fourth octet)
= 	(217 * 16777216) + (110 * 65536) + (18 * 256) + (206)
= 	3647869646

Considering IPv6, you can convert them to integers (128bit vs 32bit IPv4) as well. Have a look at this question: Formatting IPv6 as an int in C# and storing it in SQL Server

> The simplest route is to get the > framework to do this for you. Use > IPAddress.Parse to parse the address, > then IPAddress.GetAddressBytes to get > the "number" as byte[].

Solution 5 - C#

I used this code on codeproject before, which may be of use to you.

http://www.codeproject.com/KB/IP/ipnumbers.aspx

You have the possibility to add to IPList a range of IP numbers defined by a From IP and a To IP number. The method breaks up the range into standard IP ranges and finds their masks. So the range "10.0.0.5" to "10.0.0.20" will be broken up to the following ranges and added to the list: 10.0.0.5, 10.0.0.20, 10.0.0.6/31, 10.0.0.16/30 and 10.0.0.8/29 and you'll have the possibility to check against that.

> Disclaimer: The Class is only tested with simple data sets, and the > Class lacks validation of the IP numbers and IP masks provided. This > should be fixed before it is used in production environments.

Solution 6 - C#

reposting my answer from here

A while ago, I had to find the location of a given IP. We got the IP from the request. There are free databases which gave us this mapping. In IPv4, when we say the IP as "a.b.c.d" it is essentially a * (256^3) + b * (256^2) + c * (256) + d.

http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp

so when you say you want an IP address starting with "a", you are looking for IPs between a * 256^ 3 and a * 256^3 + 256 * (256^2) (b = 256) + 256 *(256) (c=256) + 256( d=256) (lower / upper limit may vary a little bit depending on whether you want to include/exclude the limits).

That said, there are specific IPs reserved for specific purposes(like 127.0.0.1 which is localhost, 0.0.0.0 cannot be an IP etc).

So your linq query would be

from i in iList where i >= MIN && i <= MAX select i;

where iList is your initial list MIN is your min value for your range MAX is your max value for your range

Solution 7 - C#

Could you figure out the subnet mask from your IP range?

If so then maybe you could use this IsInSameSubnet method..

Solution 8 - C#

I want to +1 BuddhiP's answer above which recommends the IPAddressRange package from NuGet: https://www.nuget.org/packages/IPAddressRange/

But because code formatting is hard in a comment I'll just add a practical code example here on how to use IPAddressRange.

CheckIPWhitelist reads a setting called IPWhitelist and assumes a semi-colon delimited list of IP ranges (such as "192.168.10.10-20;192.168.125.1-150;192.168.123.1-150") that IPAddressRange can parse. The function iterates the ranges and will and return true if present, false if not found.

This function is VB.NET and assumes some ASP.NET dependencies are present (such as the System.Web.HttpRequest namespace)

Imports NetTools ' ref. https://www.nuget.org/packages/IPAddressRange/

Function CheckIPWhitelist() As Boolean
	Dim match As Boolean = False
	Dim SourceIP As String = Request.UserHostAddress()

	' Examples of valid IPWhitelist ranges 
	' one range in longhand range format: "192.168.0.10 - 192.168.10.20"
	' one range in shorthand range format: "192.168.10.10-20"
	' multiple ranges separated by semicolons in shorthand range format: "192.168.10.10-20;192.168.125.1-150;192.168.123.1-150"
	Dim IPWhitelist As String = ConfigurationManager.AppSettings("IPWhitelist")

	Dim arrRanges As String() = IPWhitelist.Split(";")
	For i As Integer = 0 To arrRanges.Length - 1
		If arrRanges(i) IsNot Nothing Then
			Dim range As NetTools.IPAddressRange = IPAddressRange.Parse(arrRanges(i))
			If range.Contains(IPAddressRange.Parse(SourceIP)) = True Then
				match = True ' IP is in the whitelist, set a boolean
				Exit For
			End If
		End If
	Next
	Return match
End Function

Solution 9 - C#

You can remove dot at the middle of them and convert all IP to long at first, Then check them in an if :

var givenIp = Convert.ToInt64(clientIp.Replace(".", ""));
var startIp = Convert.ToInt64(startRange.Replace(".", ""));
var endIp = Convert.ToInt64(endRange.Replace(".", ""));

if (givenIp != startIp && givenIp != endIp && (givenIp < startIp || givenIp > endIp))
{
   Console.WriteLine("your ip does not allow to access!");
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRickyView Question on Stackoverflow
Solution 1 - C#Richard SzalayView Answer on Stackoverflow
Solution 2 - C#BuddhiPView Answer on Stackoverflow
Solution 3 - C#artwlView Answer on Stackoverflow
Solution 4 - C#user151323View Answer on Stackoverflow
Solution 5 - C#Aim KaiView Answer on Stackoverflow
Solution 6 - C#ramView Answer on Stackoverflow
Solution 7 - C#IanView Answer on Stackoverflow
Solution 8 - C#Jeff MerglerView Answer on Stackoverflow
Solution 9 - C#Minoo MoradiView Answer on Stackoverflow