cidr-tools 4.3.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/index.js +51 -39
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -11,54 +11,54 @@ $ npm i cidr-tools
|
|
|
11
11
|
## Example
|
|
12
12
|
|
|
13
13
|
```js
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
import {merge, exclude, expand, overlap, contains, normalize} from 'cidr-tools';
|
|
15
|
+
|
|
16
|
+
merge(['1.0.0.0/24', '1.0.1.0/24']); //=> ['1.0.0.0/23']
|
|
17
|
+
exclude(['::1/127'], ['::1/128']) //=> ['::/128']
|
|
18
|
+
expand(['2001:db8::/126']) //=> ['2001:db8::', '2001:db8::1', '2001:db8::2', '2001:db8::3']
|
|
19
|
+
overlap('1.0.0.0/24', '1.0.0.128/25') //=> true
|
|
20
|
+
contains(["1.0.0.0/24", "2.0.0.0/24"], "1.0.0.1") //=> true
|
|
21
|
+
normalize('0:0:0:0:0:0:0:0/0') //=> '::/0'
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
## API
|
|
25
25
|
|
|
26
26
|
All functions take CIDR addresses or single IP addresses. On single addresses, a prefix of `/32` or `/128` is assumed. Function that return networks will return a merged and sorted set of networks with IPv4 sorted before IPv6.
|
|
27
27
|
|
|
28
|
-
###
|
|
28
|
+
### merge(networks)
|
|
29
29
|
|
|
30
30
|
- `networks` *String* or *Array*: One or more CIDR or IP addresses.
|
|
31
31
|
|
|
32
32
|
Returns an array of merged networks.
|
|
33
33
|
|
|
34
|
-
###
|
|
34
|
+
### exclude(baseNetworks, excludeNetworks)
|
|
35
35
|
|
|
36
36
|
- `baseNetworks` *String* or *Array*: One or more CIDR or IP addresses.
|
|
37
37
|
- `excludeNetworks` *String* or *Array*: One or more CIDR or IP addresses to exclude from `baseNetworks`.
|
|
38
38
|
|
|
39
39
|
Returns an array of merged remaining networks.
|
|
40
40
|
|
|
41
|
-
###
|
|
41
|
+
### expand(networks)
|
|
42
42
|
|
|
43
43
|
- `networks` *String* or *Array*: One or more CIDR or IP addresses.
|
|
44
44
|
|
|
45
45
|
Returns an array of individual IPs contained in the networks.
|
|
46
46
|
|
|
47
|
-
###
|
|
47
|
+
### overlap(networksA, networksB)
|
|
48
48
|
|
|
49
49
|
- `networksA` *String* or *Array*: One or more CIDR or IP address.
|
|
50
50
|
- `networksB` *String* or *Array*: One or more CIDR or IP address.
|
|
51
51
|
|
|
52
52
|
Returns a boolean that indicates if `networksA` overlap (intersect) with `networksB`.
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### contains(networksA, networksB)
|
|
55
55
|
|
|
56
56
|
- `networksA` *String* or *Array*: One or more CIDR or IP address.
|
|
57
57
|
- `networksB` *String* or *Array*: One or more CIDR or IP address.
|
|
58
58
|
|
|
59
59
|
Returns a boolean that indicates whether `networksA` fully contain all `networksB`.
|
|
60
60
|
|
|
61
|
-
###
|
|
61
|
+
### normalize(networks)
|
|
62
62
|
|
|
63
63
|
- `networks` *String* or *Array*: One or more CIDR or IP address.
|
|
64
64
|
|
package/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const {Address4, Address6} = require("ip-address");
|
|
9
|
-
const {BigInteger} = require("jsbn");
|
|
1
|
+
import IPCIDR from "ip-cidr";
|
|
2
|
+
import ipRegex from "ip-regex";
|
|
3
|
+
import isCidr from "is-cidr";
|
|
4
|
+
import ipv6Normalize from "ipv6-normalize";
|
|
5
|
+
import naturalCompare from "string-natural-compare";
|
|
6
|
+
import {stringify as stringifyIp} from "ip-bigint";
|
|
7
|
+
import {BigInteger} from "jsbn";
|
|
10
8
|
|
|
11
9
|
const bits = {
|
|
12
10
|
"v4": 32,
|
|
@@ -19,15 +17,26 @@ const zero = bigint("0");
|
|
|
19
17
|
const one = bigint("1");
|
|
20
18
|
const two = bigint("2");
|
|
21
19
|
|
|
20
|
+
function isIP(ip) {
|
|
21
|
+
if (ipRegex.v4({exact: true}).test(ip)) return 4;
|
|
22
|
+
if (ipRegex.v6({exact: true}).test(ip)) return 6;
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
function doNormalize(cidr) {
|
|
23
27
|
const cidrVersion = isCidr(cidr);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
// cidr
|
|
30
|
+
if (cidrVersion) {
|
|
31
|
+
// set network address to first address
|
|
32
|
+
let start = (new IPCIDR(cidr)).start();
|
|
33
|
+
if (cidrVersion === 6) start = ipv6Normalize(start).toString();
|
|
34
|
+
if (start) {
|
|
35
|
+
return `${start}${cidr.match(/\/.+/)}`.toLowerCase();
|
|
36
|
+
}
|
|
29
37
|
}
|
|
30
38
|
|
|
39
|
+
// single ip
|
|
31
40
|
const parsed = parse(cidr);
|
|
32
41
|
if (parsed && parsed.address && parsed.address.v4) {
|
|
33
42
|
return cidr;
|
|
@@ -38,27 +47,30 @@ function doNormalize(cidr) {
|
|
|
38
47
|
throw new Error(`Invalid network: ${cidr}`);
|
|
39
48
|
}
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
export function normalize(cidr) {
|
|
42
51
|
return Array.isArray(cidr) ? cidr.map(doNormalize) : doNormalize(cidr);
|
|
43
|
-
}
|
|
52
|
+
}
|
|
44
53
|
|
|
45
54
|
function parse(str) {
|
|
46
55
|
if (isCidr(str)) {
|
|
47
|
-
return new IPCIDR(
|
|
56
|
+
return new IPCIDR(normalize(str));
|
|
48
57
|
} else {
|
|
49
|
-
const version =
|
|
58
|
+
const version = isIP(str);
|
|
50
59
|
if (version) {
|
|
51
|
-
return new IPCIDR(
|
|
60
|
+
return new IPCIDR(normalize(`${str}/${bits[`v${version}`]}`));
|
|
52
61
|
} else {
|
|
53
62
|
throw new Error(`Network is not a CIDR or IP: ${str}`);
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
function format(number,
|
|
59
|
-
const cls = v === "v6" ? Address6 : Address4;
|
|
67
|
+
function format(number, version) {
|
|
60
68
|
if (!(number instanceof BigInteger)) number = bigint(number);
|
|
61
|
-
|
|
69
|
+
|
|
70
|
+
return normalize(stringifyIp({
|
|
71
|
+
number: BigInt(number.toString()),
|
|
72
|
+
version: Number(version.substring(1)),
|
|
73
|
+
}));
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
function uniq(arr) {
|
|
@@ -90,7 +102,7 @@ function doNetsOverlap(a, b) {
|
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
// returns whether network a fully contains network b;
|
|
93
|
-
function
|
|
105
|
+
function netContains(a, b) {
|
|
94
106
|
const {aStart, bStart, aEnd, bEnd} = getBoundaries(a, b);
|
|
95
107
|
|
|
96
108
|
// aaa
|
|
@@ -163,7 +175,7 @@ function excludeNets(a, b, v) {
|
|
|
163
175
|
}
|
|
164
176
|
}
|
|
165
177
|
|
|
166
|
-
return
|
|
178
|
+
return merge(remaining);
|
|
167
179
|
}
|
|
168
180
|
|
|
169
181
|
function biggestPowerOfTwo(num) {
|
|
@@ -266,7 +278,7 @@ function mapNets(nets) {
|
|
|
266
278
|
return maps;
|
|
267
279
|
}
|
|
268
280
|
|
|
269
|
-
|
|
281
|
+
export function merge(nets) {
|
|
270
282
|
nets = uniq((Array.isArray(nets) ? nets : [nets]).map(parse));
|
|
271
283
|
const maps = mapNets(nets);
|
|
272
284
|
|
|
@@ -308,14 +320,14 @@ module.exports.merge = function(nets) {
|
|
|
308
320
|
merged.v4 = merged.v4.sort(naturalCompare);
|
|
309
321
|
merged.v6 = merged.v6.sort(naturalCompare);
|
|
310
322
|
return merged.v4.concat(merged.v6);
|
|
311
|
-
}
|
|
323
|
+
}
|
|
312
324
|
|
|
313
|
-
|
|
325
|
+
export function exclude(basenets, exclnets) {
|
|
314
326
|
basenets = uniq(Array.isArray(basenets) ? basenets : [basenets]);
|
|
315
327
|
exclnets = uniq(Array.isArray(exclnets) ? exclnets : [exclnets]);
|
|
316
328
|
|
|
317
|
-
basenets =
|
|
318
|
-
exclnets =
|
|
329
|
+
basenets = merge(basenets);
|
|
330
|
+
exclnets = merge(exclnets);
|
|
319
331
|
|
|
320
332
|
const bases = {v4: [], v6: []};
|
|
321
333
|
const excls = {v4: [], v6: []};
|
|
@@ -343,19 +355,19 @@ module.exports.exclude = (basenets, exclnets) => {
|
|
|
343
355
|
}
|
|
344
356
|
|
|
345
357
|
return bases.v4.concat(bases.v6);
|
|
346
|
-
}
|
|
358
|
+
}
|
|
347
359
|
|
|
348
|
-
|
|
360
|
+
export function expand(nets) {
|
|
349
361
|
nets = uniq(Array.isArray(nets) ? nets : [nets]);
|
|
350
362
|
|
|
351
363
|
let ips = [];
|
|
352
|
-
for (const net of
|
|
364
|
+
for (const net of merge(nets)) {
|
|
353
365
|
ips = ips.concat((new IPCIDR(net)).toArray());
|
|
354
366
|
}
|
|
355
|
-
return ips.map(
|
|
356
|
-
}
|
|
367
|
+
return ips.map(normalize);
|
|
368
|
+
}
|
|
357
369
|
|
|
358
|
-
|
|
370
|
+
export function overlap(a, b) {
|
|
359
371
|
const aNets = uniq(Array.isArray(a) ? a : [a]);
|
|
360
372
|
const bNets = uniq(Array.isArray(b) ? b : [b]);
|
|
361
373
|
|
|
@@ -376,9 +388,9 @@ module.exports.overlap = (a, b) => {
|
|
|
376
388
|
}
|
|
377
389
|
|
|
378
390
|
return false;
|
|
379
|
-
}
|
|
391
|
+
}
|
|
380
392
|
|
|
381
|
-
|
|
393
|
+
export function contains(a, b) {
|
|
382
394
|
const aNets = uniq(Array.isArray(a) ? a : [a]);
|
|
383
395
|
const bNets = uniq(Array.isArray(b) ? b : [b]);
|
|
384
396
|
|
|
@@ -394,7 +406,7 @@ module.exports.contains = (a, b) => {
|
|
|
394
406
|
continue;
|
|
395
407
|
}
|
|
396
408
|
|
|
397
|
-
if (
|
|
409
|
+
if (netContains(aParsed, bParsed)) {
|
|
398
410
|
numFound++;
|
|
399
411
|
continue;
|
|
400
412
|
}
|
|
@@ -402,4 +414,4 @@ module.exports.contains = (a, b) => {
|
|
|
402
414
|
}
|
|
403
415
|
|
|
404
416
|
return numFound === numExpected;
|
|
405
|
-
}
|
|
417
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cidr-tools",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"author": "silverwind <me@silverwind.io>",
|
|
5
5
|
"description": "Tools to work with IPv4 and IPv6 CIDR network lists",
|
|
6
6
|
"repository": "silverwind/cidr-tools",
|
|
7
7
|
"license": "BSD-2-Clause",
|
|
8
|
+
"type": "module",
|
|
8
9
|
"engines": {
|
|
9
|
-
"node": ">=
|
|
10
|
+
"node": ">=14"
|
|
10
11
|
},
|
|
11
12
|
"keywords": [
|
|
12
13
|
"cidr",
|
|
@@ -26,19 +27,19 @@
|
|
|
26
27
|
],
|
|
27
28
|
"types": "./index.d.ts",
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"ip-
|
|
30
|
-
"ip-cidr": "^3.0.
|
|
30
|
+
"ip-bigint": "3.0.3",
|
|
31
|
+
"ip-cidr": "^3.0.10",
|
|
32
|
+
"ip-regex": "5.0.0",
|
|
31
33
|
"ipv6-normalize": "^1.0.1",
|
|
32
34
|
"is-cidr": "^4.0.2",
|
|
33
|
-
"is-ip": "^3.1.0",
|
|
34
35
|
"jsbn": "^1.1.0",
|
|
35
36
|
"string-natural-compare": "^3.0.1"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"eslint": "8.
|
|
39
|
-
"eslint-config-silverwind": "
|
|
40
|
-
"jest": "
|
|
41
|
-
"updates": "13.
|
|
42
|
-
"versions": "9.
|
|
39
|
+
"eslint": "8.23.1",
|
|
40
|
+
"eslint-config-silverwind": "54.0.2",
|
|
41
|
+
"jest": "29.0.3",
|
|
42
|
+
"updates": "13.1.5",
|
|
43
|
+
"versions": "9.3.0"
|
|
43
44
|
}
|
|
44
45
|
}
|