Here I have a static reference the ranges I need to check:
private static List<string> 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"
};
Here's some pseudo code on how I see it working:
public static bool IpIsWithinRange(string ip) //Something like 127.0.0.1 or 184.56.26.35
{
IPAddress incomingIp = IPAddress.Parse(ip);
foreach (var subnet in Ip_Range)
{
IPAddress sub = IPAddress.Parse(subnet); ?????
if (incomingIp "is in" sub) ?
return true;
}
return false;
}
Any suggestions on how to code up this functionality?
If you understand the CIDR notation, you can easily do the math in your parse method.
You basically know that an IPv4 address is 32bits long and that the CIDR notation means that the number of bits behind the "/" are the network address bits (ie the masked out bits), therefore the leftover bits are represent the number of hosts in the subnet.
From wikipedia article:
So you could (no I'm not going to work out the details for you) convert your addresses into binary and do the binary AND with the given mask (also in binary form), then you have the network address part of the IP address left, which should match with whatever address you're checking against to see if it's in a particular subnet.
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! Below is the code I used:
Luckily most of the work has already been done for you (so we don't have to). Check out the IPNetwork project. You'll parse all of your CIDR addresses with
IPNetwork.Parse
. Then to see if a specificIPAddress
is in range just useIPNetwork.Contains
method.I got bored so here's a method you can use to test whether an IP address is in range or not:
This is dependent on the
Ip_Range
list from your question but translates them toIPNetwork
instances (missing sanity checks for brevity).Usage:
Test Output:
Of course there is still a lot that could (and probably should) be done with it, but this proves the concept.
If you don't want/can't add another library (as the IPnetwork one) to your project and just need to deal with IPv4 CIDR ranges, here's a quick solution to your problem
the above will allow you to quickly check if a given IPv4 address falls inside a given CIDR range; notice that the above code is barebone, it's up to you to check if a given IP (string) and CIDR range are correct before feeding them to the function (you may just use the tryparse or whatever...)
For start, you should use that:
Output