pnpm 10.33.2 → 10.33.3
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/dist/node_modules/.modules.yaml +66 -66
- package/dist/node_modules/.pnpm/lock.yaml +8 -8
- package/dist/node_modules/.pnpm-workspace-state-v1.json +1 -1
- package/dist/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/dist/node_modules/ip-address/dist/common.js +21 -0
- package/dist/node_modules/ip-address/dist/common.js.map +1 -1
- package/dist/node_modules/ip-address/dist/ip-address.js.map +1 -1
- package/dist/node_modules/ip-address/dist/ipv4.js +193 -68
- package/dist/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/dist/node_modules/ip-address/dist/ipv6.js +345 -131
- package/dist/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/dist/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/dist/node_modules/ip-address/dist/v6/constants.js +5 -0
- package/dist/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/dist/node_modules/ip-address/dist/v6/helpers.js +12 -3
- package/dist/node_modules/ip-address/dist/v6/helpers.js.map +1 -1
- package/dist/node_modules/ip-address/dist/v6/regular-expressions.js.map +1 -1
- package/dist/node_modules/ip-address/package.json +45 -35
- package/dist/node_modules/socks/.claude/settings.local.json +26 -0
- package/dist/node_modules/socks/package.json +2 -2
- package/dist/pnpm.cjs +38 -4
- package/package.json +1 -1
- package/dist/node_modules/ip-address/dist/address-error.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/common.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/ip-address.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/ipv4.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/ipv6.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/v4/constants.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/v6/constants.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/v6/helpers.d.ts.map +0 -1
- package/dist/node_modules/ip-address/dist/v6/regular-expressions.d.ts.map +0 -1
|
@@ -34,6 +34,7 @@ const ipv4_1 = require("./ipv4");
|
|
|
34
34
|
const regular_expressions_1 = require("./v6/regular-expressions");
|
|
35
35
|
const address_error_1 = require("./address-error");
|
|
36
36
|
const common_1 = require("./common");
|
|
37
|
+
const isCorrect6 = common.isCorrect(constants6.BITS);
|
|
37
38
|
function assert(condition) {
|
|
38
39
|
if (!condition) {
|
|
39
40
|
throw new Error('Assertion failed.');
|
|
@@ -77,7 +78,6 @@ function unsignByte(b) {
|
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
80
|
* Represents an IPv6 address
|
|
80
|
-
* @class Address6
|
|
81
81
|
* @param {string} address - An IPv6 address string
|
|
82
82
|
* @param {number} [groups=8] - How many octets to parse
|
|
83
83
|
* @example
|
|
@@ -94,18 +94,14 @@ class Address6 {
|
|
|
94
94
|
// #region Attributes
|
|
95
95
|
/**
|
|
96
96
|
* Returns true if the given address is in the subnet of the current address
|
|
97
|
-
* @memberof Address6
|
|
98
|
-
* @instance
|
|
99
97
|
* @returns {boolean}
|
|
100
98
|
*/
|
|
101
99
|
this.isInSubnet = common.isInSubnet;
|
|
102
100
|
/**
|
|
103
101
|
* Returns true if the address is correct, false otherwise
|
|
104
|
-
* @memberof Address6
|
|
105
|
-
* @instance
|
|
106
102
|
* @returns {boolean}
|
|
107
103
|
*/
|
|
108
|
-
this.isCorrect =
|
|
104
|
+
this.isCorrect = isCorrect6;
|
|
109
105
|
if (optionalGroups === undefined) {
|
|
110
106
|
this.groups = constants6.GROUPS;
|
|
111
107
|
}
|
|
@@ -136,6 +132,13 @@ class Address6 {
|
|
|
136
132
|
this.addressMinusSuffix = address;
|
|
137
133
|
this.parsedAddress = this.parse(this.addressMinusSuffix);
|
|
138
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns true if the given string is a valid IPv6 address (with optional
|
|
137
|
+
* CIDR subnet and zone identifier), false otherwise. Host bits in the
|
|
138
|
+
* subnet portion are allowed (e.g. `2001:db8::1/32` is valid); for strict
|
|
139
|
+
* network-address validation compare `correctForm()` to
|
|
140
|
+
* `startAddress().correctForm()`, or use `networkForm()`.
|
|
141
|
+
*/
|
|
139
142
|
static isValid(address) {
|
|
140
143
|
try {
|
|
141
144
|
// eslint-disable-next-line no-new
|
|
@@ -147,9 +150,8 @@ class Address6 {
|
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
152
|
/**
|
|
150
|
-
* Convert a BigInt to a v6 address object
|
|
151
|
-
*
|
|
152
|
-
* @static
|
|
153
|
+
* Convert a BigInt to a v6 address object. The value must be in the
|
|
154
|
+
* range `[0, 2**128 - 1]`; otherwise `AddressError` is thrown.
|
|
153
155
|
* @param {bigint} bigInt - a BigInt to convert
|
|
154
156
|
* @returns {Address6}
|
|
155
157
|
* @example
|
|
@@ -158,19 +160,21 @@ class Address6 {
|
|
|
158
160
|
* address.correctForm(); // '::e8:d4a5:1000'
|
|
159
161
|
*/
|
|
160
162
|
static fromBigInt(bigInt) {
|
|
163
|
+
if (bigInt < 0n || bigInt > (1n << BigInt(constants6.BITS)) - 1n) {
|
|
164
|
+
throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1');
|
|
165
|
+
}
|
|
161
166
|
const hex = bigInt.toString(16).padStart(32, '0');
|
|
162
167
|
const groups = [];
|
|
163
|
-
let i;
|
|
164
|
-
for (i = 0; i < constants6.GROUPS; i++) {
|
|
168
|
+
for (let i = 0; i < constants6.GROUPS; i++) {
|
|
165
169
|
groups.push(hex.slice(i * 4, (i + 1) * 4));
|
|
166
170
|
}
|
|
167
171
|
return new Address6(groups.join(':'));
|
|
168
172
|
}
|
|
169
173
|
/**
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
+
* Parse a URL (with optional bracketed host and port) into an address and
|
|
175
|
+
* port. Returns either `{ address, port }` on success or
|
|
176
|
+
* `{ error, address: null, port: null }` if the URL could not be parsed.
|
|
177
|
+
* Ports are returned as numbers (or `null` if absent or out of range).
|
|
174
178
|
* @example
|
|
175
179
|
* var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');
|
|
176
180
|
* addressAndPort.address.correctForm(); // 'ffff::'
|
|
@@ -229,10 +233,92 @@ class Address6 {
|
|
|
229
233
|
port,
|
|
230
234
|
};
|
|
231
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Construct an `Address6` from an address and a hex subnet mask given as
|
|
238
|
+
* separate strings (e.g. as returned by Node's `os.networkInterfaces()`).
|
|
239
|
+
* Throws `AddressError` if the mask is non-contiguous (e.g.
|
|
240
|
+
* `ffff::ffff`).
|
|
241
|
+
* @example
|
|
242
|
+
* var address = Address6.fromAddressAndMask('fe80::1', 'ffff:ffff:ffff:ffff::');
|
|
243
|
+
* address.subnetMask; // 64
|
|
244
|
+
*/
|
|
245
|
+
static fromAddressAndMask(address, mask) {
|
|
246
|
+
const bits = common.prefixLengthFromMask(new Address6(mask).bigInt(), constants6.BITS);
|
|
247
|
+
return new Address6(`${address}/${bits}`);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Construct an `Address6` from an address and a Cisco-style wildcard mask
|
|
251
|
+
* given as separate strings (e.g. `::ffff:ffff:ffff:ffff` for a `/64`).
|
|
252
|
+
* The wildcard mask is the bitwise inverse of the subnet mask. Throws
|
|
253
|
+
* `AddressError` if the mask is non-contiguous.
|
|
254
|
+
* @example
|
|
255
|
+
* var address = Address6.fromAddressAndWildcardMask('fe80::1', '::ffff:ffff:ffff:ffff');
|
|
256
|
+
* address.subnetMask; // 64
|
|
257
|
+
*/
|
|
258
|
+
static fromAddressAndWildcardMask(address, wildcardMask) {
|
|
259
|
+
const wildcard = new Address6(wildcardMask).bigInt();
|
|
260
|
+
const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1);
|
|
261
|
+
// eslint-disable-next-line no-bitwise
|
|
262
|
+
const mask = wildcard ^ allOnes;
|
|
263
|
+
const bits = common.prefixLengthFromMask(mask, constants6.BITS);
|
|
264
|
+
return new Address6(`${address}/${bits}`);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Construct an `Address6` from a wildcard pattern with trailing `*`
|
|
268
|
+
* groups. The number of trailing wildcards determines the prefix
|
|
269
|
+
* length: each `*` represents 16 bits. `::` is expanded to zero groups
|
|
270
|
+
* (not wildcards) before evaluating trailing wildcards.
|
|
271
|
+
*
|
|
272
|
+
* Only trailing whole-group wildcards are supported. Partial-group
|
|
273
|
+
* wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g.
|
|
274
|
+
* `*::1`) throw `AddressError`.
|
|
275
|
+
* @example
|
|
276
|
+
* Address6.fromWildcard('2001:db8:*:*:*:*:*:*').subnet; // '/32'
|
|
277
|
+
* Address6.fromWildcard('2001:db8::*').subnet; // '/112'
|
|
278
|
+
* Address6.fromWildcard('*:*:*:*:*:*:*:*').subnet; // '/0'
|
|
279
|
+
*/
|
|
280
|
+
static fromWildcard(input) {
|
|
281
|
+
if (input.includes('%') || input.includes('/')) {
|
|
282
|
+
throw new address_error_1.AddressError('Wildcard pattern must not include a zone or CIDR suffix');
|
|
283
|
+
}
|
|
284
|
+
const halves = input.split('::');
|
|
285
|
+
if (halves.length > 2) {
|
|
286
|
+
throw new address_error_1.AddressError("Wildcard pattern cannot contain more than one '::'");
|
|
287
|
+
}
|
|
288
|
+
let groups;
|
|
289
|
+
if (halves.length === 2) {
|
|
290
|
+
const left = halves[0] === '' ? [] : halves[0].split(':');
|
|
291
|
+
const right = halves[1] === '' ? [] : halves[1].split(':');
|
|
292
|
+
const remaining = constants6.GROUPS - left.length - right.length;
|
|
293
|
+
if (remaining < 1) {
|
|
294
|
+
throw new address_error_1.AddressError("Wildcard pattern with '::' has too many groups");
|
|
295
|
+
}
|
|
296
|
+
groups = [...left, ...new Array(remaining).fill('0'), ...right];
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
groups = input.split(':');
|
|
300
|
+
}
|
|
301
|
+
if (groups.length !== constants6.GROUPS) {
|
|
302
|
+
throw new address_error_1.AddressError('Wildcard pattern must have 8 groups');
|
|
303
|
+
}
|
|
304
|
+
let firstWildcard = -1;
|
|
305
|
+
for (let i = 0; i < groups.length; i++) {
|
|
306
|
+
if (groups[i] === '*') {
|
|
307
|
+
if (firstWildcard === -1) {
|
|
308
|
+
firstWildcard = i;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else if (firstWildcard !== -1) {
|
|
312
|
+
throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing groups (e.g. `2001:db8:*:*:*:*:*:*`)');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;
|
|
316
|
+
const replaced = groups.map((g) => (g === '*' ? '0' : g));
|
|
317
|
+
const subnetBits = constants6.BITS - trailing * 16;
|
|
318
|
+
return new Address6(`${replaced.join(':')}/${subnetBits}`);
|
|
319
|
+
}
|
|
232
320
|
/**
|
|
233
321
|
* Create an IPv6-mapped address given an IPv4 address
|
|
234
|
-
* @memberof Address6
|
|
235
|
-
* @static
|
|
236
322
|
* @param {string} address - An IPv4 address string
|
|
237
323
|
* @returns {Address6}
|
|
238
324
|
* @example
|
|
@@ -247,8 +333,6 @@ class Address6 {
|
|
|
247
333
|
}
|
|
248
334
|
/**
|
|
249
335
|
* Return an address from ip6.arpa form
|
|
250
|
-
* @memberof Address6
|
|
251
|
-
* @static
|
|
252
336
|
* @param {string} arpaFormAddress - an 'ip6.arpa' form address
|
|
253
337
|
* @returns {Adress6}
|
|
254
338
|
* @example
|
|
@@ -273,8 +357,6 @@ class Address6 {
|
|
|
273
357
|
}
|
|
274
358
|
/**
|
|
275
359
|
* Return the Microsoft UNC transcription of the address
|
|
276
|
-
* @memberof Address6
|
|
277
|
-
* @instance
|
|
278
360
|
* @returns {String} the Microsoft UNC transcription of the address
|
|
279
361
|
*/
|
|
280
362
|
microsoftTranscription() {
|
|
@@ -282,8 +364,6 @@ class Address6 {
|
|
|
282
364
|
}
|
|
283
365
|
/**
|
|
284
366
|
* Return the first n bits of the address, defaulting to the subnet mask
|
|
285
|
-
* @memberof Address6
|
|
286
|
-
* @instance
|
|
287
367
|
* @param {number} [mask=subnet] - the number of bits to mask
|
|
288
368
|
* @returns {String} the first n bits of the address as a string
|
|
289
369
|
*/
|
|
@@ -292,8 +372,6 @@ class Address6 {
|
|
|
292
372
|
}
|
|
293
373
|
/**
|
|
294
374
|
* Return the number of possible subnets of a given size in the address
|
|
295
|
-
* @memberof Address6
|
|
296
|
-
* @instance
|
|
297
375
|
* @param {number} [subnetSize=128] - the subnet size
|
|
298
376
|
* @returns {String}
|
|
299
377
|
*/
|
|
@@ -309,8 +387,6 @@ class Address6 {
|
|
|
309
387
|
}
|
|
310
388
|
/**
|
|
311
389
|
* Helper function getting start address.
|
|
312
|
-
* @memberof Address6
|
|
313
|
-
* @instance
|
|
314
390
|
* @returns {bigint}
|
|
315
391
|
*/
|
|
316
392
|
_startAddress() {
|
|
@@ -319,8 +395,6 @@ class Address6 {
|
|
|
319
395
|
/**
|
|
320
396
|
* The first address in the range given by this address' subnet
|
|
321
397
|
* Often referred to as the Network Address.
|
|
322
|
-
* @memberof Address6
|
|
323
|
-
* @instance
|
|
324
398
|
* @returns {Address6}
|
|
325
399
|
*/
|
|
326
400
|
startAddress() {
|
|
@@ -329,8 +403,6 @@ class Address6 {
|
|
|
329
403
|
/**
|
|
330
404
|
* The first host address in the range given by this address's subnet ie
|
|
331
405
|
* the first address after the Network Address
|
|
332
|
-
* @memberof Address6
|
|
333
|
-
* @instance
|
|
334
406
|
* @returns {Address6}
|
|
335
407
|
*/
|
|
336
408
|
startAddressExclusive() {
|
|
@@ -339,8 +411,6 @@ class Address6 {
|
|
|
339
411
|
}
|
|
340
412
|
/**
|
|
341
413
|
* Helper function getting end address.
|
|
342
|
-
* @memberof Address6
|
|
343
|
-
* @instance
|
|
344
414
|
* @returns {bigint}
|
|
345
415
|
*/
|
|
346
416
|
_endAddress() {
|
|
@@ -349,8 +419,6 @@ class Address6 {
|
|
|
349
419
|
/**
|
|
350
420
|
* The last address in the range given by this address' subnet
|
|
351
421
|
* Often referred to as the Broadcast
|
|
352
|
-
* @memberof Address6
|
|
353
|
-
* @instance
|
|
354
422
|
* @returns {Address6}
|
|
355
423
|
*/
|
|
356
424
|
endAddress() {
|
|
@@ -359,8 +427,6 @@ class Address6 {
|
|
|
359
427
|
/**
|
|
360
428
|
* The last host address in the range given by this address's subnet ie
|
|
361
429
|
* the last address prior to the Broadcast Address
|
|
362
|
-
* @memberof Address6
|
|
363
|
-
* @instance
|
|
364
430
|
* @returns {Address6}
|
|
365
431
|
*/
|
|
366
432
|
endAddressExclusive() {
|
|
@@ -368,36 +434,73 @@ class Address6 {
|
|
|
368
434
|
return Address6.fromBigInt(this._endAddress() - adjust);
|
|
369
435
|
}
|
|
370
436
|
/**
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
* @
|
|
437
|
+
* The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a
|
|
438
|
+
* `/64`. Returns an `Address6`; call `.correctForm()` for the string.
|
|
439
|
+
* @returns {Address6}
|
|
440
|
+
*/
|
|
441
|
+
subnetMaskAddress() {
|
|
442
|
+
return Address6.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants6.BITS - this.subnetMask)}`));
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* The Cisco-style wildcard mask, e.g. `::ffff:ffff:ffff:ffff` for a
|
|
446
|
+
* `/64`. This is the bitwise inverse of `subnetMaskAddress()`. Returns
|
|
447
|
+
* an `Address6`; call `.correctForm()` for the string.
|
|
448
|
+
* @returns {Address6}
|
|
449
|
+
*/
|
|
450
|
+
wildcardMask() {
|
|
451
|
+
return Address6.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants6.BITS - this.subnetMask)}`));
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* The network address in CIDR string form, e.g. `2001:db8::/32` for
|
|
455
|
+
* `2001:db8::1/32`. For an address with no explicit subnet the prefix
|
|
456
|
+
* is `/128`, e.g. `networkForm()` on `2001:db8::1` returns
|
|
457
|
+
* `2001:db8::1/128`.
|
|
458
|
+
* @returns {string}
|
|
459
|
+
*/
|
|
460
|
+
networkForm() {
|
|
461
|
+
return `${this.startAddress().correctForm()}/${this.subnetMask}`;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Return the scope of the address. The 4-bit scope field
|
|
465
|
+
* ([RFC 4291 §2.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.7))
|
|
466
|
+
* is only defined for multicast addresses; for unicast addresses the scope
|
|
467
|
+
* is derived from the address type per
|
|
468
|
+
* [RFC 4007 §6](https://datatracker.ietf.org/doc/html/rfc4007#section-6).
|
|
374
469
|
* @returns {String}
|
|
375
470
|
*/
|
|
376
471
|
getScope() {
|
|
377
|
-
|
|
378
|
-
if (
|
|
379
|
-
scope =
|
|
472
|
+
const type = this.getType();
|
|
473
|
+
if (type === 'Multicast' || type.startsWith('Multicast ')) {
|
|
474
|
+
const scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];
|
|
475
|
+
return scope || 'Unknown';
|
|
476
|
+
}
|
|
477
|
+
// RFC 4291 §2.5.3: the loopback address is treated as having Link-Local
|
|
478
|
+
// scope. (Multicast scope 1, "Interface-Local", is a different concept
|
|
479
|
+
// used only for loopback transmission of multicast.)
|
|
480
|
+
if (type === 'Link-local unicast' || type === 'Loopback') {
|
|
481
|
+
return 'Link local';
|
|
482
|
+
}
|
|
483
|
+
// RFC 4007 §6: the unspecified address has no scope.
|
|
484
|
+
if (type === 'Unspecified') {
|
|
485
|
+
return 'Unknown';
|
|
380
486
|
}
|
|
381
|
-
return
|
|
487
|
+
return 'Global';
|
|
382
488
|
}
|
|
383
489
|
/**
|
|
384
490
|
* Return the type of the address
|
|
385
|
-
* @memberof Address6
|
|
386
|
-
* @instance
|
|
387
491
|
* @returns {String}
|
|
388
492
|
*/
|
|
389
493
|
getType() {
|
|
390
|
-
for (
|
|
391
|
-
|
|
392
|
-
|
|
494
|
+
for (let i = 0; i < TYPE_SUBNETS.length; i++) {
|
|
495
|
+
const entry = TYPE_SUBNETS[i];
|
|
496
|
+
if (this.isInSubnet(entry[0])) {
|
|
497
|
+
return entry[1];
|
|
393
498
|
}
|
|
394
499
|
}
|
|
395
500
|
return 'Global unicast';
|
|
396
501
|
}
|
|
397
502
|
/**
|
|
398
503
|
* Return the bits in the given range as a BigInt
|
|
399
|
-
* @memberof Address6
|
|
400
|
-
* @instance
|
|
401
504
|
* @returns {bigint}
|
|
402
505
|
*/
|
|
403
506
|
getBits(start, end) {
|
|
@@ -405,8 +508,6 @@ class Address6 {
|
|
|
405
508
|
}
|
|
406
509
|
/**
|
|
407
510
|
* Return the bits in the given range as a base-2 string
|
|
408
|
-
* @memberof Address6
|
|
409
|
-
* @instance
|
|
410
511
|
* @returns {String}
|
|
411
512
|
*/
|
|
412
513
|
getBitsBase2(start, end) {
|
|
@@ -414,8 +515,6 @@ class Address6 {
|
|
|
414
515
|
}
|
|
415
516
|
/**
|
|
416
517
|
* Return the bits in the given range as a base-16 string
|
|
417
|
-
* @memberof Address6
|
|
418
|
-
* @instance
|
|
419
518
|
* @returns {String}
|
|
420
519
|
*/
|
|
421
520
|
getBitsBase16(start, end) {
|
|
@@ -429,8 +528,6 @@ class Address6 {
|
|
|
429
528
|
}
|
|
430
529
|
/**
|
|
431
530
|
* Return the bits that are set past the subnet mask length
|
|
432
|
-
* @memberof Address6
|
|
433
|
-
* @instance
|
|
434
531
|
* @returns {String}
|
|
435
532
|
*/
|
|
436
533
|
getBitsPastSubnet() {
|
|
@@ -438,10 +535,8 @@ class Address6 {
|
|
|
438
535
|
}
|
|
439
536
|
/**
|
|
440
537
|
* Return the reversed ip6.arpa form of the address
|
|
441
|
-
* @memberof Address6
|
|
442
538
|
* @param {Object} options
|
|
443
539
|
* @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix
|
|
444
|
-
* @instance
|
|
445
540
|
* @returns {String}
|
|
446
541
|
*/
|
|
447
542
|
reverseForm(options) {
|
|
@@ -467,10 +562,10 @@ class Address6 {
|
|
|
467
562
|
return 'ip6.arpa.';
|
|
468
563
|
}
|
|
469
564
|
/**
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
565
|
+
* Returns the address in correct form, per
|
|
566
|
+
* [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952): leading zeros
|
|
567
|
+
* stripped, the longest run of zero groups collapsed to `::`, and hex digits
|
|
568
|
+
* lowercased (e.g. `2001:db8::1`). This is the recommended form for display.
|
|
474
569
|
*/
|
|
475
570
|
correctForm() {
|
|
476
571
|
let i;
|
|
@@ -514,8 +609,6 @@ class Address6 {
|
|
|
514
609
|
}
|
|
515
610
|
/**
|
|
516
611
|
* Return a zero-padded base-2 string representation of the address
|
|
517
|
-
* @memberof Address6
|
|
518
|
-
* @instance
|
|
519
612
|
* @returns {String}
|
|
520
613
|
* @example
|
|
521
614
|
* var address = new Address6('2001:4860:4001:803::1011');
|
|
@@ -524,10 +617,22 @@ class Address6 {
|
|
|
524
617
|
* // 0000000000000000000000000000000000000000000000000001000000010001'
|
|
525
618
|
*/
|
|
526
619
|
binaryZeroPad() {
|
|
527
|
-
|
|
620
|
+
if (this._binaryZeroPad === undefined) {
|
|
621
|
+
this._binaryZeroPad = this.bigInt().toString(2).padStart(constants6.BITS, '0');
|
|
622
|
+
}
|
|
623
|
+
return this._binaryZeroPad;
|
|
528
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the
|
|
627
|
+
* trailing IPv4 address into `this.address4` / `this.parsedAddress4` and
|
|
628
|
+
* returning the address with the v4 portion converted to two v6 groups.
|
|
629
|
+
* Used internally by `parse()`.
|
|
630
|
+
*/
|
|
529
631
|
// TODO: Improve the semantics of this helper function
|
|
530
632
|
parse4in6(address) {
|
|
633
|
+
if (address.indexOf('.') === -1) {
|
|
634
|
+
return address;
|
|
635
|
+
}
|
|
531
636
|
const groups = address.split(':');
|
|
532
637
|
const lastGroup = groups.slice(-1)[0];
|
|
533
638
|
const address4 = lastGroup.match(constants4.RE_ADDRESS);
|
|
@@ -536,7 +641,12 @@ class Address6 {
|
|
|
536
641
|
this.address4 = new ipv4_1.Address4(this.parsedAddress4);
|
|
537
642
|
for (let i = 0; i < this.address4.groups; i++) {
|
|
538
643
|
if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) {
|
|
539
|
-
|
|
644
|
+
// The prefix groups haven't been through the bad-character check
|
|
645
|
+
// yet, so escape them before including in the error HTML.
|
|
646
|
+
const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.');
|
|
647
|
+
const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');
|
|
648
|
+
const separator = groups.length > 1 ? ':' : '';
|
|
649
|
+
throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
|
|
540
650
|
}
|
|
541
651
|
}
|
|
542
652
|
this.v4 = true;
|
|
@@ -545,6 +655,13 @@ class Address6 {
|
|
|
545
655
|
}
|
|
546
656
|
return address;
|
|
547
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* Parses an IPv6 address string into its 8 hexadecimal groups (expanding
|
|
660
|
+
* any `::` elision and any trailing v4-in-v6 portion) and stores the result
|
|
661
|
+
* on `this.parsedAddress`. Called automatically by the constructor; you
|
|
662
|
+
* typically don't need to call it directly. Throws `AddressError` if the
|
|
663
|
+
* input is malformed.
|
|
664
|
+
*/
|
|
548
665
|
// TODO: Make private?
|
|
549
666
|
parse(address) {
|
|
550
667
|
address = this.parse4in6(address);
|
|
@@ -594,18 +711,16 @@ class Address6 {
|
|
|
594
711
|
return groups;
|
|
595
712
|
}
|
|
596
713
|
/**
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
714
|
+
* Returns the canonical (fully expanded) form of the address: all 8 groups,
|
|
715
|
+
* each padded to 4 hex digits, with no `::` collapsing
|
|
716
|
+
* (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and
|
|
717
|
+
* byte-exact comparison.
|
|
601
718
|
*/
|
|
602
719
|
canonicalForm() {
|
|
603
720
|
return this.parsedAddress.map(paddedHex).join(':');
|
|
604
721
|
}
|
|
605
722
|
/**
|
|
606
723
|
* Return the decimal form of the address
|
|
607
|
-
* @memberof Address6
|
|
608
|
-
* @instance
|
|
609
724
|
* @returns {String}
|
|
610
725
|
*/
|
|
611
726
|
decimal() {
|
|
@@ -613,8 +728,6 @@ class Address6 {
|
|
|
613
728
|
}
|
|
614
729
|
/**
|
|
615
730
|
* Return the address as a BigInt
|
|
616
|
-
* @memberof Address6
|
|
617
|
-
* @instance
|
|
618
731
|
* @returns {bigint}
|
|
619
732
|
*/
|
|
620
733
|
bigInt() {
|
|
@@ -622,8 +735,6 @@ class Address6 {
|
|
|
622
735
|
}
|
|
623
736
|
/**
|
|
624
737
|
* Return the last two groups of this address as an IPv4 address string
|
|
625
|
-
* @memberof Address6
|
|
626
|
-
* @instance
|
|
627
738
|
* @returns {Address4}
|
|
628
739
|
* @example
|
|
629
740
|
* var address = new Address6('2001:4860:4001::1825:bf11');
|
|
@@ -631,12 +742,10 @@ class Address6 {
|
|
|
631
742
|
*/
|
|
632
743
|
to4() {
|
|
633
744
|
const binary = this.binaryZeroPad().split('');
|
|
634
|
-
return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16));
|
|
745
|
+
return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16).padStart(8, '0'));
|
|
635
746
|
}
|
|
636
747
|
/**
|
|
637
748
|
* Return the v4-in-v6 form of the address
|
|
638
|
-
* @memberof Address6
|
|
639
|
-
* @instance
|
|
640
749
|
* @returns {String}
|
|
641
750
|
*/
|
|
642
751
|
to4in6() {
|
|
@@ -650,10 +759,10 @@ class Address6 {
|
|
|
650
759
|
return correct + infix + address4.address;
|
|
651
760
|
}
|
|
652
761
|
/**
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
762
|
+
* Decodes the Teredo tunneling fields embedded in this address. Returns the
|
|
763
|
+
* Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag,
|
|
764
|
+
* UDP port, and Microsoft-format flag breakdown (reserved, universal/local,
|
|
765
|
+
* group/individual, nonce). Only meaningful for addresses in `2001::/32`.
|
|
657
766
|
*/
|
|
658
767
|
inspectTeredo() {
|
|
659
768
|
/*
|
|
@@ -684,7 +793,7 @@ class Address6 {
|
|
|
684
793
|
const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));
|
|
685
794
|
const bitsForClient4 = this.getBits(96, 128);
|
|
686
795
|
// eslint-disable-next-line no-bitwise
|
|
687
|
-
const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16));
|
|
796
|
+
const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0'));
|
|
688
797
|
const flagsBase2 = this.getBitsBase2(64, 80);
|
|
689
798
|
const coneNat = (0, common_1.testBit)(flagsBase2, 15);
|
|
690
799
|
const reserved = (0, common_1.testBit)(flagsBase2, 14);
|
|
@@ -707,10 +816,9 @@ class Address6 {
|
|
|
707
816
|
};
|
|
708
817
|
}
|
|
709
818
|
/**
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
* @returns {Object}
|
|
819
|
+
* Decodes the 6to4 tunneling fields embedded in this address. Returns the
|
|
820
|
+
* 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for
|
|
821
|
+
* addresses in `2002::/16`.
|
|
714
822
|
*/
|
|
715
823
|
inspect6to4() {
|
|
716
824
|
/*
|
|
@@ -726,8 +834,6 @@ class Address6 {
|
|
|
726
834
|
}
|
|
727
835
|
/**
|
|
728
836
|
* Return a v6 6to4 address from a v6 v4inv6 address
|
|
729
|
-
* @memberof Address6
|
|
730
|
-
* @instance
|
|
731
837
|
* @returns {Address6}
|
|
732
838
|
*/
|
|
733
839
|
to6to4() {
|
|
@@ -744,9 +850,80 @@ class Address6 {
|
|
|
744
850
|
return new Address6(addr6to4);
|
|
745
851
|
}
|
|
746
852
|
/**
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
853
|
+
* Embed an IPv4 address into a NAT64 IPv6 address using the encoding
|
|
854
|
+
* defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).
|
|
855
|
+
* The default prefix is the well-known prefix `64:ff9b::/96`. The prefix
|
|
856
|
+
* length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter
|
|
857
|
+
* than /64 the IPv4 octets are split around the reserved bits 64–71.
|
|
858
|
+
* @example
|
|
859
|
+
* Address6.fromAddress4Nat64('192.0.2.33').correctForm(); // '64:ff9b::c000:221'
|
|
860
|
+
* Address6.fromAddress4Nat64('192.0.2.33', '2001:db8::/32').correctForm(); // '2001:db8:c000:221::'
|
|
861
|
+
*/
|
|
862
|
+
static fromAddress4Nat64(address, prefix = '64:ff9b::/96') {
|
|
863
|
+
const v4 = new ipv4_1.Address4(address);
|
|
864
|
+
const prefix6 = new Address6(prefix);
|
|
865
|
+
const pl = prefix6.subnetMask;
|
|
866
|
+
if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {
|
|
867
|
+
throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');
|
|
868
|
+
}
|
|
869
|
+
const prefixBits = prefix6.binaryZeroPad();
|
|
870
|
+
const v4Bits = v4.binaryZeroPad();
|
|
871
|
+
let bits;
|
|
872
|
+
if (pl === 96) {
|
|
873
|
+
bits = prefixBits.slice(0, 96) + v4Bits;
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
const beforeU = 64 - pl;
|
|
877
|
+
bits =
|
|
878
|
+
prefixBits.slice(0, pl) +
|
|
879
|
+
v4Bits.slice(0, beforeU) +
|
|
880
|
+
'00000000' +
|
|
881
|
+
v4Bits.slice(beforeU) +
|
|
882
|
+
'0'.repeat(128 - 72 - (32 - beforeU));
|
|
883
|
+
}
|
|
884
|
+
const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0');
|
|
885
|
+
const groups = [];
|
|
886
|
+
for (let i = 0; i < 8; i++) {
|
|
887
|
+
groups.push(hex.slice(i * 4, (i + 1) * 4));
|
|
888
|
+
}
|
|
889
|
+
return new Address6(groups.join(':'));
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Extract the embedded IPv4 address from a NAT64 IPv6 address using the
|
|
893
|
+
* encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).
|
|
894
|
+
* The default prefix is the well-known prefix `64:ff9b::/96`. Returns
|
|
895
|
+
* `null` if this address is not contained within the given prefix.
|
|
896
|
+
* @example
|
|
897
|
+
* new Address6('64:ff9b::c000:221').toAddress4Nat64()!.correctForm(); // '192.0.2.33'
|
|
898
|
+
*/
|
|
899
|
+
toAddress4Nat64(prefix = '64:ff9b::/96') {
|
|
900
|
+
const prefix6 = new Address6(prefix);
|
|
901
|
+
const pl = prefix6.subnetMask;
|
|
902
|
+
if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {
|
|
903
|
+
throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');
|
|
904
|
+
}
|
|
905
|
+
if (!this.isInSubnet(prefix6)) {
|
|
906
|
+
return null;
|
|
907
|
+
}
|
|
908
|
+
const bits = this.binaryZeroPad();
|
|
909
|
+
let v4Bits;
|
|
910
|
+
if (pl === 96) {
|
|
911
|
+
v4Bits = bits.slice(96, 128);
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
const beforeU = 64 - pl;
|
|
915
|
+
v4Bits = bits.slice(pl, pl + beforeU) + bits.slice(72, 72 + (32 - beforeU));
|
|
916
|
+
}
|
|
917
|
+
const octets = [];
|
|
918
|
+
for (let i = 0; i < 4; i++) {
|
|
919
|
+
octets.push(parseInt(v4Bits.slice(i * 8, (i + 1) * 8), 2).toString());
|
|
920
|
+
}
|
|
921
|
+
return new ipv4_1.Address4(octets.join('.'));
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Return a byte array.
|
|
925
|
+
*
|
|
926
|
+
* To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`.
|
|
750
927
|
* @returns {Array}
|
|
751
928
|
*/
|
|
752
929
|
toByteArray() {
|
|
@@ -760,27 +937,27 @@ class Address6 {
|
|
|
760
937
|
return bytes;
|
|
761
938
|
}
|
|
762
939
|
/**
|
|
763
|
-
* Return an unsigned byte array
|
|
764
|
-
*
|
|
765
|
-
*
|
|
940
|
+
* Return an unsigned byte array.
|
|
941
|
+
*
|
|
942
|
+
* To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`.
|
|
766
943
|
* @returns {Array}
|
|
767
944
|
*/
|
|
768
945
|
toUnsignedByteArray() {
|
|
769
946
|
return this.toByteArray().map(unsignByte);
|
|
770
947
|
}
|
|
771
948
|
/**
|
|
772
|
-
* Convert a byte array to an Address6 object
|
|
773
|
-
*
|
|
774
|
-
*
|
|
949
|
+
* Convert a byte array to an Address6 object.
|
|
950
|
+
*
|
|
951
|
+
* To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.
|
|
775
952
|
* @returns {Address6}
|
|
776
953
|
*/
|
|
777
954
|
static fromByteArray(bytes) {
|
|
778
955
|
return this.fromUnsignedByteArray(bytes.map(unsignByte));
|
|
779
956
|
}
|
|
780
957
|
/**
|
|
781
|
-
* Convert an unsigned byte array to an Address6 object
|
|
782
|
-
*
|
|
783
|
-
*
|
|
958
|
+
* Convert an unsigned byte array to an Address6 object.
|
|
959
|
+
*
|
|
960
|
+
* To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.
|
|
784
961
|
* @returns {Address6}
|
|
785
962
|
*/
|
|
786
963
|
static fromUnsignedByteArray(bytes) {
|
|
@@ -795,8 +972,6 @@ class Address6 {
|
|
|
795
972
|
}
|
|
796
973
|
/**
|
|
797
974
|
* Returns true if the address is in the canonical form, false otherwise
|
|
798
|
-
* @memberof Address6
|
|
799
|
-
* @instance
|
|
800
975
|
* @returns {boolean}
|
|
801
976
|
*/
|
|
802
977
|
isCanonical() {
|
|
@@ -804,8 +979,6 @@ class Address6 {
|
|
|
804
979
|
}
|
|
805
980
|
/**
|
|
806
981
|
* Returns true if the address is a link local address, false otherwise
|
|
807
|
-
* @memberof Address6
|
|
808
|
-
* @instance
|
|
809
982
|
* @returns {boolean}
|
|
810
983
|
*/
|
|
811
984
|
isLinkLocal() {
|
|
@@ -818,53 +991,81 @@ class Address6 {
|
|
|
818
991
|
}
|
|
819
992
|
/**
|
|
820
993
|
* Returns true if the address is a multicast address, false otherwise
|
|
821
|
-
* @memberof Address6
|
|
822
|
-
* @instance
|
|
823
994
|
* @returns {boolean}
|
|
824
995
|
*/
|
|
825
996
|
isMulticast() {
|
|
826
|
-
|
|
997
|
+
const type = this.getType();
|
|
998
|
+
return type === 'Multicast' || type.startsWith('Multicast ');
|
|
827
999
|
}
|
|
828
1000
|
/**
|
|
829
|
-
* Returns true if the address
|
|
830
|
-
*
|
|
831
|
-
*
|
|
1001
|
+
* Returns true if the address was written in v4-in-v6 dotted-quad notation
|
|
1002
|
+
* (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag
|
|
1003
|
+
* and does not reflect whether the address bits lie in the IPv4-mapped
|
|
1004
|
+
* (`::ffff:0:0/96`) subnet — for that, see {@link isMapped4}.
|
|
832
1005
|
* @returns {boolean}
|
|
833
1006
|
*/
|
|
834
1007
|
is4() {
|
|
835
1008
|
return this.v4;
|
|
836
1009
|
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Returns true if the address is an IPv4-mapped IPv6 address in
|
|
1012
|
+
* `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)),
|
|
1013
|
+
* false otherwise. Unlike {@link is4}, this checks the underlying address
|
|
1014
|
+
* bits rather than the textual notation, so `::ffff:127.0.0.1` and
|
|
1015
|
+
* `::ffff:7f00:1` both return true.
|
|
1016
|
+
* @returns {boolean}
|
|
1017
|
+
*/
|
|
1018
|
+
isMapped4() {
|
|
1019
|
+
return this.isInSubnet(IPV4_MAPPED_SUBNET);
|
|
1020
|
+
}
|
|
837
1021
|
/**
|
|
838
1022
|
* Returns true if the address is a Teredo address, false otherwise
|
|
839
|
-
* @memberof Address6
|
|
840
|
-
* @instance
|
|
841
1023
|
* @returns {boolean}
|
|
842
1024
|
*/
|
|
843
1025
|
isTeredo() {
|
|
844
|
-
return this.isInSubnet(
|
|
1026
|
+
return this.isInSubnet(TEREDO_SUBNET);
|
|
845
1027
|
}
|
|
846
1028
|
/**
|
|
847
1029
|
* Returns true if the address is a 6to4 address, false otherwise
|
|
848
|
-
* @memberof Address6
|
|
849
|
-
* @instance
|
|
850
1030
|
* @returns {boolean}
|
|
851
1031
|
*/
|
|
852
1032
|
is6to4() {
|
|
853
|
-
return this.isInSubnet(
|
|
1033
|
+
return this.isInSubnet(SIX_TO_FOUR_SUBNET);
|
|
854
1034
|
}
|
|
855
1035
|
/**
|
|
856
1036
|
* Returns true if the address is a loopback address, false otherwise
|
|
857
|
-
* @memberof Address6
|
|
858
|
-
* @instance
|
|
859
1037
|
* @returns {boolean}
|
|
860
1038
|
*/
|
|
861
1039
|
isLoopback() {
|
|
862
1040
|
return this.getType() === 'Loopback';
|
|
863
1041
|
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses.
|
|
1044
|
+
* @returns {boolean}
|
|
1045
|
+
*/
|
|
1046
|
+
isULA() {
|
|
1047
|
+
return this.isInSubnet(ULA_SUBNET);
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Returns true if the address is the unspecified address `::`.
|
|
1051
|
+
* @returns {boolean}
|
|
1052
|
+
*/
|
|
1053
|
+
isUnspecified() {
|
|
1054
|
+
return this.getType() === 'Unspecified';
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)).
|
|
1058
|
+
* @returns {boolean}
|
|
1059
|
+
*/
|
|
1060
|
+
isDocumentation() {
|
|
1061
|
+
return this.isInSubnet(DOCUMENTATION_SUBNET);
|
|
1062
|
+
}
|
|
864
1063
|
// #endregion
|
|
865
1064
|
// #region HTML
|
|
866
1065
|
/**
|
|
867
|
-
*
|
|
1066
|
+
* Returns the address as an HTTP URL with the host bracketed, e.g.
|
|
1067
|
+
* `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended,
|
|
1068
|
+
* e.g. `http://[2001:db8::1]:8080/`.
|
|
868
1069
|
*/
|
|
869
1070
|
href(optionalPort) {
|
|
870
1071
|
if (optionalPort === undefined) {
|
|
@@ -876,7 +1077,12 @@ class Address6 {
|
|
|
876
1077
|
return `http://[${this.correctForm()}]${optionalPort}/`;
|
|
877
1078
|
}
|
|
878
1079
|
/**
|
|
879
|
-
*
|
|
1080
|
+
* Returns an HTML `<a>` element whose `href` encodes the address in a URL
|
|
1081
|
+
* hash fragment (default prefix `/#address=`). Useful for linking between
|
|
1082
|
+
* pages of an address-inspector UI.
|
|
1083
|
+
* @param options.className - CSS class for the rendered `<a>` element
|
|
1084
|
+
* @param options.prefix - hash prefix prepended to the address (default `/#address=`)
|
|
1085
|
+
* @param options.v4 - when true, render the address in v4-in-v6 form
|
|
880
1086
|
*/
|
|
881
1087
|
link(options) {
|
|
882
1088
|
if (!options) {
|
|
@@ -896,10 +1102,13 @@ class Address6 {
|
|
|
896
1102
|
formFunction = this.to4in6;
|
|
897
1103
|
}
|
|
898
1104
|
const form = formFunction.call(this);
|
|
1105
|
+
const safeHref = helpers.escapeHtml(`${options.prefix}${form}`);
|
|
1106
|
+
const safeForm = helpers.escapeHtml(form);
|
|
899
1107
|
if (options.className) {
|
|
900
|
-
|
|
1108
|
+
const safeClass = helpers.escapeHtml(options.className);
|
|
1109
|
+
return `<a href="${safeHref}" class="${safeClass}">${safeForm}</a>`;
|
|
901
1110
|
}
|
|
902
|
-
return `<a href="${
|
|
1111
|
+
return `<a href="${safeHref}">${safeForm}</a>`;
|
|
903
1112
|
}
|
|
904
1113
|
/**
|
|
905
1114
|
* Groups an address
|
|
@@ -908,13 +1117,13 @@ class Address6 {
|
|
|
908
1117
|
group() {
|
|
909
1118
|
if (this.elidedGroups === 0) {
|
|
910
1119
|
// The simple case
|
|
911
|
-
return helpers.simpleGroup(this.
|
|
1120
|
+
return helpers.simpleGroup(this.addressMinusSuffix).join(':');
|
|
912
1121
|
}
|
|
913
1122
|
assert(typeof this.elidedGroups === 'number');
|
|
914
1123
|
assert(typeof this.elisionBegin === 'number');
|
|
915
1124
|
// The elided case
|
|
916
1125
|
const output = [];
|
|
917
|
-
const [left, right] = this.
|
|
1126
|
+
const [left, right] = this.addressMinusSuffix.split('::');
|
|
918
1127
|
if (left.length) {
|
|
919
1128
|
output.push(...helpers.simpleGroup(left));
|
|
920
1129
|
}
|
|
@@ -944,8 +1153,6 @@ class Address6 {
|
|
|
944
1153
|
/**
|
|
945
1154
|
* Generate a regular expression string that can be used to find or validate
|
|
946
1155
|
* all variations of this address
|
|
947
|
-
* @memberof Address6
|
|
948
|
-
* @instance
|
|
949
1156
|
* @param {boolean} substringSearch
|
|
950
1157
|
* @returns {string}
|
|
951
1158
|
*/
|
|
@@ -990,8 +1197,6 @@ class Address6 {
|
|
|
990
1197
|
/**
|
|
991
1198
|
* Generate a regular expression that can be used to find or validate all
|
|
992
1199
|
* variations of this address.
|
|
993
|
-
* @memberof Address6
|
|
994
|
-
* @instance
|
|
995
1200
|
* @param {boolean} substringSearch
|
|
996
1201
|
* @returns {RegExp}
|
|
997
1202
|
*/
|
|
@@ -1000,4 +1205,13 @@ class Address6 {
|
|
|
1000
1205
|
}
|
|
1001
1206
|
}
|
|
1002
1207
|
exports.Address6 = Address6;
|
|
1208
|
+
const TYPE_SUBNETS = Object.keys(constants6.TYPES).map((subnet) => [
|
|
1209
|
+
new Address6(subnet),
|
|
1210
|
+
constants6.TYPES[subnet],
|
|
1211
|
+
]);
|
|
1212
|
+
const TEREDO_SUBNET = new Address6('2001::/32');
|
|
1213
|
+
const SIX_TO_FOUR_SUBNET = new Address6('2002::/16');
|
|
1214
|
+
const ULA_SUBNET = new Address6('fc00::/7');
|
|
1215
|
+
const DOCUMENTATION_SUBNET = new Address6('2001:db8::/32');
|
|
1216
|
+
const IPV4_MAPPED_SUBNET = new Address6('::ffff:0:0/96');
|
|
1003
1217
|
//# sourceMappingURL=ipv6.js.map
|