Comparing version 1.0.2 to 1.0.3
66
acl.js
@@ -22,2 +22,7 @@ // pixl-acl | ||
ranges.forEach( function(str) { | ||
// convert IP ranges to CIDR format | ||
if (str.match(/\-/)) { | ||
str = self.parseRange(str); | ||
} | ||
if (!str.match(/\/\d+$/)) { | ||
@@ -107,3 +112,64 @@ // try to guess bits (i.e. partial IP was passed in) | ||
parseRange(str) { | ||
// parse dash-delimited IP range (e.g. '8.12.144.0 - 8.12.144.255') into CIDR block (e.g. '8.12.144.0/24') | ||
// suppport IPv4 and IPv6 | ||
var parts = str.split(/\s*\-\s*/); | ||
var start_ip = parts[0].trim(); | ||
var end_ip = parts[1].trim(); | ||
if (start_ip.match(/^\d+\.\d+\.\d+\.\d+$/)) return rangeToCIDR(start_ip, end_ip); | ||
else return rangeToCIDRv6(start_ip, end_ip); | ||
} | ||
}; // class | ||
// Internal Utility Functions: | ||
function ipToInteger(ip) { | ||
return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0); | ||
} | ||
function integerToIP(int) { | ||
return [int >>> 24, int >> 16 & 255, int >> 8 & 255, int & 255].join('.'); | ||
} | ||
function rangeToCIDR(startIP, endIP) { | ||
const start = ipToInteger(startIP); | ||
const end = ipToInteger(endIP); | ||
const range = end - start + 1; | ||
const bits = Math.floor(Math.log2(range)); | ||
const mask = 32 - bits; | ||
const cidr = integerToIP(start & (0xFFFFFFFF << bits)) + '/' + mask; | ||
return cidr; | ||
} | ||
function ipv6ToBigInt(ipv6) { | ||
const sections = ipv6.split(':').map(section => parseInt(section, 16)); | ||
return sections.reduce((acc, section) => acc * 65536n + BigInt(section), 0n); | ||
} | ||
function bigIntToIPv6(bigInt) { | ||
const parts = []; | ||
for (let i = 0; i < 8; i++) { | ||
parts.unshift((bigInt & 0xffffn).toString(16)); | ||
bigInt >>= 16n; | ||
} | ||
return parts.join(':'); | ||
} | ||
function rangeToCIDRv6(startIP, endIP) { | ||
const start = ipv6ToBigInt(startIP); | ||
const end = ipv6ToBigInt(endIP); | ||
const range = end - start + 1n; | ||
const bits = BigInt(Math.floor(Math.log2(Number(range)))); | ||
const mask = 128n - bits; | ||
let cidr = bigIntToIPv6(start & (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn << bits)) + '/' + mask; | ||
// Replace consecutive groups of zeros with '::' | ||
cidr = cidr.replace(/(?:0(?::0)+)(?::(?:0(?::0)*)?)/, '::'); | ||
// Remove leading zeros | ||
cidr = cidr.replace(/(?:^|:)0+(?=[0-9a-f])/g, ':'); | ||
return cidr.replace(/::/, ':'); | ||
} |
{ | ||
"name": "pixl-acl", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "A simple but fast implementation of IPv4 and IPv6 ACL filtering.", | ||
@@ -5,0 +5,0 @@ "author": "Joseph Huckaby <jhuckaby@gmail.com>", |
@@ -16,3 +16,3 @@ # Overview | ||
```js | ||
var ACL = require('pixl-acl'); | ||
const ACL = require('pixl-acl'); | ||
``` | ||
@@ -23,4 +23,4 @@ | ||
```js | ||
var acl = new ACL( "10.0.0.0/8" ); | ||
var acl = new ACL([ "10.11.12.13", "fd00::/8" ]); | ||
let acl = new ACL( "10.0.0.0/8" ); | ||
let acl = new ACL([ "10.11.12.13", "fd00::/8" ]); | ||
``` | ||
@@ -44,2 +44,8 @@ | ||
IP ranges are also accepted. Make sure they are separated by a dash (and zero or more spaces): | ||
```js | ||
acl.add( "8.12.144.0 - 8.12.144.255" ); | ||
``` | ||
## Matching IP Addresses | ||
@@ -78,3 +84,3 @@ | ||
```js | ||
var acl = new ACL([ "::1/128", "127.0.0.1/32", "169.254.0.0/16", "fe80::/10", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8" ]); | ||
let acl = new ACL([ "::1/128", "127.0.0.1/32", "169.254.0.0/16", "fe80::/10", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8" ]); | ||
``` | ||
@@ -102,3 +108,3 @@ | ||
*Copyright (c) 2018 Joseph Huckaby.* | ||
*Copyright (c) 2018 - 2023 Joseph Huckaby.* | ||
@@ -105,0 +111,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
10785
146
123