cidr-tools 13.0.3 → 13.0.4
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 +13 -8
- package/dist/index.js +15 -20
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# cidr-tools
|
|
2
2
|
[](https://www.npmjs.org/package/cidr-tools) [](https://www.npmjs.org/package/cidr-tools) [](https://bundlephobia.com/package/cidr-tools) [](https://packagephobia.com/result?p=cidr-tools) [](https://depx.co/pkg/cidr-tools)
|
|
3
|
+
|
|
3
4
|
> Tools to work with IPv4 and IPv6 CIDR
|
|
4
5
|
|
|
5
6
|
## Usage
|
|
6
7
|
|
|
8
|
+
```sh
|
|
9
|
+
pnpm add cidr-tools
|
|
10
|
+
```
|
|
11
|
+
|
|
7
12
|
```js
|
|
8
13
|
import {mergeCidr, excludeCidr, expandCidr, overlapCidr, containsCidr, normalizeCidr, parseCidr} from "cidr-tools";
|
|
9
14
|
|
|
@@ -26,12 +31,12 @@ normalizeCidr("::ffff/64");
|
|
|
26
31
|
//=> "::/64"
|
|
27
32
|
|
|
28
33
|
parseCidr("::/64");
|
|
29
|
-
//=> {cidr: "::/64", version: 6, prefix: "64", start: 0n, end: 18446744073709551615n}
|
|
34
|
+
//=> {cidr: "::/64", ip: "::", version: 6, prefix: "64", prefixPresent: true, start: 0n, end: 18446744073709551615n}
|
|
30
35
|
```
|
|
31
36
|
|
|
32
37
|
## API
|
|
33
38
|
|
|
34
|
-
All functions take CIDR addresses or single IP addresses. On single addresses, a prefix of `/32` or `/128` is assumed.
|
|
39
|
+
All functions take CIDR addresses or single IP addresses. On single addresses, a prefix of `/32` or `/128` is assumed. `mergeCidr`, `excludeCidr` and `expandCidr` return a merged and sorted set with IPv4 sorted before IPv6.
|
|
35
40
|
|
|
36
41
|
Networks are validated with [cidr-regex](https://github.com/silverwind/cidr-regex) and anything that is not a CIDR or IP address throws, including out-of-family prefixes like `1.2.3.4/33` and ambiguous zero-padded octets like `010.0.0.1`.
|
|
37
42
|
|
|
@@ -72,21 +77,21 @@ if (end - start >= 1000000n) {
|
|
|
72
77
|
|
|
73
78
|
### overlapCidr(networksA, networksB, [opts])
|
|
74
79
|
|
|
75
|
-
- `networksA` *String* or *Array*: One or more CIDR or IP
|
|
76
|
-
- `networksB` *String* or *Array*: One or more CIDR or IP
|
|
80
|
+
- `networksA` *String* or *Array*: One or more CIDR or IP addresses.
|
|
81
|
+
- `networksB` *String* or *Array*: One or more CIDR or IP addresses.
|
|
77
82
|
|
|
78
83
|
Returns a boolean that indicates if `networksA` overlap (intersect) with `networksB`.
|
|
79
84
|
|
|
80
85
|
### containsCidr(networksA, networksB, [opts])
|
|
81
86
|
|
|
82
|
-
- `networksA` *String* or *Array*: One or more CIDR or IP
|
|
83
|
-
- `networksB` *String* or *Array*: One or more CIDR or IP
|
|
87
|
+
- `networksA` *String* or *Array*: One or more CIDR or IP addresses.
|
|
88
|
+
- `networksB` *String* or *Array*: One or more CIDR or IP addresses.
|
|
84
89
|
|
|
85
90
|
Returns a boolean that indicates whether `networksA` fully contain all `networksB`.
|
|
86
91
|
|
|
87
92
|
### normalizeCidr(networks, [opts])
|
|
88
93
|
|
|
89
|
-
- `networks` *String* or *Array*: One or more CIDR or IP
|
|
94
|
+
- `networks` *String* or *Array*: One or more CIDR or IP addresses.
|
|
90
95
|
|
|
91
96
|
Returns a string or array (depending on input) with a normalized representation. Will not include a prefix on single IPs. Will set network address to the start of the network.
|
|
92
97
|
|
|
@@ -115,4 +120,4 @@ Returns a `parsed` Object which is used internally by this module. It can be use
|
|
|
115
120
|
- [is-cidr](https://github.com/silverwind/is-cidr) - Check if a string is an IP address in CIDR notation
|
|
116
121
|
- [cidr-regex](https://github.com/silverwind/cidr-regex) - Regular expression for matching IP addresses in CIDR notation and bare IP addresses
|
|
117
122
|
|
|
118
|
-
© [silverwind](https://github.com/silverwind), distributed under BSD licence
|
|
123
|
+
© [silverwind](https://github.com/silverwind), distributed under BSD licence
|
package/dist/index.js
CHANGED
|
@@ -106,10 +106,13 @@ function parseIPv4Range(str) {
|
|
|
106
106
|
rangeV4End = (v4num | mask) >>> 0;
|
|
107
107
|
return true;
|
|
108
108
|
}
|
|
109
|
+
function formatPrefix(prefixNum) {
|
|
110
|
+
return prefixStrings[prefixNum] ?? `/${prefixNum}`;
|
|
111
|
+
}
|
|
109
112
|
function doNormalize(cidr, opts) {
|
|
110
113
|
if (parseIPv4Range(cidr)) {
|
|
111
114
|
const ip = formatIPv4Fast(rangeV4Start);
|
|
112
|
-
return rangeSlashIndex !== -1 ? ip +
|
|
115
|
+
return rangeSlashIndex !== -1 ? ip + formatPrefix(rangeV4Prefix) : ip;
|
|
113
116
|
}
|
|
114
117
|
const slashIndex = rangeSlashIndex;
|
|
115
118
|
const prefixPresent = slashIndex !== -1;
|
|
@@ -117,15 +120,13 @@ function doNormalize(cidr, opts) {
|
|
|
117
120
|
const { number, version, ipv4mapped, scopeid } = parseIp(prefixPresent ? cidr.substring(0, slashIndex) : cidr, unchecked);
|
|
118
121
|
if (prefixNum === -1) prefixNum = bits[version];
|
|
119
122
|
if (version === 4) {
|
|
120
|
-
const
|
|
121
|
-
const mask = hostMasks4[Math.max(hostBits, 0)];
|
|
123
|
+
const mask = hostMasks4[Math.max(32 - prefixNum, 0)];
|
|
122
124
|
const ip = formatIPv4Fast((Number(number) & ~mask) >>> 0);
|
|
123
|
-
return
|
|
125
|
+
return prefixPresent ? ip + formatPrefix(prefixNum) : ip;
|
|
124
126
|
}
|
|
125
127
|
const compress = opts?.compress ?? true;
|
|
126
128
|
const hexify = opts?.hexify ?? false;
|
|
127
|
-
|
|
128
|
-
if (hostBits <= 0 && !prefixPresent) return stringifyIp({
|
|
129
|
+
if (!prefixPresent) return stringifyIp({
|
|
129
130
|
number,
|
|
130
131
|
version,
|
|
131
132
|
ipv4mapped,
|
|
@@ -134,6 +135,7 @@ function doNormalize(cidr, opts) {
|
|
|
134
135
|
compress,
|
|
135
136
|
hexify
|
|
136
137
|
});
|
|
138
|
+
const hostBits = 128 - prefixNum;
|
|
137
139
|
const start = hostBits > 0 ? number & hostNotMasks[hostBits] : number;
|
|
138
140
|
const startMapped = ipv4mapped && start >> 32n === 65535n;
|
|
139
141
|
return stringifyIp({
|
|
@@ -144,7 +146,7 @@ function doNormalize(cidr, opts) {
|
|
|
144
146
|
}, {
|
|
145
147
|
compress,
|
|
146
148
|
hexify
|
|
147
|
-
}) +
|
|
149
|
+
}) + formatPrefix(prefixNum);
|
|
148
150
|
}
|
|
149
151
|
/** Returns a string or array (depending on input) with a normalized representation. Will not include a prefix on single IPs. Will set network address to the start of the network. */
|
|
150
152
|
function normalizeCidr(cidr, opts) {
|
|
@@ -162,7 +164,7 @@ function parseCidr(str, opts) {
|
|
|
162
164
|
const ip = formatIPv4Fast(v4num);
|
|
163
165
|
const mask = hostMasks4[Math.max(32 - prefixNum, 0)];
|
|
164
166
|
return {
|
|
165
|
-
cidr: ip +
|
|
167
|
+
cidr: ip + formatPrefix(prefixNum),
|
|
166
168
|
ip,
|
|
167
169
|
version: 4,
|
|
168
170
|
prefix: prefixNumStrings[prefixNum] ?? String(prefixNum),
|
|
@@ -171,12 +173,10 @@ function parseCidr(str, opts) {
|
|
|
171
173
|
end: BigInt((v4num | mask) >>> 0)
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
|
-
const ipPart = prefixPresent ? str.substring(0, slashIndex) : str;
|
|
175
176
|
let prefixNum = prefixPresent ? parsePrefixNum(str, slashIndex) : -1;
|
|
176
|
-
const { number, version, ipv4mapped, scopeid } = parseIp(
|
|
177
|
+
const { number, version, ipv4mapped, scopeid } = parseIp(prefixPresent ? str.substring(0, slashIndex) : str, unchecked);
|
|
177
178
|
const numBits = bits[version];
|
|
178
179
|
if (prefixNum === -1) prefixNum = numBits;
|
|
179
|
-
const prefix = prefixNumStrings[prefixNum] ?? String(prefixNum);
|
|
180
180
|
const ip = stringifyIp({
|
|
181
181
|
number,
|
|
182
182
|
version,
|
|
@@ -191,10 +191,10 @@ function parseCidr(str, opts) {
|
|
|
191
191
|
end = number | hostMasks[hostBits];
|
|
192
192
|
}
|
|
193
193
|
return {
|
|
194
|
-
cidr: ip +
|
|
194
|
+
cidr: ip + formatPrefix(prefixNum),
|
|
195
195
|
ip,
|
|
196
196
|
version,
|
|
197
|
-
prefix,
|
|
197
|
+
prefix: prefixNumStrings[prefixNum] ?? String(prefixNum),
|
|
198
198
|
prefixPresent,
|
|
199
199
|
start,
|
|
200
200
|
end
|
|
@@ -202,9 +202,8 @@ function parseCidr(str, opts) {
|
|
|
202
202
|
}
|
|
203
203
|
function parseCidrLeanSlow(str) {
|
|
204
204
|
const slashIndex = rangeSlashIndex;
|
|
205
|
-
const ipPart = slashIndex !== -1 ? str.substring(0, slashIndex) : str;
|
|
206
205
|
let prefixNum = slashIndex !== -1 ? parsePrefixNum(str, slashIndex) : -1;
|
|
207
|
-
const { number, version } = parseIp(
|
|
206
|
+
const { number, version } = parseIp(slashIndex !== -1 ? str.substring(0, slashIndex) : str, unchecked);
|
|
208
207
|
const numBits = bits[version];
|
|
209
208
|
if (prefixNum === -1) prefixNum = numBits;
|
|
210
209
|
const hostBits = numBits - prefixNum;
|
|
@@ -237,7 +236,6 @@ function parseCidrLean(str) {
|
|
|
237
236
|
return parseCidrLeanSlow(str);
|
|
238
237
|
}
|
|
239
238
|
function bigintBitLength(n) {
|
|
240
|
-
if (n === 0n) return 0;
|
|
241
239
|
let len = 0;
|
|
242
240
|
if (n >= 18446744073709551616n) {
|
|
243
241
|
n >>= 64n;
|
|
@@ -250,7 +248,6 @@ function bigintBitLength(n) {
|
|
|
250
248
|
return len + 32 - Math.clz32(Number(n));
|
|
251
249
|
}
|
|
252
250
|
function biggestPowerOfTwo4(num) {
|
|
253
|
-
if (num === 0) return 0;
|
|
254
251
|
if (num >= 4294967296) return 4294967296;
|
|
255
252
|
return 1 << 31 - Math.clz32(num) >>> 0;
|
|
256
253
|
}
|
|
@@ -325,7 +322,6 @@ function mergeIntervalsRaw6(nets) {
|
|
|
325
322
|
}
|
|
326
323
|
function subtractSorted4(bases, excls) {
|
|
327
324
|
if (excls.length === 0) return bases;
|
|
328
|
-
if (bases.length === 0) return [];
|
|
329
325
|
const result = [];
|
|
330
326
|
let j = 0;
|
|
331
327
|
for (const base of bases) {
|
|
@@ -350,7 +346,6 @@ function subtractSorted4(bases, excls) {
|
|
|
350
346
|
}
|
|
351
347
|
function subtractSorted6(bases, excls) {
|
|
352
348
|
if (excls.length === 0) return bases;
|
|
353
|
-
if (bases.length === 0) return [];
|
|
354
349
|
const result = [];
|
|
355
350
|
let j = 0;
|
|
356
351
|
for (const base of bases) {
|
|
@@ -420,7 +415,7 @@ function* expandChecked(nets) {
|
|
|
420
415
|
if (net.version === 4) v4.push(net);
|
|
421
416
|
else v6.push(net);
|
|
422
417
|
}
|
|
423
|
-
|
|
418
|
+
for (const part of mergeIntervalsRaw4(v4)) {
|
|
424
419
|
let prevHigh = -1;
|
|
425
420
|
let prefix = "";
|
|
426
421
|
for (let num = part.start; num <= part.end; num++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cidr-tools",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.4",
|
|
4
4
|
"author": "silverwind <me@silverwind.io>",
|
|
5
5
|
"description": "Tools to work with IPv4 and IPv6 CIDR",
|
|
6
6
|
"keywords": [
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"@vitest/coverage-v8": "5.0.2",
|
|
39
39
|
"eslint": "10.11.0",
|
|
40
40
|
"eslint-config-silverwind": "151.0.1",
|
|
41
|
-
"jest-extended": "7.0.0",
|
|
42
41
|
"tsdown": "0.23.0",
|
|
43
42
|
"tsdown-config-silverwind": "4.1.2",
|
|
44
43
|
"typescript": "6.0.3",
|