Files
cloudron-box/src/ipaddr.js

63 lines
1.7 KiB
JavaScript
Raw Normal View History

2025-05-06 16:16:33 +02:00
'use strict';
exports = module.exports = {
isValid,
isValidCIDR,
isEqual,
includes,
};
const assert = require('node:assert'),
net = require('node:net');
2025-05-06 16:16:33 +02:00
function isValid(ip) {
assert.strictEqual(typeof ip, 'string');
const type = net.isIP(ip);
return type === 4 || type === 6;
}
function isValidCIDR(cidr) {
assert.strictEqual(typeof cidr, 'string');
const parts = cidr.split('/');
if (parts.length !== 2) return false;
const [ ip, prefixString ] = parts;
const type = net.isIP(ip);
if (type === 0) return false;
const prefix = Number.parseInt(prefixString, 10);
if (!Number.isInteger(prefix) || prefix < 0 || (prefix > (type === 4 ? 32 : 128)) || String(prefix) !== prefixString) return false;
return true;
}
function isEqual(ip1, ip2) {
assert.strictEqual(typeof ip1, 'string');
assert.strictEqual(typeof ip2, 'string');
if (ip1 === ip2) return true;
const type1 = net.isIP(ip1), type2 = net.isIP(ip2);
if (type1 === 0 || type2 === 0) return false; // otherwise, it will throw invalid socket address below
// use blocklist to compare since strings may not be in RFC 5952 format
const blockList = new net.BlockList();
blockList.addAddress(ip1, `ipv${type1}`);
return blockList.check(ip2, `ipv${type2}`);
}
function includes(cidr, ip) {
assert.strictEqual(typeof cidr, 'string');
assert.strictEqual(typeof ip, 'string');
const type = net.isIP(ip);
const [ subnet, prefix ] = cidr.split('/');
const subnetType = net.isIP(subnet);
const blockList = new net.BlockList();
blockList.addSubnet(subnet, parseInt(prefix, 10), `ipv${subnetType}`);
return blockList.check(ip, `ipv${type}`);
}