cidr-block 1.3.2 → 2.0.0
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 +659 -34
- package/dist/cjs/index.cjs +32 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +1945 -0
- package/dist/cjs/ipv4-address.cjs +407 -0
- package/dist/cjs/ipv4-address.cjs.map +1 -0
- package/dist/cjs/ipv4-cidr.cjs +498 -0
- package/dist/cjs/ipv4-cidr.cjs.map +1 -0
- package/dist/cjs/ipv4-errors.cjs +25 -0
- package/dist/cjs/ipv4-errors.cjs.map +1 -0
- package/dist/cjs/ipv4.cjs +344 -0
- package/dist/cjs/ipv4.cjs.map +1 -0
- package/dist/cjs/ipv6-address.cjs +522 -0
- package/dist/cjs/ipv6-address.cjs.map +1 -0
- package/dist/cjs/ipv6-cidr.cjs +488 -0
- package/dist/cjs/ipv6-cidr.cjs.map +1 -0
- package/dist/cjs/ipv6-errors.cjs +25 -0
- package/dist/cjs/ipv6-errors.cjs.map +1 -0
- package/dist/cjs/ipv6.cjs +392 -0
- package/dist/cjs/ipv6.cjs.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/ipv4-address.d.ts +333 -0
- package/dist/esm/ipv4-address.d.ts.map +1 -0
- package/dist/esm/ipv4-address.js +405 -0
- package/dist/esm/ipv4-address.js.map +1 -0
- package/dist/esm/ipv4-cidr.d.ts +376 -0
- package/dist/esm/ipv4-cidr.d.ts.map +1 -0
- package/dist/esm/ipv4-cidr.js +496 -0
- package/dist/esm/ipv4-cidr.js.map +1 -0
- package/dist/esm/ipv4-errors.d.ts +12 -0
- package/dist/esm/ipv4-errors.d.ts.map +1 -0
- package/dist/esm/ipv4-errors.js +21 -0
- package/dist/esm/ipv4-errors.js.map +1 -0
- package/dist/esm/ipv4-types.d.ts +32 -0
- package/dist/esm/ipv4-types.d.ts.map +1 -0
- package/dist/esm/ipv4.d.ts +221 -0
- package/dist/esm/ipv4.d.ts.map +1 -0
- package/dist/esm/ipv4.js +339 -0
- package/dist/esm/ipv4.js.map +1 -0
- package/dist/esm/ipv6-address.d.ts +385 -0
- package/dist/esm/ipv6-address.d.ts.map +1 -0
- package/dist/esm/ipv6-address.js +520 -0
- package/dist/esm/ipv6-address.js.map +1 -0
- package/dist/esm/ipv6-cidr.d.ts +361 -0
- package/dist/esm/ipv6-cidr.d.ts.map +1 -0
- package/dist/esm/ipv6-cidr.js +486 -0
- package/dist/esm/ipv6-cidr.js.map +1 -0
- package/dist/esm/ipv6-errors.d.ts +12 -0
- package/dist/esm/ipv6-errors.d.ts.map +1 -0
- package/dist/esm/ipv6-errors.js +21 -0
- package/dist/esm/ipv6-errors.js.map +1 -0
- package/dist/esm/ipv6-types.d.ts +24 -0
- package/dist/esm/ipv6-types.d.ts.map +1 -0
- package/dist/esm/ipv6.d.ts +207 -0
- package/dist/esm/ipv6.d.ts.map +1 -0
- package/dist/esm/ipv6.js +387 -0
- package/dist/esm/ipv6.js.map +1 -0
- package/package.json +41 -78
- package/build/errors.d.ts +0 -6
- package/build/index.d.ts +0 -3
- package/build/index.esm.js +0 -500
- package/build/index.esm.js.map +0 -1
- package/build/index.js +0 -500
- package/build/index.js.map +0 -1
- package/build/ipv4/constants.d.ts +0 -4
- package/build/ipv4/index.d.ts +0 -5
- package/build/ipv4/ipv4-address.d.ts +0 -137
- package/build/ipv4/ipv4-cidr.d.ts +0 -68
- package/build/ipv4/rfc1918.d.ts +0 -8
- package/build/ipv4/types.d.ts +0 -9
- package/build/ipv6/constants.d.ts +0 -4
- package/build/ipv6/index.d.ts +0 -3
- package/build/ipv6/ipv6-address.d.ts +0 -109
- package/build/ipv6/types.d.ts +0 -9
package/README.md
CHANGED
|
@@ -1,68 +1,693 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
ipv4 and ipv6 address and cidr range utilities
|
|
1
|
+
IPv4 and IPv6 address and CIDR range utilities for JavaScript and TypeScript.
|
|
4
2
|
|
|
5
3
|
## Installation
|
|
6
4
|
|
|
7
|
-
To install npm package, run the following in your project:
|
|
8
|
-
|
|
9
5
|
```bash
|
|
10
6
|
npm install cidr-block
|
|
11
7
|
```
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
## Features
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
- Full IPv4 and IPv6 address support
|
|
12
|
+
- CIDR block creation and manipulation
|
|
13
|
+
- Address validation and parsing
|
|
14
|
+
- Network calculations (netmask, address count, usable addresses)
|
|
15
|
+
- Subnetting operations
|
|
16
|
+
- Address type detection (private, loopback, multicast, etc.)
|
|
17
|
+
- Full TypeScript support with comprehensive type definitions
|
|
18
|
+
- Zero dependencies
|
|
19
|
+
- Works with ESM and CommonJS
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { ipv4, ipv6 } from 'cidr-block';
|
|
25
|
+
|
|
26
|
+
// Create and work with IPv4 addresses
|
|
27
|
+
const addr = ipv4.address('192.168.1.1');
|
|
28
|
+
console.log(addr.isPrivateAddress()); // true
|
|
29
|
+
|
|
30
|
+
// Create and work with CIDR blocks
|
|
31
|
+
const cidr = ipv4.cidr('10.0.0.0/16');
|
|
32
|
+
console.log(cidr.addressCount()); // 65536
|
|
33
|
+
|
|
34
|
+
// IPv6 works the same way
|
|
35
|
+
const v6addr = ipv6.address('2001:db8::1');
|
|
36
|
+
console.log(v6addr.toString()); // "2001:db8::1"
|
|
17
37
|
```
|
|
18
38
|
|
|
19
|
-
|
|
20
|
-
meaning you don't need to install any additional `@types` typings.
|
|
39
|
+
## API Reference
|
|
21
40
|
|
|
22
|
-
|
|
41
|
+
### IPv4
|
|
23
42
|
|
|
24
|
-
|
|
43
|
+
#### Creating Addresses
|
|
25
44
|
|
|
26
45
|
```typescript
|
|
27
|
-
import { ipv4
|
|
46
|
+
import { ipv4 } from 'cidr-block';
|
|
47
|
+
|
|
48
|
+
// From string
|
|
49
|
+
const addr1 = ipv4.address('192.168.1.1');
|
|
28
50
|
|
|
29
|
-
|
|
51
|
+
// From number
|
|
52
|
+
const addr2 = ipv4.address(3232235777);
|
|
53
|
+
|
|
54
|
+
// From octet array
|
|
55
|
+
const addr3 = ipv4.address([192, 168, 1, 1]);
|
|
30
56
|
```
|
|
31
57
|
|
|
32
|
-
|
|
58
|
+
#### Address Validation
|
|
33
59
|
|
|
34
60
|
```typescript
|
|
35
|
-
|
|
61
|
+
import { ipv4 } from 'cidr-block';
|
|
62
|
+
|
|
63
|
+
ipv4.isValidAddress('192.168.1.1'); // true
|
|
64
|
+
ipv4.isValidAddress('256.1.1.1'); // false
|
|
65
|
+
ipv4.isValidAddress([10, 0, 0, 1]); // true
|
|
66
|
+
ipv4.isValidAddress(4294967295); // true (255.255.255.255)
|
|
67
|
+
ipv4.isValidAddress(4294967296); // false (exceeds max)
|
|
36
68
|
```
|
|
37
69
|
|
|
38
|
-
|
|
39
|
-
|
|
70
|
+
#### Address Conversion
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { ipv4 } from 'cidr-block';
|
|
74
|
+
|
|
75
|
+
const addr = ipv4.address('192.168.1.1');
|
|
40
76
|
|
|
41
|
-
|
|
77
|
+
addr.toString(); // "192.168.1.1"
|
|
78
|
+
addr.toNumber(); // 3232235777
|
|
79
|
+
addr.octets(); // [192, 168, 1, 1]
|
|
80
|
+
addr.toBinaryString(); // "11000000.10101000.00000001.00000001"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Address Type Detection
|
|
42
84
|
|
|
43
85
|
```typescript
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
86
|
+
import { ipv4 } from 'cidr-block';
|
|
87
|
+
|
|
88
|
+
// Private addresses (RFC 1918)
|
|
89
|
+
ipv4.address('10.0.0.1').isPrivateAddress(); // true
|
|
90
|
+
ipv4.address('172.16.0.1').isPrivateAddress(); // true
|
|
91
|
+
ipv4.address('192.168.0.1').isPrivateAddress(); // true
|
|
92
|
+
ipv4.address('8.8.8.8').isPrivateAddress(); // false
|
|
93
|
+
|
|
94
|
+
// Loopback addresses
|
|
95
|
+
ipv4.address('127.0.0.1').isLoopbackAddress(); // true
|
|
96
|
+
ipv4.address('127.255.255.255').isLoopbackAddress(); // true
|
|
97
|
+
|
|
98
|
+
// Link-local addresses
|
|
99
|
+
ipv4.address('169.254.1.1').isLocalLinkAddress(); // true
|
|
100
|
+
|
|
101
|
+
// Multicast addresses
|
|
102
|
+
ipv4.address('224.0.0.1').isMulticastAddress(); // true
|
|
103
|
+
ipv4.address('239.255.255.255').isMulticastAddress(); // true
|
|
48
104
|
```
|
|
49
105
|
|
|
50
|
-
|
|
106
|
+
#### Address Comparison
|
|
51
107
|
|
|
52
|
-
|
|
108
|
+
```typescript
|
|
109
|
+
import { ipv4 } from 'cidr-block';
|
|
53
110
|
|
|
54
|
-
|
|
111
|
+
const addr1 = ipv4.address('192.168.1.1');
|
|
112
|
+
const addr2 = ipv4.address('192.168.1.2');
|
|
55
113
|
|
|
56
|
-
|
|
114
|
+
addr1.equals('192.168.1.1'); // true
|
|
115
|
+
addr1.equals(addr2); // false
|
|
116
|
+
addr1.isLessThan(addr2); // true
|
|
117
|
+
addr1.isGreaterThan(addr2); // false
|
|
118
|
+
addr1.isLessThanOrEqual(addr2); // true
|
|
119
|
+
addr1.isGreaterThanOrEqual(addr2); // false
|
|
120
|
+
```
|
|
57
121
|
|
|
58
|
-
|
|
122
|
+
#### Address Navigation
|
|
59
123
|
|
|
60
124
|
```typescript
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
125
|
+
import { ipv4 } from 'cidr-block';
|
|
126
|
+
|
|
127
|
+
const addr = ipv4.address('192.168.1.100');
|
|
128
|
+
|
|
129
|
+
addr.hasNextAddress(); // true
|
|
130
|
+
addr.nextAddress()?.toString(); // "192.168.1.101"
|
|
131
|
+
|
|
132
|
+
addr.hasPreviousAddress(); // true
|
|
133
|
+
addr.previousAddress()?.toString(); // "192.168.1.99"
|
|
134
|
+
|
|
135
|
+
// Edge cases
|
|
136
|
+
const maxAddr = ipv4.address('255.255.255.255');
|
|
137
|
+
maxAddr.hasNextAddress(); // false
|
|
138
|
+
maxAddr.nextAddress(); // undefined
|
|
139
|
+
|
|
140
|
+
const minAddr = ipv4.address('0.0.0.0');
|
|
141
|
+
minAddr.hasPreviousAddress(); // false
|
|
142
|
+
minAddr.previousAddress(); // undefined
|
|
65
143
|
```
|
|
66
144
|
|
|
67
|
-
|
|
68
|
-
|
|
145
|
+
#### Creating CIDR Blocks
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { ipv4 } from 'cidr-block';
|
|
149
|
+
|
|
150
|
+
// From string
|
|
151
|
+
const cidr1 = ipv4.cidr('192.168.0.0/24');
|
|
152
|
+
|
|
153
|
+
// From object
|
|
154
|
+
const cidr2 = ipv4.cidr({ address: '192.168.0.0', range: 24 });
|
|
155
|
+
|
|
156
|
+
// From tuple
|
|
157
|
+
const cidr3 = ipv4.cidr(['192.168.0.0', 24]);
|
|
158
|
+
|
|
159
|
+
// Mixed formats work too
|
|
160
|
+
const cidr4 = ipv4.cidr({ address: [192, 168, 0, 0], range: 24 });
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### CIDR Validation
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { ipv4 } from 'cidr-block';
|
|
167
|
+
|
|
168
|
+
ipv4.isValidCIDR('192.168.0.0/24'); // true
|
|
169
|
+
ipv4.isValidCIDR('192.168.0.0/33'); // false (range exceeds 32)
|
|
170
|
+
ipv4.isValidCIDR('256.0.0.0/24'); // false (invalid address)
|
|
171
|
+
ipv4.isValidCIDR(['10.0.0.0', 8]); // true
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### CIDR Properties
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { ipv4 } from 'cidr-block';
|
|
178
|
+
|
|
179
|
+
const cidr = ipv4.cidr('192.168.0.0/24');
|
|
180
|
+
|
|
181
|
+
cidr.toString(); // "192.168.0.0/24"
|
|
182
|
+
cidr.baseAddress().toString(); // "192.168.0.0"
|
|
183
|
+
cidr.range(); // 24
|
|
184
|
+
cidr.netmask().toString(); // "255.255.255.0"
|
|
185
|
+
cidr.addressCount(); // 256
|
|
186
|
+
cidr.rangeParts(); // [Ipv4Address, 24]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Usable Addresses
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { ipv4 } from 'cidr-block';
|
|
193
|
+
|
|
194
|
+
const cidr = ipv4.cidr('192.168.1.0/24');
|
|
195
|
+
|
|
196
|
+
// First usable (excludes network address)
|
|
197
|
+
cidr.getFirstUsableAddress()?.toString(); // "192.168.1.1"
|
|
198
|
+
|
|
199
|
+
// Last usable (excludes broadcast address)
|
|
200
|
+
cidr.getLastUsableAddress()?.toString(); // "192.168.1.254"
|
|
201
|
+
|
|
202
|
+
// For /32, there are no usable addresses
|
|
203
|
+
const hostCidr = ipv4.cidr('192.168.1.1/32');
|
|
204
|
+
hostCidr.getFirstUsableAddress(); // undefined
|
|
205
|
+
hostCidr.getLastUsableAddress(); // undefined
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Iterating Addresses
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { ipv4 } from 'cidr-block';
|
|
212
|
+
|
|
213
|
+
const cidr = ipv4.cidr('192.168.1.0/30');
|
|
214
|
+
|
|
215
|
+
// Using the generator
|
|
216
|
+
for (const addr of cidr.addresses()) {
|
|
217
|
+
console.log(addr.toString());
|
|
218
|
+
}
|
|
219
|
+
// Output:
|
|
220
|
+
// 192.168.1.0
|
|
221
|
+
// 192.168.1.1
|
|
222
|
+
// 192.168.1.2
|
|
223
|
+
// 192.168.1.3
|
|
224
|
+
|
|
225
|
+
// Convert to array
|
|
226
|
+
const allAddresses = [...cidr.addresses()];
|
|
227
|
+
console.log(allAddresses.length); // 4
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### Address Containment
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { ipv4 } from 'cidr-block';
|
|
234
|
+
|
|
235
|
+
const cidr = ipv4.cidr('192.168.0.0/24');
|
|
236
|
+
|
|
237
|
+
cidr.includes(ipv4.address('192.168.0.100')); // true
|
|
238
|
+
cidr.includes(ipv4.address('192.168.1.1')); // false
|
|
239
|
+
cidr.includes(ipv4.address('192.168.0.0')); // true
|
|
240
|
+
cidr.includes(ipv4.address('192.168.0.255')); // true
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### CIDR Overlap Detection
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { ipv4 } from 'cidr-block';
|
|
247
|
+
|
|
248
|
+
const cidr1 = ipv4.cidr('192.168.0.0/24');
|
|
249
|
+
const cidr2 = ipv4.cidr('192.168.0.128/25');
|
|
250
|
+
const cidr3 = ipv4.cidr('192.168.1.0/24');
|
|
251
|
+
|
|
252
|
+
cidr1.overlaps(cidr2); // true (cidr2 is a subnet of cidr1)
|
|
253
|
+
cidr1.overlaps(cidr3); // false (different networks)
|
|
254
|
+
|
|
255
|
+
// Also accepts string format
|
|
256
|
+
cidr1.overlaps('10.0.0.0/8'); // false
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Subnetting
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { ipv4 } from 'cidr-block';
|
|
263
|
+
|
|
264
|
+
const cidr = ipv4.cidr('192.168.0.0/24');
|
|
265
|
+
|
|
266
|
+
// Split into equal subnets
|
|
267
|
+
const subnets = cidr.subnet(26);
|
|
268
|
+
subnets.forEach(s => console.log(s.toString()));
|
|
269
|
+
// Output:
|
|
270
|
+
// 192.168.0.0/26
|
|
271
|
+
// 192.168.0.64/26
|
|
272
|
+
// 192.168.0.128/26
|
|
273
|
+
// 192.168.0.192/26
|
|
274
|
+
|
|
275
|
+
// Split into variable-sized subnets
|
|
276
|
+
const varSubnets = cidr.subnetBy([26, 27, 27, 26]);
|
|
277
|
+
varSubnets.forEach(s => console.log(s.toString()));
|
|
278
|
+
// Output:
|
|
279
|
+
// 192.168.0.0/26
|
|
280
|
+
// 192.168.0.64/27
|
|
281
|
+
// 192.168.0.96/27
|
|
282
|
+
// 192.168.0.128/26
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### CIDR Navigation
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { ipv4 } from 'cidr-block';
|
|
289
|
+
|
|
290
|
+
const cidr = ipv4.cidr('192.168.0.0/24');
|
|
291
|
+
|
|
292
|
+
cidr.hasNextCIDR(); // true
|
|
293
|
+
cidr.nextCIDR()?.toString(); // "192.168.1.0/24"
|
|
294
|
+
|
|
295
|
+
cidr.hasPreviousCIDR(); // true
|
|
296
|
+
cidr.previousCIDR()?.toString(); // "192.167.255.0/24"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### IPv6
|
|
300
|
+
|
|
301
|
+
#### Creating Addresses
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { ipv6 } from 'cidr-block';
|
|
305
|
+
|
|
306
|
+
// From string (with :: compression)
|
|
307
|
+
const addr1 = ipv6.address('2001:db8::1');
|
|
308
|
+
|
|
309
|
+
// From full string
|
|
310
|
+
const addr2 = ipv6.address('2001:0db8:0000:0000:0000:0000:0000:0001');
|
|
311
|
+
|
|
312
|
+
// From BigInt
|
|
313
|
+
const addr3 = ipv6.address(42540766411282592856903984951653826561n);
|
|
314
|
+
|
|
315
|
+
// From hextets array
|
|
316
|
+
const addr4 = ipv6.address([0x2001, 0x0db8, 0, 0, 0, 0, 0, 1]);
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Address Validation
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { ipv6 } from 'cidr-block';
|
|
323
|
+
|
|
324
|
+
ipv6.isValidAddress('2001:db8::1'); // true
|
|
325
|
+
ipv6.isValidAddress('::1'); // true
|
|
326
|
+
ipv6.isValidAddress('::'); // true
|
|
327
|
+
ipv6.isValidAddress('::ffff:192.168.1.1'); // true (IPv4-mapped)
|
|
328
|
+
ipv6.isValidAddress('2001:db8::g'); // false (invalid hex)
|
|
329
|
+
ipv6.isValidAddress('2001:db8:::1'); // false (multiple ::)
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### Address Conversion
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import { ipv6 } from 'cidr-block';
|
|
336
|
+
|
|
337
|
+
const addr = ipv6.address('2001:db8::1');
|
|
338
|
+
|
|
339
|
+
addr.toString(); // "2001:db8::1" (compressed)
|
|
340
|
+
addr.toFullString(); // "2001:0db8:0000:0000:0000:0000:0000:0001"
|
|
341
|
+
addr.toBigInt(); // 42540766411282592856903984951653826561n
|
|
342
|
+
addr.hextets(); // [8193, 3512, 0, 0, 0, 0, 0, 1]
|
|
343
|
+
addr.toBinaryString(); // Binary representation with colons
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### Address Type Detection
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
import { ipv6 } from 'cidr-block';
|
|
350
|
+
|
|
351
|
+
// Loopback
|
|
352
|
+
ipv6.address('::1').isLoopbackAddress(); // true
|
|
353
|
+
|
|
354
|
+
// Unspecified
|
|
355
|
+
ipv6.address('::').isUnspecifiedAddress(); // true
|
|
356
|
+
|
|
357
|
+
// Unique local (private equivalent)
|
|
358
|
+
ipv6.address('fc00::1').isUniqueLocalAddress(); // true
|
|
359
|
+
ipv6.address('fd00::1').isUniqueLocalAddress(); // true
|
|
360
|
+
|
|
361
|
+
// Link-local
|
|
362
|
+
ipv6.address('fe80::1').isLinkLocalAddress(); // true
|
|
363
|
+
|
|
364
|
+
// Multicast
|
|
365
|
+
ipv6.address('ff02::1').isMulticastAddress(); // true
|
|
366
|
+
|
|
367
|
+
// IPv4-mapped
|
|
368
|
+
ipv6.address('::ffff:192.168.1.1').isIPv4MappedAddress(); // true
|
|
369
|
+
|
|
370
|
+
// Documentation
|
|
371
|
+
ipv6.address('2001:db8::1').isDocumentationAddress(); // true
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### Address Comparison
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
import { ipv6 } from 'cidr-block';
|
|
378
|
+
|
|
379
|
+
const addr1 = ipv6.address('2001:db8::1');
|
|
380
|
+
const addr2 = ipv6.address('2001:db8::2');
|
|
381
|
+
|
|
382
|
+
addr1.equals('2001:db8::1'); // true
|
|
383
|
+
addr1.equals(addr2); // false
|
|
384
|
+
addr1.isLessThan(addr2); // true
|
|
385
|
+
addr1.isGreaterThan(addr2); // false
|
|
386
|
+
addr1.isLessThanOrEqual(addr2); // true
|
|
387
|
+
addr1.isGreaterThanOrEqual(addr2); // false
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Address Navigation
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
import { ipv6 } from 'cidr-block';
|
|
394
|
+
|
|
395
|
+
const addr = ipv6.address('2001:db8::1');
|
|
396
|
+
|
|
397
|
+
addr.hasNextAddress(); // true
|
|
398
|
+
addr.nextAddress()?.toString(); // "2001:db8::2"
|
|
399
|
+
|
|
400
|
+
addr.hasPreviousAddress(); // true
|
|
401
|
+
addr.previousAddress()?.toString(); // "2001:db8::"
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### Creating CIDR Blocks
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
import { ipv6 } from 'cidr-block';
|
|
408
|
+
|
|
409
|
+
// From string
|
|
410
|
+
const cidr1 = ipv6.cidr('2001:db8::/32');
|
|
411
|
+
|
|
412
|
+
// From object
|
|
413
|
+
const cidr2 = ipv6.cidr({ address: '2001:db8::', range: 32 });
|
|
414
|
+
|
|
415
|
+
// From tuple
|
|
416
|
+
const cidr3 = ipv6.cidr(['2001:db8::', 32]);
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
#### CIDR Validation
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
import { ipv6 } from 'cidr-block';
|
|
423
|
+
|
|
424
|
+
ipv6.isValidCIDR('2001:db8::/32'); // true
|
|
425
|
+
ipv6.isValidCIDR('2001:db8::/129'); // false (range exceeds 128)
|
|
426
|
+
ipv6.isValidCIDR(['::1', 128]); // true
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### CIDR Properties
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import { ipv6 } from 'cidr-block';
|
|
433
|
+
|
|
434
|
+
const cidr = ipv6.cidr('2001:db8::/32');
|
|
435
|
+
|
|
436
|
+
cidr.toString(); // "2001:db8::/32"
|
|
437
|
+
cidr.baseAddress().toString(); // "2001:db8::"
|
|
438
|
+
cidr.range(); // 32
|
|
439
|
+
cidr.netmask().toString(); // "ffff:ffff::"
|
|
440
|
+
cidr.addressCount(); // 79228162514264337593543950336n (BigInt)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
#### Usable Addresses
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
import { ipv6 } from 'cidr-block';
|
|
447
|
+
|
|
448
|
+
const cidr = ipv6.cidr('2001:db8::/126');
|
|
449
|
+
|
|
450
|
+
cidr.getFirstUsableAddress()?.toString(); // "2001:db8::1"
|
|
451
|
+
cidr.getLastUsableAddress()?.toString(); // "2001:db8::2"
|
|
452
|
+
|
|
453
|
+
// For /128, there are no usable addresses
|
|
454
|
+
const hostCidr = ipv6.cidr('2001:db8::1/128');
|
|
455
|
+
hostCidr.getFirstUsableAddress(); // undefined
|
|
456
|
+
hostCidr.getLastUsableAddress(); // undefined
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### Iterating Addresses
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
import { ipv6 } from 'cidr-block';
|
|
463
|
+
|
|
464
|
+
const cidr = ipv6.cidr('2001:db8::/126');
|
|
465
|
+
|
|
466
|
+
for (const addr of cidr.addresses()) {
|
|
467
|
+
console.log(addr.toString());
|
|
468
|
+
}
|
|
469
|
+
// Output:
|
|
470
|
+
// 2001:db8::
|
|
471
|
+
// 2001:db8::1
|
|
472
|
+
// 2001:db8::2
|
|
473
|
+
// 2001:db8::3
|
|
474
|
+
|
|
475
|
+
// With limit (useful for large ranges)
|
|
476
|
+
for (const addr of cidr.addresses(2n)) {
|
|
477
|
+
console.log(addr.toString());
|
|
478
|
+
}
|
|
479
|
+
// Output:
|
|
480
|
+
// 2001:db8::
|
|
481
|
+
// 2001:db8::1
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### Address Containment and Overlap
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
import { ipv6 } from 'cidr-block';
|
|
488
|
+
|
|
489
|
+
const cidr = ipv6.cidr('2001:db8::/32');
|
|
490
|
+
|
|
491
|
+
cidr.includes(ipv6.address('2001:db8::1')); // true
|
|
492
|
+
cidr.includes(ipv6.address('2001:db9::1')); // false
|
|
493
|
+
|
|
494
|
+
const cidr2 = ipv6.cidr('2001:db8:1::/48');
|
|
495
|
+
cidr.overlaps(cidr2); // true
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
#### Subnetting
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
import { ipv6 } from 'cidr-block';
|
|
502
|
+
|
|
503
|
+
const cidr = ipv6.cidr('2001:db8::/32');
|
|
504
|
+
|
|
505
|
+
// Split into /34 subnets
|
|
506
|
+
const subnets = cidr.subnet(34);
|
|
507
|
+
subnets.forEach(s => console.log(s.toString()));
|
|
508
|
+
// Output:
|
|
509
|
+
// 2001:db8::/34
|
|
510
|
+
// 2001:db8:4000::/34
|
|
511
|
+
// 2001:db8:8000::/34
|
|
512
|
+
// 2001:db8:c000::/34
|
|
513
|
+
|
|
514
|
+
// Variable-sized subnets
|
|
515
|
+
const varSubnets = cidr.subnetBy([34, 34, 33]);
|
|
516
|
+
varSubnets.forEach(s => console.log(s.toString()));
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
#### CIDR Navigation
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
import { ipv6 } from 'cidr-block';
|
|
523
|
+
|
|
524
|
+
const cidr = ipv6.cidr('2001:db8::/32');
|
|
525
|
+
|
|
526
|
+
cidr.hasNextCIDR(); // true
|
|
527
|
+
cidr.nextCIDR()?.toString(); // "2001:db9::/32"
|
|
528
|
+
|
|
529
|
+
cidr.hasPreviousCIDR(); // true
|
|
530
|
+
cidr.previousCIDR()?.toString(); // "2001:db7::/32"
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Error Handling
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
import {
|
|
537
|
+
ipv4,
|
|
538
|
+
ipv6,
|
|
539
|
+
InvalidIpv4AddressError,
|
|
540
|
+
InvalidIpv4CidrError,
|
|
541
|
+
InvalidIpv4CidrRangeError,
|
|
542
|
+
InvalidIpv6AddressError,
|
|
543
|
+
InvalidIpv6CidrError,
|
|
544
|
+
InvalidIpv6CidrRangeError
|
|
545
|
+
} from 'cidr-block';
|
|
546
|
+
|
|
547
|
+
// Invalid address throws error
|
|
548
|
+
try {
|
|
549
|
+
ipv4.address('256.0.0.1');
|
|
550
|
+
} catch (e) {
|
|
551
|
+
if (e instanceof InvalidIpv4AddressError) {
|
|
552
|
+
console.log(e.message); // "256.0.0.1 is not a valid IPv4 address"
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Invalid CIDR throws error
|
|
557
|
+
try {
|
|
558
|
+
ipv4.cidr('192.168.0.0/33');
|
|
559
|
+
} catch (e) {
|
|
560
|
+
if (e instanceof InvalidIpv4CidrError) {
|
|
561
|
+
console.log(e.message); // "192.168.0.0/33 is not a valid IPv4 CIDR range"
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Invalid subnet operation throws error
|
|
566
|
+
try {
|
|
567
|
+
const cidr = ipv4.cidr('192.168.0.0/24');
|
|
568
|
+
cidr.subnet(20); // Can't create larger subnets
|
|
569
|
+
} catch (e) {
|
|
570
|
+
if (e instanceof InvalidIpv4CidrRangeError) {
|
|
571
|
+
console.log('Invalid subnet range');
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Use validation to avoid exceptions
|
|
576
|
+
if (ipv4.isValidAddress(userInput)) {
|
|
577
|
+
const addr = ipv4.address(userInput);
|
|
578
|
+
// Safe to use
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Constants
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
import { ipv4, ipv6 } from 'cidr-block';
|
|
586
|
+
|
|
587
|
+
// IPv4 constants
|
|
588
|
+
ipv4.MAX_SIZE; // 0xffffffff (4294967295)
|
|
589
|
+
ipv4.MIN_SIZE; // 0x00000000
|
|
590
|
+
ipv4.MAX_RANGE; // 32
|
|
591
|
+
ipv4.MIN_RANGE; // 0
|
|
592
|
+
|
|
593
|
+
// IPv6 constants
|
|
594
|
+
ipv6.MAX_SIZE; // (1n << 128n) - 1n
|
|
595
|
+
ipv6.MIN_SIZE; // 0n
|
|
596
|
+
ipv6.MAX_RANGE; // 128
|
|
597
|
+
ipv6.MIN_RANGE; // 0
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Type Definitions
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
import type {
|
|
604
|
+
// IPv4 types
|
|
605
|
+
Ipv4AddressLiteral, // string | number | number[]
|
|
606
|
+
Ipv4AddressString, // "${number}.${number}.${number}.${number}"
|
|
607
|
+
Ipv4AddressOctets, // [number, number, number, number]
|
|
608
|
+
Ipv4CidrLiteral, // string | { address, range } | [address, range]
|
|
609
|
+
Ipv4CidrString, // "${number}.${number}.${number}.${number}/${number}"
|
|
610
|
+
|
|
611
|
+
// IPv6 types
|
|
612
|
+
Ipv6AddressLiteral, // string | bigint | number[]
|
|
613
|
+
Ipv6AddressHextets, // [number, number, number, number, number, number, number, number]
|
|
614
|
+
Ipv6CidrLiteral, // string | { address, range } | [address, range]
|
|
615
|
+
} from 'cidr-block';
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## Common Use Cases
|
|
619
|
+
|
|
620
|
+
### Checking if an IP is in a Private Network
|
|
621
|
+
|
|
622
|
+
```typescript
|
|
623
|
+
import { ipv4 } from 'cidr-block';
|
|
624
|
+
|
|
625
|
+
function isInternalIP(ip: string): boolean {
|
|
626
|
+
if (!ipv4.isValidAddress(ip)) return false;
|
|
627
|
+
const addr = ipv4.address(ip);
|
|
628
|
+
return addr.isPrivateAddress() || addr.isLoopbackAddress();
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
isInternalIP('192.168.1.1'); // true
|
|
632
|
+
isInternalIP('10.0.0.1'); // true
|
|
633
|
+
isInternalIP('8.8.8.8'); // false
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
### Allocating Subnets from a Pool
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
import { ipv4 } from 'cidr-block';
|
|
640
|
+
|
|
641
|
+
function allocateSubnets(poolCidr: string, subnetSize: number, count: number) {
|
|
642
|
+
const pool = ipv4.cidr(poolCidr);
|
|
643
|
+
const subnets = pool.subnet(subnetSize);
|
|
644
|
+
return subnets.slice(0, count);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
const allocated = allocateSubnets('10.0.0.0/16', 24, 3);
|
|
648
|
+
allocated.forEach(s => console.log(s.toString()));
|
|
649
|
+
// 10.0.0.0/24
|
|
650
|
+
// 10.0.1.0/24
|
|
651
|
+
// 10.0.2.0/24
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Checking for CIDR Conflicts
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
import { ipv4, Ipv4Cidr } from 'cidr-block';
|
|
658
|
+
|
|
659
|
+
function findConflicts(newCidr: string, existing: string[]): string[] {
|
|
660
|
+
const cidr = ipv4.cidr(newCidr);
|
|
661
|
+
return existing.filter(e => cidr.overlaps(e));
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const existingRanges = ['10.0.0.0/24', '10.0.1.0/24', '192.168.0.0/16'];
|
|
665
|
+
const conflicts = findConflicts('10.0.0.0/16', existingRanges);
|
|
666
|
+
// ['10.0.0.0/24', '10.0.1.0/24']
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Generating IP Addresses in a Range
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
import { ipv4 } from 'cidr-block';
|
|
673
|
+
|
|
674
|
+
function getUsableIPs(cidrStr: string): string[] {
|
|
675
|
+
const cidr = ipv4.cidr(cidrStr);
|
|
676
|
+
const ips: string[] = [];
|
|
677
|
+
|
|
678
|
+
for (const addr of cidr.addresses()) {
|
|
679
|
+
// Skip network and broadcast addresses for practical use
|
|
680
|
+
if (addr.equals(cidr.baseAddress())) continue;
|
|
681
|
+
|
|
682
|
+
const lastOctet = addr.octets()[3];
|
|
683
|
+
if (lastOctet === 255) continue; // Skip broadcast
|
|
684
|
+
|
|
685
|
+
ips.push(addr.toString());
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return ips;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const usable = getUsableIPs('192.168.1.0/29');
|
|
692
|
+
// ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4', '192.168.1.5', '192.168.1.6']
|
|
693
|
+
```
|