How to Check a Input Ip Fall in a Specific Ip Range

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

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

Check if Ip address in range

Using the IPNetwork class from Codeplex, you can do the following:

//see http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
ReadOnlyCollection<IPNetwork> reservedNetworks =
new ReadOnlyCollection<IPNetwork>(new[]
{
IPNetwork.Parse("0.0.0.0/8"),
IPNetwork.Parse("10.0.0.0/8"),
IPNetwork.Parse("127.0.0.0/8"),
IPNetwork.Parse("169.254.0.0/16"),
IPNetwork.Parse("172.16.0.0/12"),
IPNetwork.Parse("192.0.2.0/24"),
IPNetwork.Parse("192.88.99.0/24"),
IPNetwork.Parse("192.168.0.0/16"),
IPNetwork.Parse("198.18.0.0/15"),
IPNetwork.Parse("198.51.100.0/24"),
IPNetwork.Parse("203.0.113.0/24"),
IPNetwork.Parse("224.0.0.0/4"),
IPNetwork.Parse("240.0.0.0/4")
});

var isInRange =
!reservedNetworks.Any(n => IPNetwork.Contains(n, suspiciousIpAddress));

How to see if an IP address belongs inside of a range of IPs using CIDR notation?

Decided to answer my own question so people can benefit. If it can be improved, please do!

I used the IPNetwork library and it worked out fantastically!

nuget install IPNetwork2

Below is the code I used:

using System.Net;

public static class RedirectHelpers
{
public static bool IpIsWithinBoliviaRange(string ip)
{
IPAddress incomingIp = IPAddress.Parse(ip);
foreach (var subnet in Bolivia_Ip_Range)
{
IPNetwork network = IPNetwork.Parse(subnet);

if (IPNetwork.Contains(network, incomingIp))
return true;
}
return false;
}

private static List<string> Bolivia_Ip_Range = new List<string>()
{
"12.144.86.0/23",
"31.201.1.176/30",
"46.36.198.101/32",
"46.36.198.102/31",
"46.36.198.104/31",
"46.136.172.0/24",
"63.65.11.0/24",
"63.65.12.0/25",
"63.65.12.128/26",
"63.65.12.192/27",
"63.65.12.224/28",
"63.65.12.240/29",
"63.65.12.248/30",
"63.65.12.252/31",
"63.65.12.254/32",
"65.173.56.0/21",
"67.23.241.179/32",
"67.23.241.180/30",
"67.23.241.184/29",
"67.23.241.192/30",
"67.23.241.196/31",
"67.23.241.198/32",
"72.32.164.56/29",
"72.46.244.32/28",
"74.91.16.48/29",
"74.91.16.208/29",
"74.91.20.48/28",
"74.91.20.64/29",
"74.112.134.120/29",
"74.112.135.104/29",
"74.205.37.16/29",
"78.24.205.32/28",
"98.129.27.88/29",
"98.129.91.40/29",
"166.114.0.0/16",
"167.157.0.0/16",
"174.143.165.80/29",
"186.0.156.0/22",
"186.2.0.0/17",
"186.27.0.0/17",
"190.0.248.0/21",
"190.3.184.0/21",
"166.114.0.0/16",
"167.157.0.0/16",
"186.2.0.0/18",
"190.11.64.0/20",
"190.11.80.0/20",
"190.103.64.0/20",
"190.104.0.0/19",
"190.107.32.0/20",
"190.129.0.0/17",
"190.181.0.0/18",
"190.186.0.0/18",
"190.186.64.0/18",
"190.186.128.0/18",
"200.7.160.0/20",
"200.58.64.0/20",
"200.58.80.0/20",
"200.58.160.0/20",
"200.58.176.0/20",
"200.75.160.0/20",
"200.85.128.0/20",
"200.87.0.0/17",
"200.87.128.0/17",
"200.105.128.0/19",
"200.105.160.0/19",
"200.105.192.0/19",
"200.112.192.0/20",
"200.119.192.0/20",
"200.119.208.0/20",
"201.222.64.0/19",
"201.222.96.0/19"
};
}

How to check if an IP address is within a particular subnet

