Skip to content Skip to sidebar Skip to footer

Javascript: Is Ip In One Of These Subnets?

So I have ~12600 subnets: eg. 123.123.208.0/20 and an IP. I can use a SQLite Database or an array or whatever There was a similar question asked about a month ago, however I am no

Solution 1:

The best approach is IMO making use of bitwise operators. For example, 123.123.48.0/22 represents (123<<24)+(123<<16)+(48<<8)+0 (=2071670784; this might be a negative number) as a 32 bit numeric IP address, and -1<<(32-22) = -1024 as a mask. With this, and likewise, your test IP address converted to a number, you can do:

(inputIP & testMask) == testIP

For example, 123.123.49.123 is in that range, as 2071671163 & -1024 is 2071670784

So, here are some tool functions:

functionIPnumber(IPaddress) {
    var ip = IPaddress.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
    if(ip) {
        return (+ip[1]<<24) + (+ip[2]<<16) + (+ip[3]<<8) + (+ip[4]);
    }
    // else ... ?returnnull;
}

functionIPmask(maskSize) {
    return -1<<(32-maskSize)
}

test:

(IPnumber('123.123.49.123') & IPmask('22')) == IPnumber('123.123.48.0')

yields true.

In case your mask is in the format '255.255.252.0', then you can use the IPnumber function for the mask, too.

Solution 2:

Try this:

var ip2long = function(ip){
    var components;

    if(components = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))
    {
        var iplong = 0;
        var power  = 1;
        for(var i=4; i>=1; i-=1)
        {
            iplong += power * parseInt(components[i]);
            power  *= 256;
        }
        return iplong;
    }
    elsereturn -1;
};

var inSubNet = function(ip, subnet)
{   
    var mask, base_ip, long_ip = ip2long(ip);
    if( (mask = subnet.match(/^(.*?)\/(\d{1,2})$/)) && ((base_ip=ip2long(mask[1])) >= 0) )
    {
        var freedom = Math.pow(2, 32 - parseInt(mask[2]));
        return (long_ip > base_ip) && (long_ip < base_ip + freedom - 1);
    }
    elsereturnfalse;
};

Usage:

inSubNet('192.30.252.63', '192.30.252.0/22') => trueinSubNet('192.31.252.63', '192.30.252.0/22') => false

Solution 3:

I managed to solve this by using the node netmask module. You can check if an IP belongs to a subnet by making something like this:

import { Netmask } from'netmask'const block = newNetmask('123.123.208.0/20')
const ip = '123.123.208.0'console.log(block.contains(ip))

Will here print true.

You can install it by using:

npm i--save netmask

Solution 4:

Convert the lower ip and the upper ip in the range to integers and store the range in the db then make sure both columns are indexed.

Off the top of my head (pseudo code):

functionipmap(w,x,y,z) {
  return16777216*w + 65536*x + 256*y + z;
}

var masks = array[ipmap(128,0,0,0), ipmap(196,0,0,0), ..., ipmap(255,255,255,255)]

functionlowrange(w, x, y, z, rangelength) {
  return ipmap(w, x, y, z) & masks[rangelength]
}

functionhirange(w, x, y, z, rangelength) {
  return lowrange(w, x, y, z, ,rangelength) + ipmap(255,255,255,255) - masks[rangelength];
}

That ought to do it.

To find whether a particular ip falls in any of the ranges, convert it to an integer and do:

SELECTCOUNT(*) FROM ipranges WHERE lowrange <=1234567AND1234567<= highrange

The query optimizer should be able to speed this up greatly.

Solution 5:

Functions IPnumber and IPmask are nice, however I would rather test like:

(IPnumber('123.123.49.123') & IPmask('22')) == (IPnumber('123.123.48.0')  & IPmask('22'))

Because for each address, you only need to take into account the network part of the address. Hence doing IPmask('22') will zero-out the computer part of the address and you should do the same with the network address.

Post a Comment for "Javascript: Is Ip In One Of These Subnets?"