Reputation:
I'd like to write a function in Javascript along the lines of:
in_subnet(ip, network, slash) {
...
}
in_subnet('1.2.3.4', '1.2.0.0', 16) # True, since it's in 1.2.0.0/16
in_subnet('1.2.3.4', '1.2.0.0', 24) # False, since it's not in 1.2.0.0/24
Should I write it from scratch, or are there some good libraries I could use? Or is the entire function already written and in the public domain?
Upvotes: 3
Views: 3717
Reputation: 1
function in_subnet(ip, subnet) {
let chunks = subnet.split('/')
let network = chunks[0]
let slash = Number(chunks[1])
addr_one = ip_addr_to_integer(ip) >> (32 - slash);
addr_two = ip_addr_to_integer(network) >> (32 - slash);
return (addr_one === addr_two);
}
function ip_addr_to_integer(ip) {
let chunks = ip.split('.')
let sum =
chunks[0] << 24
chunks[1] << 16
chunks[2] << 8
chunks[3]
return sum
}
This code does no input sanitation.
Use it like:
if (in_subnet('127.0.0.1', '127.0.0.0/8')) {
console.log('127.0.0.1 is in 127.0.0.0/8.')
} else {
console.log('Address is not in subnet.')
}
if (in_subnet('10.0.11.0', '10.0.10.0/24')) {
console.log('Address is in subnet.')
} else {
console.log('10.0.11.0 is not in 10.0.10.0/24.')
}
output:
127.0.0.1 is in 127.0.0.0/8.
10.0.11.0 is not in 10.0.10.0/24.
Based on answers by user1951756 and Dustin
Upvotes: 0
Reputation: 511
addr_one = ip_addr_to_integer(ip >> (32 - slash));
addr_two = ip_addr_to_integer(network >> (32 - slash));
return (addr_one == addr_two);
Bitwise operators stop working with 32 bits.
Upvotes: 0
Reputation: 49089
Pseudocode, building on dustin's answer:
addr_one = ip_addr_to_integer(ip);
addr_two = ip_addr_to_integer(network);
mask = ((1 << (32-slash)) - 1) ^ 0xFFFFFFFF;
return (((addr_one ^ addr_two) & mask) == 0);
If you know that the IP address strings are valid, you can probably use string.split('.') to get the four octets and easily convert them to an integer.
Upvotes: 4
Reputation: 90980
Go ahead and learn it. :)
The trick is to parse '1.2.3.4' into a single integer ( (1 << 24 | 2 << 16 | 3 << 8 | 4) == 16909060), and then '1.2.0.0' as an integer (16908288) and then the mask as the number of 1 bits from the msb as an integer (16 bits == 4294901760) and then apply the mask with bitwise and to the original address ((16909060 & 4294901760) == 16908288) if the masked address == the network address, then it's in the network.
Upvotes: 1