Using the answers from Thomas and Chris together with Ciscos Subnetting Examples I finally got something to work for IPv4 and IPv6 if you use the CIDR notation (IPAddress/PrefixLength). My IPv6-Implementation might be a bit too straight forward but as there is no UInt128-datatype I couldn't adapt Thomas's solution. Here is the code that seems to work well:

public static bool IsInSubnet(this IPAddress address, string subnetMask)
{
var slashIdx = subnetMask.IndexOf("/");
if (slashIdx == -1)
{ // We only handle netmasks in format "IP/PrefixLength".
throw new NotSupportedException("Only SubNetMasks with a given prefix length are supported.");
}

// First parse the address of the netmask before the prefix length.
var maskAddress = IPAddress.Parse(subnetMask.Substring(0, slashIdx));

if (maskAddress.AddressFamily != address.AddressFamily)
{ // We got something like an IPV4-Address for an IPv6-Mask. This is not valid.
return false;
}

// Now find out how long the prefix is.
int maskLength = int.Parse(subnetMask.Substring(slashIdx + 1));

if (maskLength == 0)
{
return true;
}

if (maskLength < 0)
{
throw new NotSupportedException("A Subnetmask should not be less than 0.");
}

if (maskAddress.AddressFamily == AddressFamily.InterNetwork)
{
// Convert the mask address to an unsigned integer.
var maskAddressBits = BitConverter.ToUInt32(maskAddress.GetAddressBytes().Reverse().ToArray(), 0);

// And convert the IpAddress to an unsigned integer.
var ipAddressBits = BitConverter.ToUInt32(address.GetAddressBytes().Reverse().ToArray(), 0);

// Get the mask/network address as unsigned integer.
uint mask = uint.MaxValue << (32 - maskLength);

// https://stackoverflow.com/a/1499284/3085985
// Bitwise AND mask and MaskAddress, this should be the same as mask and IpAddress
// as the end of the mask is 0000 which leads to both addresses to end with 0000
// and to start with the prefix.
return (maskAddressBits & mask) == (ipAddressBits & mask);
}

if (maskAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
// Convert the mask address to a BitArray. Reverse the BitArray to compare the bits of each byte in the right order.
var maskAddressBits = new BitArray(maskAddress.GetAddressBytes().Reverse().ToArray());

// And convert the IpAddress to a BitArray. Reverse the BitArray to compare the bits of each byte in the right order.
var ipAddressBits = new BitArray(address.GetAddressBytes().Reverse().ToArray());
var ipAddressLength = ipAddressBits.Length;

if (maskAddressBits.Length != ipAddressBits.Length)
{
throw new ArgumentException("Length of IP Address and Subnet Mask do not match.");
}

// Compare the prefix bits.
for (var i = ipAddressLength - 1; i >= ipAddressLength - maskLength; i--)
{
if (ipAddressBits[i] != maskAddressBits[i])
{
return false;
}
}

return true;
}

throw new NotSupportedException("Only InterNetworkV6 or InterNetwork address families are supported.");
}

And this are the XUnit tests I tested it with:

public class IpAddressExtensionsTests
{
[Theory]
[InlineData("192.168.5.85/24", "192.168.5.1")]
[InlineData("192.168.5.85/24", "192.168.5.254")]
[InlineData("10.128.240.50/30", "10.128.240.48")]
[InlineData("10.128.240.50/30", "10.128.240.49")]
[InlineData("10.128.240.50/30", "10.128.240.50")]
[InlineData("10.128.240.50/30", "10.128.240.51")]
[InlineData("192.168.5.85/0", "0.0.0.0")]
[InlineData("192.168.5.85/0", "255.255.255.255")]
public void IpV4SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.True(ipAddressObj.IsInSubnet(netMask));
}

[Theory]
[InlineData("192.168.5.85/24", "192.168.4.254")]
[InlineData("192.168.5.85/24", "191.168.5.254")]
[InlineData("10.128.240.50/30", "10.128.240.47")]
[InlineData("10.128.240.50/30", "10.128.240.52")]
[InlineData("10.128.240.50/30", "10.128.239.50")]
[InlineData("10.128.240.50/30", "10.127.240.51")]
public void IpV4SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.False(ipAddressObj.IsInSubnet(netMask));
}

