Our PHP friends have all the fun with their functions, like IP to long and what not. We’ve duplicated some of that.
For a recent project where orders coming from IPv4 addresses outside the country are flagged in our system as fraud, I ran into the problem that the free databases that correlate ISO country code to IP ranges no longer include the CIDR data.
Web service calls were unapproachable for the volume of the update, as there are any number of free services out there that will find the CIDR for a range of IPs for you.
Here are a couple of functions I banged out to quickly calculate the net mask value from a range. It’s not a catchall, mind you, there are always places where more subnets are applicable, but it seemed to work well for my purposes. And at any rate, given the paucity of information out there on the web for performing this kind of function with ColdFusion, I believe it’s ultimately helpful.
// Function: getOctet: Takes in a piece of an IPv4 address and returns the appropriate length binary string (i.e. 10101010)
function getOctet(ippart) {
var octetpart = FormatBaseN(ippart,2);
var addstring = "";
if (len(octetpart) lt
{
for ( i = 1; i lte (8 - len(octetpart)); i++ ) {
addstring &= 0;
}
}
return addstring & octetpart;
}
// Function: calcNetMask: depends on getOctet, takes in two IP addresses in a range and calculates the subnet mask and CIDR for the range, only works for very specific ranges
// i.e. countries
function calcNetMask(ip1,ip2) {
var Local = StructNew();
Local.binary1 = getOctet( ListGetAt(ip1,1,”.”)) & getOctet( ListGetAt(ip1,2,”.”)) & getOctet( ListGetAt(ip1,3,”.”)) & getOctet( ListGetAt(ip1,4,”.”));
Local.binary2 = getOctet( ListGetAt(ip2,1,”.”)) & getOctet( ListGetAt(ip2,2,”.”)) & getOctet( ListGetAt(ip2,3,”.”)) & getOctet( ListGetAt(ip2,4,”.”));
Local.subnet = ”;
for ( i = 1; i lte 32; i ++) {
if ( CompareNoCase( Mid(Local.binary1,i,1), Mid(Local.binary2,i,1) ) eq 0 ) {
Local.subnet &=1;
Local.netmask = i;
} else {
Local.subnet &=0;
Local.netmask = i – 1;
break;
}
}
if (len(Local.subnet) LT 32) {
addstring = “”;
for ( x = 1; x lte ( 32 – len(Local.subnet)); x++) {
addstring &= 0;
}
Local.subnet = Local.subnet & addstring;
}
Local.SubNetMask = InputBaseN( Mid(Local.subnet,1,8),2) & “.” & InputBaseN( Mid(Local.subnet,9,8),2) & “.” & InputBaseN( Mid(Local.subnet,17,8),2) & “.” & InputBaseN( Mid(Local.subnet,25,8),2);
// I like to clean up variables I’m not going to return
delkeys = ‘binary1,binary2,subnet’;
for ( n = 1; n lte listLen(DelKeys,”,”); n++) {
StructDelete(Local,ListGetAt(delkeys,n,”,”));
}
Local.CIDR = ip1 & “/” & Local.netmask;
return Local;
}
You’ll note that final function returns a structure of data. I don’t know, you might want to know some of those other values for your own edification.
It makes you wonder, though…how many of these functions are going to be orphaned as we more widely embrace IPv6. Right now, all I know about IPv6 are the issues I’ve had with DIG and DNS on Mac OS X. We’ll have to see.