[Theory]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFFF")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0001:0000:0000:0000")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFF0")]
[InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
[InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:5000:0000:0000:0000:0000")]
[InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:57ff:ffff:ffff:ffff:ffff")]
[InlineData("2001:db8:abcd:0012::0/0", "::")]
[InlineData("2001:db8:abcd:0012::0/0", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]
public void IpV6SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.True(ipAddressObj.IsInSubnet(netMask));
}

[Theory]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFFF")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0000:0000:0000:0000")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0001:0000:0000:0000")]
[InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFF0")]
[InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0001")]
[InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:4999:0000:0000:0000:0000")]
[InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:5800:0000:0000:0000:0000")]
public void IpV6SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.False(ipAddressObj.IsInSubnet(netMask));
}
}

As base for the tests I used Ciscos Subnetting Examples and IBMs IPV6 address examples.

I hope someone finds this helpful ;)

How to check an IP address is within a range of two IPs in PHP?

With ip2long() it's easy to convert your addresses to numbers. After this, you just have to check if the number is in range:

if ($ip <= $high_ip && $low_ip <= $ip) {
echo "in range";
}

How do I check if an ip address is in a specific range in perl?

Using Net::IP and the overlaps method:

use strict;
use warnings;

use Net::IP;

my $range = Net::IP->new('100.0.0.0 - 200.79.255.255') or die Net::IP::Error();

while (<DATA>) {
chomp;
my $ip = Net::IP->new($_) or die Net::IP::Error();
my $match = $range->overlaps($ip) ? "(match)" : "";
print "$_ $match\n";
}

__DATA__
10.0.0.1
99.99.99.99
100.0.0.1
124.21.23.5
200.79.255.1
200.80.1.1

Outputs:

10.0.0.1
99.99.99.99
100.0.0.1 (match)
124.21.23.5 (match)
200.79.255.1 (match)
200.80.1.1

check if an IP is within a range of CIDR in Python

You can't really do string comparisons on a dot separated list of numbers because your test will simply fail on input say 1.1.99.99 as '9' is simply greater than '2'

>>> '1.1.99.99' < '1.1.255.255'
False

So instead you can convert the input into tuples of integers through comprehension expression

def convert_ipv4(ip):
return tuple(int(n) for n in ip.split('.'))

Note the lack of type checking, but if your input is a proper IP address it will be fine. Since you have a 2-tuple of IP addresses, you can create a function that takes both start and end as argument, pass that tuple in through argument list, and return that with just one statement (as Python allows chaining of comparisons). Perhaps like:

def check_ipv4_in(addr, start, end):
return convert_ipv4(start) < convert_ipv4(addr) < convert_ipv4(end)

Test it out.

>>> ip_range = ('1.1.0.0', '1.1.255.255')
>>> check_ipv4_in('1.1.99.99', *ip_range)
True

With this method you can lazily expand it to IPv6, though the conversion to and from hex (instead of int) will be needed instead.

validating if a user entered an ip address or CIDR notation when prompted

The ipaddress class does not appear to provide any convenience methods for determinig whether a string represents a valid IPv4 address versus a valid IPv4 network versus neither a valid address or network.

However, you can build your own rudimentary functionality to check to see if one or the other throws an exception and return true or false and use it in your conditional:

import ipaddress
def valid_ip_or_cidr(ip):
try:
ipaddress.IPv4Address(ip)
print('valid as address')
return True
except:
try:
ipaddress.IPv4Network(ip)
print('valid as network')
return True
except:
print('invalid as both an address and network')
return False


valid_ip_or_cidr('192.168.1.1')
# valid as address
# True
valid_ip_or_cidr('192.168.1.0/24')
# valid as network
# True
valid_ip_or_cidr('foo')
# invalid as both an address and network
# False

In your context, this would be implemented in your conditional as:

newIpAddress = input("Please enter the IP address for SFTP access: ")
if valid_ip_or_cidr(newIpAddress):
# code to execute if validation succeeds


Related Topics



Leave a reply



Submit