@terascope/ip-utils 2.3.2 → 2.4.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/dist/src/index.d.ts +10 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +76 -154
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/cidr-block.d.ts +60 -0
- package/dist/src/utils/cidr-block.d.ts.map +1 -0
- package/dist/src/utils/cidr-block.js +181 -0
- package/dist/src/utils/cidr-block.js.map +1 -0
- package/dist/src/utils/ip-address.d.ts +33 -0
- package/dist/src/utils/ip-address.d.ts.map +1 -0
- package/dist/src/utils/ip-address.js +332 -0
- package/dist/src/utils/ip-address.js.map +1 -0
- package/dist/src/utils/ip-range.d.ts +27 -0
- package/dist/src/utils/ip-range.d.ts.map +1 -0
- package/dist/src/utils/ip-range.js +58 -0
- package/dist/src/utils/ip-range.js.map +1 -0
- package/package.json +1 -11
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { IPAddress } from './utils/ip-address.js';
|
|
2
|
+
import { CIDRBlock } from './utils/cidr-block.js';
|
|
3
|
+
import { IPRange } from './utils/ip-range.js';
|
|
4
|
+
export { IPAddress, CIDRBlock, IPRange };
|
|
1
5
|
export declare function isIP(input: unknown): input is string;
|
|
2
6
|
/** Will throw if input is not a valid CIDR */
|
|
3
7
|
export declare function isIPRangeOrThrow(input: unknown): string;
|
|
@@ -16,47 +20,40 @@ export declare function isRoutableIP(input: unknown): boolean;
|
|
|
16
20
|
export declare function isNonRoutableIP(input: unknown): boolean;
|
|
17
21
|
export declare function isCIDR(input: unknown): input is string;
|
|
18
22
|
/**
|
|
19
|
-
*
|
|
20
23
|
* @param input ip address block in CIDR notation
|
|
21
24
|
* @returns first IP address in the block
|
|
22
25
|
* @deprecated use getFirstUsableIPInCIDR
|
|
23
26
|
*/
|
|
24
27
|
export declare function getCIDRMin(input: unknown): string;
|
|
25
28
|
/**
|
|
26
|
-
*
|
|
27
29
|
* @param input ip address block in CIDR notation
|
|
28
30
|
* @returns last ip address in the block
|
|
29
31
|
* @deprecated use getLastUsableIPInCIDR
|
|
30
32
|
*/
|
|
31
33
|
export declare function getCIDRMax(input: unknown): string;
|
|
32
34
|
/**
|
|
33
|
-
*
|
|
34
35
|
* @param input ip address block in CIDR notation, inclusive
|
|
35
36
|
* @returns first IP address in the block
|
|
36
37
|
*/
|
|
37
38
|
export declare function getFirstIPInCIDR(input: unknown): string;
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
40
|
* @param input ip address block in CIDR notation
|
|
41
41
|
* @returns last ip address in the block, inclusive
|
|
42
42
|
*/
|
|
43
43
|
export declare function getLastIPInCIDR(input: unknown): string;
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
46
45
|
* @param input ip address block in CIDR notation
|
|
47
46
|
* @returns first usable ip address of the CIDR block
|
|
48
47
|
*/
|
|
49
48
|
export declare function getFirstUsableIPInCIDR(input: unknown): string;
|
|
50
49
|
/**
|
|
51
|
-
*
|
|
52
50
|
* @param input ip address block in CIDR notation
|
|
53
51
|
* @returns last usable ip address of the CIDR block
|
|
54
52
|
*/
|
|
55
53
|
export declare function getLastUsableIPInCIDR(input: unknown): string;
|
|
56
54
|
/**
|
|
57
|
-
*
|
|
58
55
|
* @param input ip address
|
|
59
|
-
* @returns IPv6 addresses are returned without leading 0's in a group or empty groups
|
|
56
|
+
* @returns IPv6 addresses are returned without leading 0's in a group or empty groups;
|
|
60
57
|
* ipv4 addresses are simply returned
|
|
61
58
|
*/
|
|
62
59
|
export declare function shortenIPv6Address(input: unknown): string;
|
|
@@ -67,4 +64,9 @@ export declare function isNonZeroCidr(input: string): boolean;
|
|
|
67
64
|
export declare function ipToInt(input: unknown): bigint;
|
|
68
65
|
export declare function intToIP(input: unknown, ipVersion: string | number): string;
|
|
69
66
|
export declare function reverseIP(input: unknown): string;
|
|
67
|
+
/**
|
|
68
|
+
* Returns the smallest CIDR block that encloses both IP addresses.
|
|
69
|
+
* Both IPs must be the same version (both IPv4 or both IPv6).
|
|
70
|
+
*/
|
|
71
|
+
export declare function ipsToCIDR(ip1: unknown, ip2: unknown): string;
|
|
70
72
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAEzC,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEpD;AAED,8CAA8C;AAC9C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQvD;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQxD;AAED,wBAAgB,SAAS,CACrB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,OAAO,CAoBT;AAsBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGvD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQvD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQtD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ7D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ5D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMzD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASrD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAYtE;AAkBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAiB1E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIhD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAK5D"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { toInteger, isNumberLike, toBigIntOrThrow,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import { parseIp, stringifyIp } from 'ip-bigint';
|
|
7
|
-
import ip6addr from 'ip6addr';
|
|
8
|
-
import { IpAddress } from 'cidr-calc';
|
|
1
|
+
import { toInteger, isNumberLike, toBigIntOrThrow, isString, getTypeOf, isBoolean, } from '@terascope/core-utils';
|
|
2
|
+
import { IPAddress } from './utils/ip-address.js';
|
|
3
|
+
import { CIDRBlock } from './utils/cidr-block.js';
|
|
4
|
+
import { IPRange } from './utils/ip-range.js';
|
|
5
|
+
export { IPAddress, CIDRBlock, IPRange };
|
|
9
6
|
export function isIP(input) {
|
|
10
|
-
return isString(input) &&
|
|
7
|
+
return isString(input) && IPAddress.isValid(input);
|
|
11
8
|
}
|
|
12
9
|
/** Will throw if input is not a valid CIDR */
|
|
13
10
|
export function isIPRangeOrThrow(input) {
|
|
@@ -24,122 +21,73 @@ export function isIPOrThrow(input) {
|
|
|
24
21
|
return input;
|
|
25
22
|
}
|
|
26
23
|
export function isIPv6(input) {
|
|
27
|
-
return isString(input) &&
|
|
24
|
+
return isString(input) && IPAddress.isIPv6(input);
|
|
28
25
|
}
|
|
29
26
|
export function isIPv4(input) {
|
|
30
|
-
return isString(input) &&
|
|
27
|
+
return isString(input) && IPAddress.isIPv4(input);
|
|
31
28
|
}
|
|
32
29
|
export function isMappedIPv4(input) {
|
|
33
|
-
if (isIPv6(input))
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
return false;
|
|
30
|
+
if (!isIPv6(input))
|
|
31
|
+
return false;
|
|
32
|
+
return IPAddress.of(input).isMappedIPv4();
|
|
38
33
|
}
|
|
39
34
|
export function extractMappedIPv4(input) {
|
|
40
35
|
if (isIPv6(input) && isMappedIPv4(input)) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
return IPAddress.of(input)
|
|
37
|
+
.toMappedIPv4()
|
|
38
|
+
.toString();
|
|
44
39
|
}
|
|
45
40
|
throw Error('input must be an IPv4 address mapped to an IPv6 address');
|
|
46
41
|
}
|
|
47
42
|
export function inIPRange(input, args) {
|
|
48
43
|
if (!isIP(input))
|
|
49
44
|
return false;
|
|
50
|
-
const
|
|
45
|
+
const ip = IPAddress.of(input);
|
|
51
46
|
if (args.cidr != null) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// this should be refactored
|
|
56
|
-
const minValue = args.min || _assignMin(ipType);
|
|
57
|
-
const maxValue = args.max || _assignMax(ipType);
|
|
58
|
-
if (_validMinAndMax(minValue, maxValue)) {
|
|
59
|
-
const min = IpAddress.of(minValue).toString();
|
|
60
|
-
const max = IpAddress.of(maxValue).toString();
|
|
61
|
-
return ip6addr.createAddrRange(min, max).contains(data);
|
|
47
|
+
if (!isCIDR(args.cidr))
|
|
48
|
+
return false;
|
|
49
|
+
return CIDRBlock.of(args.cidr).contains(ip);
|
|
62
50
|
}
|
|
63
|
-
|
|
51
|
+
const ipVersion = ip.version;
|
|
52
|
+
const minStr = args.min ?? _assignMin(ipVersion);
|
|
53
|
+
const maxStr = args.max ?? _assignMax(ipVersion);
|
|
54
|
+
if (!_validMinAndMax(minStr, maxStr))
|
|
55
|
+
return false;
|
|
56
|
+
const min = IPAddress.of(minStr);
|
|
57
|
+
const max = IPAddress.of(maxStr);
|
|
58
|
+
return ip.compare(min) >= 0 && ip.compare(max) <= 0;
|
|
64
59
|
}
|
|
65
|
-
function _assignMin(
|
|
66
|
-
|
|
67
|
-
return IpAddress.of(min).toString();
|
|
68
|
-
if (ipType === 4)
|
|
69
|
-
return '0.0.0.0';
|
|
70
|
-
return '::';
|
|
60
|
+
function _assignMin(version) {
|
|
61
|
+
return version === 4 ? '0.0.0.0' : '::';
|
|
71
62
|
}
|
|
72
|
-
function _assignMax(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return '255.255.255.255';
|
|
77
|
-
return 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
|
|
63
|
+
function _assignMax(version) {
|
|
64
|
+
return version === 4
|
|
65
|
+
? '255.255.255.255'
|
|
66
|
+
: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
|
|
78
67
|
}
|
|
79
68
|
function _validMinAndMax(min, max) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
69
|
+
if (!IPAddress.isValid(min) || !IPAddress.isValid(max))
|
|
70
|
+
return false;
|
|
71
|
+
const minIP = IPAddress.of(min);
|
|
72
|
+
const maxIP = IPAddress.of(max);
|
|
73
|
+
if (minIP.version !== maxIP.version)
|
|
74
|
+
return false;
|
|
75
|
+
return minIP.compare(maxIP) <= 0;
|
|
83
76
|
}
|
|
84
77
|
export function isRoutableIP(input) {
|
|
85
78
|
if (!isIP(input))
|
|
86
79
|
return false;
|
|
87
|
-
return
|
|
80
|
+
return IPAddress.of(input).isRoutable();
|
|
88
81
|
}
|
|
89
82
|
export function isNonRoutableIP(input) {
|
|
90
83
|
if (!isIP(input))
|
|
91
84
|
return false;
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
function _isPrivateIP(input) {
|
|
95
|
-
const parsedIp = _parseIpAddress(input);
|
|
96
|
-
return _inPrivateIPRange(parsedIp.range()) || _inRestrictedIPRange(parsedIp);
|
|
97
|
-
}
|
|
98
|
-
function _parseIpAddress(input) {
|
|
99
|
-
if (isMappedIPv4(input)) {
|
|
100
|
-
return ipaddr.parse(extractMappedIPv4(input));
|
|
101
|
-
}
|
|
102
|
-
return ipaddr.parse(input);
|
|
103
|
-
}
|
|
104
|
-
function _inPrivateIPRange(ipRange) {
|
|
105
|
-
return [
|
|
106
|
-
'private',
|
|
107
|
-
'uniqueLocal',
|
|
108
|
-
'loopback',
|
|
109
|
-
'unspecified',
|
|
110
|
-
'carrierGradeNat',
|
|
111
|
-
'linkLocal',
|
|
112
|
-
'reserved',
|
|
113
|
-
'rfc6052',
|
|
114
|
-
'teredo',
|
|
115
|
-
'6to4',
|
|
116
|
-
'broadcast'
|
|
117
|
-
].includes(ipRange);
|
|
118
|
-
}
|
|
119
|
-
// parse the ranges here
|
|
120
|
-
// to avoid having to parse every time the function is called
|
|
121
|
-
const ipv4RestrictedRanges = [
|
|
122
|
-
ipaddr.parseCIDR('192.31.196.0/24'),
|
|
123
|
-
ipaddr.parseCIDR('192.52.193.0/24'),
|
|
124
|
-
ipaddr.parseCIDR('192.175.48.0/24'),
|
|
125
|
-
ipaddr.parseCIDR('198.18.0.0/15'),
|
|
126
|
-
ipaddr.parseCIDR('224.0.0.0/8')
|
|
127
|
-
];
|
|
128
|
-
const ipv6RestrictedRanges = [
|
|
129
|
-
ipaddr.parseCIDR('64:ff9b:1::/48'),
|
|
130
|
-
ipaddr.parseCIDR('100::/64'),
|
|
131
|
-
ipaddr.parseCIDR('2001::/23'),
|
|
132
|
-
ipaddr.parseCIDR('2620:4f:8000::/48')
|
|
133
|
-
];
|
|
134
|
-
function _inRestrictedIPRange(parsedIp) {
|
|
135
|
-
const rangesToCheck = parsedIp.kind() === 'ipv4' ? ipv4RestrictedRanges : ipv6RestrictedRanges;
|
|
136
|
-
return rangesToCheck.some((ipRange) => parsedIp.match(ipRange));
|
|
85
|
+
return !IPAddress.of(input).isRoutable();
|
|
137
86
|
}
|
|
138
87
|
export function isCIDR(input) {
|
|
139
|
-
return isString(input) &&
|
|
88
|
+
return isString(input) && CIDRBlock.isValid(input);
|
|
140
89
|
}
|
|
141
90
|
/**
|
|
142
|
-
*
|
|
143
91
|
* @param input ip address block in CIDR notation
|
|
144
92
|
* @returns first IP address in the block
|
|
145
93
|
* @deprecated use getFirstUsableIPInCIDR
|
|
@@ -148,7 +96,6 @@ export function getCIDRMin(input) {
|
|
|
148
96
|
return getFirstUsableIPInCIDR(input);
|
|
149
97
|
}
|
|
150
98
|
/**
|
|
151
|
-
*
|
|
152
99
|
* @param input ip address block in CIDR notation
|
|
153
100
|
* @returns last ip address in the block
|
|
154
101
|
* @deprecated use getLastUsableIPInCIDR
|
|
@@ -157,85 +104,87 @@ export function getCIDRMax(input) {
|
|
|
157
104
|
return getLastUsableIPInCIDR(input);
|
|
158
105
|
}
|
|
159
106
|
/**
|
|
160
|
-
*
|
|
161
107
|
* @param input ip address block in CIDR notation, inclusive
|
|
162
108
|
* @returns first IP address in the block
|
|
163
109
|
*/
|
|
164
110
|
export function getFirstIPInCIDR(input) {
|
|
165
111
|
if (isCIDR(input)) {
|
|
166
|
-
return
|
|
112
|
+
return CIDRBlock.of(input)
|
|
113
|
+
.first()
|
|
114
|
+
.toString();
|
|
167
115
|
}
|
|
168
116
|
throw Error('input must be a valid IP address in CIDR notation');
|
|
169
117
|
}
|
|
170
118
|
/**
|
|
171
|
-
*
|
|
172
119
|
* @param input ip address block in CIDR notation
|
|
173
120
|
* @returns last ip address in the block, inclusive
|
|
174
121
|
*/
|
|
175
122
|
export function getLastIPInCIDR(input) {
|
|
176
123
|
if (isCIDR(input)) {
|
|
177
|
-
return
|
|
124
|
+
return CIDRBlock.of(input)
|
|
125
|
+
.last()
|
|
126
|
+
.toString();
|
|
178
127
|
}
|
|
179
128
|
throw Error('input must be a valid IP address in CIDR notation');
|
|
180
129
|
}
|
|
181
130
|
/**
|
|
182
|
-
*
|
|
183
131
|
* @param input ip address block in CIDR notation
|
|
184
132
|
* @returns first usable ip address of the CIDR block
|
|
185
133
|
*/
|
|
186
134
|
export function getFirstUsableIPInCIDR(input) {
|
|
187
135
|
if (isCIDR(input)) {
|
|
188
|
-
return
|
|
136
|
+
return CIDRBlock.of(input)
|
|
137
|
+
.firstUsable()
|
|
189
138
|
.toString();
|
|
190
139
|
}
|
|
191
140
|
throw Error('input must be a valid IP address in CIDR notation');
|
|
192
141
|
}
|
|
193
142
|
/**
|
|
194
|
-
*
|
|
195
143
|
* @param input ip address block in CIDR notation
|
|
196
144
|
* @returns last usable ip address of the CIDR block
|
|
197
145
|
*/
|
|
198
146
|
export function getLastUsableIPInCIDR(input) {
|
|
199
147
|
if (isCIDR(input)) {
|
|
200
|
-
return
|
|
148
|
+
return CIDRBlock.of(input)
|
|
149
|
+
.lastUsable()
|
|
201
150
|
.toString();
|
|
202
151
|
}
|
|
203
152
|
throw Error('input must be a valid IP address in CIDR notation');
|
|
204
153
|
}
|
|
205
154
|
/**
|
|
206
|
-
*
|
|
207
155
|
* @param input ip address
|
|
208
|
-
* @returns IPv6 addresses are returned without leading 0's in a group or empty groups
|
|
156
|
+
* @returns IPv6 addresses are returned without leading 0's in a group or empty groups;
|
|
209
157
|
* ipv4 addresses are simply returned
|
|
210
158
|
*/
|
|
211
159
|
export function shortenIPv6Address(input) {
|
|
212
160
|
if (isIP(input)) {
|
|
213
|
-
return
|
|
161
|
+
return IPAddress.of(input).toString();
|
|
214
162
|
}
|
|
215
163
|
throw Error('input must be a valid address');
|
|
216
164
|
}
|
|
217
165
|
export function getCIDRBroadcast(input) {
|
|
218
166
|
if (isCIDR(input)) {
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
221
|
-
return
|
|
167
|
+
const block = CIDRBlock.of(input);
|
|
168
|
+
if (block.version === 4) {
|
|
169
|
+
return block.broadcast().toString();
|
|
222
170
|
}
|
|
223
171
|
}
|
|
224
172
|
throw Error('input must be a valid IPv4 address in CIDR notation');
|
|
225
173
|
}
|
|
226
174
|
export function getCIDRNetwork(input) {
|
|
227
175
|
if (isCIDR(input)) {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return ipaddr.IPv4.networkAddressFromCIDR(input).octets.join('.');
|
|
176
|
+
const block = CIDRBlock.of(input);
|
|
177
|
+
if (block.version === 4) {
|
|
178
|
+
return block.network().toString();
|
|
232
179
|
}
|
|
233
180
|
}
|
|
234
181
|
throw Error('input must be a valid IPv4 address in CIDR notation');
|
|
235
182
|
}
|
|
236
183
|
export function toCIDR(input, suffix) {
|
|
237
|
-
if (isIP(input)
|
|
238
|
-
|
|
184
|
+
if (isIP(input)
|
|
185
|
+
&& _validSuffix(IPAddress.ipVersion(input), suffix)) {
|
|
186
|
+
const ip = IPAddress.of(input);
|
|
187
|
+
return CIDRBlock.from(ip, toInteger(suffix)).toString();
|
|
239
188
|
}
|
|
240
189
|
throw Error('input must be a valid IP address and suffix must be a value <= 32 for IPv4 or <= 128 for IPv6');
|
|
241
190
|
}
|
|
@@ -253,21 +202,12 @@ function _validSuffix(ipVersion, suffix) {
|
|
|
253
202
|
}
|
|
254
203
|
return false;
|
|
255
204
|
}
|
|
256
|
-
function createCIDR(input, suffix) {
|
|
257
|
-
if (suffix != null) {
|
|
258
|
-
return ip6addr.createCIDR(input, suffix);
|
|
259
|
-
}
|
|
260
|
-
return ip6addr.createCIDR(input);
|
|
261
|
-
}
|
|
262
205
|
export function isNonZeroCidr(input) {
|
|
263
|
-
|
|
264
|
-
if (isNumber(cidrValue) && cidrValue > 0)
|
|
265
|
-
return true;
|
|
266
|
-
return false;
|
|
206
|
+
return CIDRBlock.isCidr(input) > 0;
|
|
267
207
|
}
|
|
268
208
|
export function ipToInt(input) {
|
|
269
209
|
if (isIP(input)) {
|
|
270
|
-
return toBigIntOrThrow(
|
|
210
|
+
return toBigIntOrThrow(IPAddress.of(input).toInt());
|
|
271
211
|
}
|
|
272
212
|
throw Error('input must be a valid ip address');
|
|
273
213
|
}
|
|
@@ -280,40 +220,22 @@ export function intToIP(input, ipVersion) {
|
|
|
280
220
|
if (bigInt < 0n || bigInt > (versionAsInt === 4 ? maxIpV4 : maxIpV6)) {
|
|
281
221
|
throw new Error(`Invalid IP input: ${bigInt}`);
|
|
282
222
|
}
|
|
283
|
-
return
|
|
284
|
-
number: bigInt,
|
|
285
|
-
version: versionAsInt,
|
|
286
|
-
ipv4mapped: false,
|
|
287
|
-
scopeid: undefined
|
|
288
|
-
});
|
|
223
|
+
return IPAddress.fromInt(bigInt, versionAsInt).toString();
|
|
289
224
|
}
|
|
290
225
|
throw Error('input should be a big int or string for large numbers. Version must be 4 or 6');
|
|
291
226
|
}
|
|
292
227
|
export function reverseIP(input) {
|
|
293
228
|
if (!isIP(input))
|
|
294
229
|
throw Error('input must be a valid ip address');
|
|
295
|
-
|
|
296
|
-
if (parsedIp.kind() === 'ipv4') {
|
|
297
|
-
return parsedIp.octets.reverse().join('.');
|
|
298
|
-
}
|
|
299
|
-
return _reverseIPv6(parsedIp);
|
|
300
|
-
}
|
|
301
|
-
function _reverseIPv6(ip) {
|
|
302
|
-
return ip.toNormalizedString().split(':')
|
|
303
|
-
.reduce((parts, part) => {
|
|
304
|
-
parts.push(_expandIPv6Part(part));
|
|
305
|
-
return parts;
|
|
306
|
-
}, [])
|
|
307
|
-
.join('')
|
|
308
|
-
.split('')
|
|
309
|
-
.reverse()
|
|
310
|
-
.join('.');
|
|
230
|
+
return IPAddress.of(input).reverse();
|
|
311
231
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
232
|
+
/**
|
|
233
|
+
* Returns the smallest CIDR block that encloses both IP addresses.
|
|
234
|
+
* Both IPs must be the same version (both IPv4 or both IPv6).
|
|
235
|
+
*/
|
|
236
|
+
export function ipsToCIDR(ip1, ip2) {
|
|
237
|
+
const a = IPAddress.of(isIPOrThrow(ip1));
|
|
238
|
+
const b = IPAddress.of(isIPOrThrow(ip2));
|
|
239
|
+
return CIDRBlock.enclosing(a, b).toString();
|
|
318
240
|
}
|
|
319
241
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EAAE,YAAY,EAAE,eAAe,EACxC,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { IPAddress } from './ip-address.js';
|
|
2
|
+
export declare class CIDRBlock {
|
|
3
|
+
private readonly _input;
|
|
4
|
+
private readonly _network;
|
|
5
|
+
private readonly _prefix;
|
|
6
|
+
readonly version: 4 | 6;
|
|
7
|
+
private constructor();
|
|
8
|
+
/** Parse "a.b.c.d/n" or "::1/128" CIDR notation. Throws if invalid. */
|
|
9
|
+
static of(cidr: string): CIDRBlock;
|
|
10
|
+
/** Build a CIDRBlock from an IPAddress and prefix length. */
|
|
11
|
+
static from(ip: IPAddress, prefix: number): CIDRBlock;
|
|
12
|
+
/**
|
|
13
|
+
* Return the smallest CIDR block that encloses both IP addresses.
|
|
14
|
+
* Both IPs must be the same version.
|
|
15
|
+
*
|
|
16
|
+
* NOTE: The result is network-aligned and may extend beyond the input IPs.
|
|
17
|
+
* For example, enclosing(192.198.0.1, 192.198.0.254) → 192.198.0.0/24,
|
|
18
|
+
* which includes 192.198.0.0 and 192.198.0.255. This is a CIDR/routing
|
|
19
|
+
* operation — use IPRange for arbitrary range containment checks.
|
|
20
|
+
*/
|
|
21
|
+
static enclosing(ip1: IPAddress, ip2: IPAddress): CIDRBlock;
|
|
22
|
+
private static _parse;
|
|
23
|
+
static isValid(input: unknown): input is string;
|
|
24
|
+
static isCidr(input: string): 4 | 6 | 0;
|
|
25
|
+
toString(): string;
|
|
26
|
+
/** The original input address (may differ from network address). */
|
|
27
|
+
address(): IPAddress;
|
|
28
|
+
/** Network address — first IP in block (all host bits 0). */
|
|
29
|
+
first(): IPAddress;
|
|
30
|
+
/** Last IP in block (all host bits 1). */
|
|
31
|
+
last(): IPAddress;
|
|
32
|
+
/**
|
|
33
|
+
* First usable host address.
|
|
34
|
+
* IPv4: network + 1, except /32 (single host).
|
|
35
|
+
* IPv6: network + 1, except /128 (single host).
|
|
36
|
+
*/
|
|
37
|
+
firstUsable(): IPAddress;
|
|
38
|
+
/**
|
|
39
|
+
* Last usable host address.
|
|
40
|
+
* IPv4: broadcast - 1, except /32 (returns broadcast).
|
|
41
|
+
* IPv6: same as last (no broadcast concept).
|
|
42
|
+
*/
|
|
43
|
+
lastUsable(): IPAddress;
|
|
44
|
+
/**
|
|
45
|
+
* IPv4 broadcast address (last IP in block).
|
|
46
|
+
* Throws for IPv6 CIDRs.
|
|
47
|
+
*/
|
|
48
|
+
broadcast(): IPAddress;
|
|
49
|
+
/**
|
|
50
|
+
* IPv4 network address (first IP in block).
|
|
51
|
+
* Throws for IPv6 CIDRs.
|
|
52
|
+
*/
|
|
53
|
+
network(): IPAddress;
|
|
54
|
+
/**
|
|
55
|
+
* Returns true if the given IP is within this CIDR block.
|
|
56
|
+
* The IP version must match the CIDR version exactly.
|
|
57
|
+
*/
|
|
58
|
+
contains(input: IPAddress | string): boolean;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=cidr-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cidr-block.d.ts","sourceRoot":"","sources":["../../../src/utils/cidr-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAiB5C,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IAExB,OAAO;IAWP,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAUlC,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS;IAYrD;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,SAAS;IAe3D,OAAO,CAAC,MAAM,CAAC,MAAM;IAyBrB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM;IAK/C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;IAavC,QAAQ,IAAI,MAAM;IAIlB,oEAAoE;IACpE,OAAO,IAAI,SAAS;IAIpB,6DAA6D;IAC7D,KAAK,IAAI,SAAS;IAIlB,0CAA0C;IAC1C,IAAI,IAAI,SAAS;IAQjB;;;;OAIG;IACH,WAAW,IAAI,SAAS;IASxB;;;;OAIG;IACH,UAAU,IAAI,SAAS;IAUvB;;;OAGG;IACH,SAAS,IAAI,SAAS;IAQtB;;;OAGG;IACH,OAAO,IAAI,SAAS;IAUpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO;CAY/C"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { IPAddress } from './ip-address.js';
|
|
2
|
+
const MAX4 = (1n << 32n) - 1n;
|
|
3
|
+
const MAX6 = (1n << 128n) - 1n;
|
|
4
|
+
function prefixMask(prefix, version) {
|
|
5
|
+
const total = version === 4 ? 32 : 128;
|
|
6
|
+
const hostBits = BigInt(total - prefix);
|
|
7
|
+
const maxVal = version === 4 ? MAX4 : MAX6;
|
|
8
|
+
return maxVal ^ ((1n << hostBits) - 1n);
|
|
9
|
+
}
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// CIDRBlock class
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
export class CIDRBlock {
|
|
14
|
+
_input; // original input address (may not be network addr)
|
|
15
|
+
_network; // network address (all host bits 0)
|
|
16
|
+
_prefix;
|
|
17
|
+
version;
|
|
18
|
+
constructor(input, prefix) {
|
|
19
|
+
this._input = input;
|
|
20
|
+
this._prefix = prefix;
|
|
21
|
+
this.version = input.version;
|
|
22
|
+
const mask = prefixMask(prefix, input.version);
|
|
23
|
+
this._network = IPAddress.fromInt(input.toInt() & mask, input.version);
|
|
24
|
+
}
|
|
25
|
+
// ---- Static factories --------------------------------------------------
|
|
26
|
+
/** Parse "a.b.c.d/n" or "::1/128" CIDR notation. Throws if invalid. */
|
|
27
|
+
static of(cidr) {
|
|
28
|
+
const result = CIDRBlock._parse(cidr);
|
|
29
|
+
if (result === null) {
|
|
30
|
+
throw new Error(`"${cidr}" is not a valid CIDR notation`);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
/** Build a CIDRBlock from an IPAddress and prefix length. */
|
|
35
|
+
static from(ip, prefix) {
|
|
36
|
+
const maxPrefix = ip.version === 4 ? 32 : 128;
|
|
37
|
+
if (!Number.isInteger(prefix) || prefix < 0 || prefix > maxPrefix) {
|
|
38
|
+
throw new Error(`Invalid prefix length ${prefix} for IPv${ip.version}`);
|
|
39
|
+
}
|
|
40
|
+
return new CIDRBlock(ip, prefix);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Return the smallest CIDR block that encloses both IP addresses.
|
|
44
|
+
* Both IPs must be the same version.
|
|
45
|
+
*
|
|
46
|
+
* NOTE: The result is network-aligned and may extend beyond the input IPs.
|
|
47
|
+
* For example, enclosing(192.198.0.1, 192.198.0.254) → 192.198.0.0/24,
|
|
48
|
+
* which includes 192.198.0.0 and 192.198.0.255. This is a CIDR/routing
|
|
49
|
+
* operation — use IPRange for arbitrary range containment checks.
|
|
50
|
+
*/
|
|
51
|
+
static enclosing(ip1, ip2) {
|
|
52
|
+
if (ip1.version !== ip2.version) {
|
|
53
|
+
throw new Error('Both IPs must be the same version to compute enclosing CIDR');
|
|
54
|
+
}
|
|
55
|
+
const xor = ip1.toInt() ^ ip2.toInt();
|
|
56
|
+
const totalBits = ip1.version === 4 ? 32 : 128;
|
|
57
|
+
const hostBits = xor === 0n ? 0 : xor.toString(2).length;
|
|
58
|
+
const prefix = totalBits - hostBits;
|
|
59
|
+
return CIDRBlock.from(ip1, prefix);
|
|
60
|
+
}
|
|
61
|
+
static _parse(cidr) {
|
|
62
|
+
if (typeof cidr !== 'string')
|
|
63
|
+
return null;
|
|
64
|
+
const slashIdx = cidr.lastIndexOf('/');
|
|
65
|
+
if (slashIdx < 0)
|
|
66
|
+
return null;
|
|
67
|
+
const ipStr = cidr.slice(0, slashIdx);
|
|
68
|
+
const prefixStr = cidr.slice(slashIdx + 1);
|
|
69
|
+
// Prefix must be a non-negative integer with no leading zeros (except "0")
|
|
70
|
+
if (!/^\d+$/.test(prefixStr))
|
|
71
|
+
return null;
|
|
72
|
+
if (prefixStr.length > 1 && prefixStr[0] === '0')
|
|
73
|
+
return null;
|
|
74
|
+
const prefix = parseInt(prefixStr, 10);
|
|
75
|
+
if (!IPAddress.isValid(ipStr))
|
|
76
|
+
return null;
|
|
77
|
+
const ip = IPAddress.of(ipStr);
|
|
78
|
+
const maxPrefix = ip.version === 4 ? 32 : 128;
|
|
79
|
+
if (prefix > maxPrefix)
|
|
80
|
+
return null;
|
|
81
|
+
return new CIDRBlock(ip, prefix);
|
|
82
|
+
}
|
|
83
|
+
// ---- Static validators -------------------------------------------------
|
|
84
|
+
static isValid(input) {
|
|
85
|
+
if (typeof input !== 'string')
|
|
86
|
+
return false;
|
|
87
|
+
return CIDRBlock._parse(input) !== null;
|
|
88
|
+
}
|
|
89
|
+
static isCidr(input) {
|
|
90
|
+
if (typeof input !== 'string')
|
|
91
|
+
return 0;
|
|
92
|
+
const block = CIDRBlock._parse(input);
|
|
93
|
+
if (block === null)
|
|
94
|
+
return 0;
|
|
95
|
+
if (block._prefix === 0)
|
|
96
|
+
return 0;
|
|
97
|
+
return block.version;
|
|
98
|
+
}
|
|
99
|
+
// ---- Instance methods --------------------------------------------------
|
|
100
|
+
toString() {
|
|
101
|
+
return `${this._network.toString()}/${this._prefix}`;
|
|
102
|
+
}
|
|
103
|
+
/** The original input address (may differ from network address). */
|
|
104
|
+
address() {
|
|
105
|
+
return this._input;
|
|
106
|
+
}
|
|
107
|
+
/** Network address — first IP in block (all host bits 0). */
|
|
108
|
+
first() {
|
|
109
|
+
return this._network;
|
|
110
|
+
}
|
|
111
|
+
/** Last IP in block (all host bits 1). */
|
|
112
|
+
last() {
|
|
113
|
+
const totalBits = this.version === 4 ? 32 : 128;
|
|
114
|
+
const hostBits = BigInt(totalBits - this._prefix);
|
|
115
|
+
const lastInt = this._network.toInt() | ((1n << hostBits) - 1n);
|
|
116
|
+
return IPAddress.fromInt(lastInt, this.version);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* First usable host address.
|
|
120
|
+
* IPv4: network + 1, except /32 (single host).
|
|
121
|
+
* IPv6: network + 1, except /128 (single host).
|
|
122
|
+
*/
|
|
123
|
+
firstUsable() {
|
|
124
|
+
const f = this.first();
|
|
125
|
+
const l = this.last();
|
|
126
|
+
if (f.toInt() === l.toInt())
|
|
127
|
+
return f;
|
|
128
|
+
return f.offset(1n);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Last usable host address.
|
|
132
|
+
* IPv4: broadcast - 1, except /32 (returns broadcast).
|
|
133
|
+
* IPv6: same as last (no broadcast concept).
|
|
134
|
+
*/
|
|
135
|
+
lastUsable() {
|
|
136
|
+
const f = this.first();
|
|
137
|
+
const l = this.last();
|
|
138
|
+
if (f.toInt() === l.toInt())
|
|
139
|
+
return l;
|
|
140
|
+
if (this.version === 4)
|
|
141
|
+
return l.offset(-1n);
|
|
142
|
+
return l;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* IPv4 broadcast address (last IP in block).
|
|
146
|
+
* Throws for IPv6 CIDRs.
|
|
147
|
+
*/
|
|
148
|
+
broadcast() {
|
|
149
|
+
if (this.version !== 4) {
|
|
150
|
+
throw new Error('IPv6 addresses do not have a broadcast address');
|
|
151
|
+
}
|
|
152
|
+
return this.last();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* IPv4 network address (first IP in block).
|
|
156
|
+
* Throws for IPv6 CIDRs.
|
|
157
|
+
*/
|
|
158
|
+
network() {
|
|
159
|
+
if (this.version !== 4) {
|
|
160
|
+
throw new Error('IPv6 addresses do not have a network address in the IPv4 sense');
|
|
161
|
+
}
|
|
162
|
+
return this.first();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns true if the given IP is within this CIDR block.
|
|
166
|
+
* The IP version must match the CIDR version exactly.
|
|
167
|
+
*/
|
|
168
|
+
contains(input) {
|
|
169
|
+
try {
|
|
170
|
+
const ip = typeof input === 'string' ? IPAddress.of(input) : input;
|
|
171
|
+
if (ip.version !== this.version)
|
|
172
|
+
return false;
|
|
173
|
+
const n = ip.toInt();
|
|
174
|
+
return n >= this._network.toInt() && n <= this.last().toInt();
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=cidr-block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cidr-block.js","sourceRoot":"","sources":["../../../src/utils/cidr-block.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare class IPAddress {
|
|
2
|
+
readonly version: 4 | 6;
|
|
3
|
+
private readonly _int;
|
|
4
|
+
private readonly _scopeId;
|
|
5
|
+
/** True when parsed from ::a.b.c.d (deprecated IPv4-compatible) notation. */
|
|
6
|
+
private readonly _isIPv4Compat;
|
|
7
|
+
private constructor();
|
|
8
|
+
static of(input: string): IPAddress;
|
|
9
|
+
static fromInt(n: bigint, version: 4 | 6): IPAddress;
|
|
10
|
+
private static _parse;
|
|
11
|
+
static isValid(input: unknown): input is string;
|
|
12
|
+
static isIPv4(input: unknown): boolean;
|
|
13
|
+
static isIPv6(input: unknown): boolean;
|
|
14
|
+
static ipVersion(input: string): 4 | 6 | undefined;
|
|
15
|
+
toInt(): bigint;
|
|
16
|
+
toString(): string;
|
|
17
|
+
/** Normalized full-groups string (no :: compression). Used by reverseIP. */
|
|
18
|
+
toNormalizedString(): string;
|
|
19
|
+
compare(other: IPAddress): -1 | 0 | 1;
|
|
20
|
+
offset(n: bigint): IPAddress;
|
|
21
|
+
/**
|
|
22
|
+
* Returns true for ::ffff:a.b.c.d (IPv4-mapped) addresses.
|
|
23
|
+
* Note: ::a.b.c.d is rewritten to ::ffff:a.b.c.d during parsing,
|
|
24
|
+
* so those also return true (matching ipaddr.js behaviour).
|
|
25
|
+
*/
|
|
26
|
+
isMappedIPv4(): boolean;
|
|
27
|
+
/** Extract the embedded IPv4 from an IPv4-mapped IPv6 address. */
|
|
28
|
+
toMappedIPv4(): IPAddress;
|
|
29
|
+
isRoutable(): boolean;
|
|
30
|
+
/** Returns DNS PTR reverse format. */
|
|
31
|
+
reverse(): string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=ip-address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-address.d.ts","sourceRoot":"","sources":["../../../src/utils/ip-address.ts"],"names":[],"mappings":"AA0OA,qBAAa,SAAS;IAClB,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IAExC,OAAO;IAcP,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAUnC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAIpD,OAAO,CAAC,MAAM,CAAC,MAAM;IAqBrB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM;IAI/C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAKtC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAOtC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS;IASlD,KAAK,IAAI,MAAM;IAIf,QAAQ,IAAI,MAAM;IAUlB,4EAA4E;IAC5E,kBAAkB,IAAI,MAAM;IAY5B,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAOrC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS;IAI5B;;;;OAIG;IACH,YAAY,IAAI,OAAO;IAYvB,kEAAkE;IAClE,YAAY,IAAI,SAAS;IAUzB,UAAU,IAAI,OAAO;IAYrB,sCAAsC;IACtC,OAAO,IAAI,MAAM;CASpB"}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Parsing helpers
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
const IPV4_OCTET = '(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)';
|
|
5
|
+
const IPV4_RE = new RegExp(`^${IPV4_OCTET}\\.${IPV4_OCTET}\\.${IPV4_OCTET}\\.${IPV4_OCTET}$`);
|
|
6
|
+
/** Parse dotted-quad IPv4 string → BigInt. Returns null on failure. */
|
|
7
|
+
function parseIPv4Int(input) {
|
|
8
|
+
if (!IPV4_RE.test(input))
|
|
9
|
+
return null;
|
|
10
|
+
const parts = input.split('.');
|
|
11
|
+
let n = 0n;
|
|
12
|
+
for (const p of parts) {
|
|
13
|
+
n = (n << 8n) | BigInt(parseInt(p, 10));
|
|
14
|
+
}
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
/** Convert 32-bit BigInt → dotted-quad string. */
|
|
18
|
+
function intToIPv4String(n) {
|
|
19
|
+
return [
|
|
20
|
+
(n >> 24n) & 0xffn,
|
|
21
|
+
(n >> 16n) & 0xffn,
|
|
22
|
+
(n >> 8n) & 0xffn,
|
|
23
|
+
n & 0xffn,
|
|
24
|
+
]
|
|
25
|
+
.map(String)
|
|
26
|
+
.join('.');
|
|
27
|
+
}
|
|
28
|
+
function parseIPv6Int(raw) {
|
|
29
|
+
// Strip scope ID
|
|
30
|
+
const scopeIdx = raw.indexOf('%');
|
|
31
|
+
const input = scopeIdx >= 0 ? raw.slice(0, scopeIdx) : raw;
|
|
32
|
+
const s = input.toLowerCase();
|
|
33
|
+
// Detect embedded IPv4 in last position
|
|
34
|
+
// Match optional leading groups + dotted-quad tail
|
|
35
|
+
const embeddedIPv4Re = /^(.*:)(\d+\.\d+\.\d+\.\d+)$/;
|
|
36
|
+
const embeddedMatch = s.match(embeddedIPv4Re);
|
|
37
|
+
let normalized = s;
|
|
38
|
+
if (embeddedMatch) {
|
|
39
|
+
const prefix = embeddedMatch[1]; // everything up to and including last ':'
|
|
40
|
+
const v4str = embeddedMatch[2];
|
|
41
|
+
const v4int = parseIPv4Int(v4str);
|
|
42
|
+
if (v4int === null)
|
|
43
|
+
return null;
|
|
44
|
+
const high16 = (v4int >> 16n) & 0xffffn;
|
|
45
|
+
const low16 = v4int & 0xffffn;
|
|
46
|
+
const v4hex = `${high16.toString(16)}:${low16.toString(16)}`;
|
|
47
|
+
normalized = `${prefix}${v4hex}`;
|
|
48
|
+
}
|
|
49
|
+
// Expand :: compression
|
|
50
|
+
const halves = normalized.split('::');
|
|
51
|
+
if (halves.length > 2)
|
|
52
|
+
return null; // multiple :: not allowed
|
|
53
|
+
let groups;
|
|
54
|
+
if (halves.length === 2) {
|
|
55
|
+
const left = halves[0] ? halves[0].split(':') : [];
|
|
56
|
+
const right = halves[1] ? halves[1].split(':') : [];
|
|
57
|
+
const missing = 8 - left.length - right.length;
|
|
58
|
+
if (missing <= 0)
|
|
59
|
+
return null;
|
|
60
|
+
groups = [...left, ...Array(missing).fill('0'), ...right];
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
groups = normalized.split(':');
|
|
64
|
+
}
|
|
65
|
+
if (groups.length !== 8)
|
|
66
|
+
return null;
|
|
67
|
+
let n = 0n;
|
|
68
|
+
for (const g of groups) {
|
|
69
|
+
if (!/^[0-9a-f]{1,4}$/.test(g))
|
|
70
|
+
return null;
|
|
71
|
+
n = (n << 16n) | BigInt(parseInt(g, 16));
|
|
72
|
+
}
|
|
73
|
+
return n;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Detect IPv6 scope ID for preservation in toString.
|
|
77
|
+
*/
|
|
78
|
+
function extractScopeId(raw) {
|
|
79
|
+
const idx = raw.indexOf('%');
|
|
80
|
+
return idx >= 0 ? raw.slice(idx + 1) : undefined;
|
|
81
|
+
}
|
|
82
|
+
/** Convert 128-bit BigInt → compressed IPv6 string (RFC 5952). */
|
|
83
|
+
function intToIPv6String(n) {
|
|
84
|
+
const groups = [];
|
|
85
|
+
for (let i = 7; i >= 0; i--) {
|
|
86
|
+
groups.push(Number((n >> BigInt(i * 16)) & 0xffffn));
|
|
87
|
+
}
|
|
88
|
+
const hex = groups.map((g) => g.toString(16));
|
|
89
|
+
// Find longest run of consecutive zero groups for :: compression
|
|
90
|
+
let bestStart = -1;
|
|
91
|
+
let bestLen = 0;
|
|
92
|
+
let curStart = -1;
|
|
93
|
+
let curLen = 0;
|
|
94
|
+
for (let i = 0; i < 8; i++) {
|
|
95
|
+
if (groups[i] === 0) {
|
|
96
|
+
if (curStart < 0) {
|
|
97
|
+
curStart = i;
|
|
98
|
+
curLen = 0;
|
|
99
|
+
}
|
|
100
|
+
curLen++;
|
|
101
|
+
if (curLen > bestLen) {
|
|
102
|
+
bestLen = curLen;
|
|
103
|
+
bestStart = curStart;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
curStart = -1;
|
|
108
|
+
curLen = 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (bestLen < 2) {
|
|
112
|
+
return hex.join(':');
|
|
113
|
+
}
|
|
114
|
+
const left = hex.slice(0, bestStart).join(':');
|
|
115
|
+
const right = hex.slice(bestStart + bestLen).join(':');
|
|
116
|
+
return `${left}::${right}`;
|
|
117
|
+
}
|
|
118
|
+
function cidr4(a, b, c, d, prefix) {
|
|
119
|
+
const base = BigInt(((a * 256 + b) * 256 + c) * 256 + d);
|
|
120
|
+
const hostBits = BigInt(32 - prefix);
|
|
121
|
+
const mask = ((1n << 32n) - 1n) ^ ((1n << hostBits) - 1n);
|
|
122
|
+
return { lo: base & mask, hi: (base & mask) | ((1n << hostBits) - 1n) };
|
|
123
|
+
}
|
|
124
|
+
// All IPv4 ranges considered non-routable
|
|
125
|
+
const NON_ROUTABLE_IPV4 = [
|
|
126
|
+
cidr4(0, 0, 0, 0, 8), // unspecified
|
|
127
|
+
cidr4(10, 0, 0, 0, 8), // private
|
|
128
|
+
cidr4(100, 64, 0, 0, 10), // carrier-grade NAT
|
|
129
|
+
cidr4(127, 0, 0, 0, 8), // loopback
|
|
130
|
+
cidr4(169, 254, 0, 0, 16), // link-local
|
|
131
|
+
cidr4(172, 16, 0, 0, 12), // private
|
|
132
|
+
cidr4(192, 0, 0, 0, 24), // reserved (IETF protocol)
|
|
133
|
+
cidr4(192, 0, 2, 0, 24), // documentation (TEST-NET-1)
|
|
134
|
+
cidr4(192, 31, 196, 0, 24), // AS112-v4 (RFC 7534)
|
|
135
|
+
cidr4(192, 52, 193, 0, 24), // AMT (RFC 7450)
|
|
136
|
+
cidr4(192, 88, 99, 0, 24), // 6to4 relay anycast (deprecated)
|
|
137
|
+
cidr4(192, 168, 0, 0, 16), // private
|
|
138
|
+
cidr4(192, 175, 48, 0, 24), // AS112-v4 (RFC 7535)
|
|
139
|
+
cidr4(198, 18, 0, 0, 15), // benchmarking
|
|
140
|
+
cidr4(198, 51, 100, 0, 24), // documentation (TEST-NET-2)
|
|
141
|
+
cidr4(203, 0, 113, 0, 24), // documentation (TEST-NET-3)
|
|
142
|
+
cidr4(224, 0, 0, 0, 8), // multicast (restricted block)
|
|
143
|
+
cidr4(240, 0, 0, 0, 4), // reserved (class E)
|
|
144
|
+
cidr4(255, 255, 255, 255, 32), // broadcast
|
|
145
|
+
];
|
|
146
|
+
function cidr6(groups, prefix) {
|
|
147
|
+
let base = 0n;
|
|
148
|
+
for (const g of groups) {
|
|
149
|
+
base = (base << 16n) | BigInt(g);
|
|
150
|
+
}
|
|
151
|
+
const hostBits = BigInt(128 - prefix);
|
|
152
|
+
const mask = ((1n << 128n) - 1n) ^ ((1n << hostBits) - 1n);
|
|
153
|
+
return { lo: base & mask, hi: (base & mask) | ((1n << hostBits) - 1n) };
|
|
154
|
+
}
|
|
155
|
+
// All IPv6 ranges considered non-routable
|
|
156
|
+
const NON_ROUTABLE_IPV6 = [
|
|
157
|
+
cidr6([0, 0, 0, 0, 0, 0, 0, 0], 128), // unspecified ::
|
|
158
|
+
cidr6([0, 0, 0, 0, 0, 0, 0, 1], 128), // loopback ::1
|
|
159
|
+
cidr6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0], 96), // RFC 6052 NAT64
|
|
160
|
+
cidr6([0x64, 0xff9b, 1, 0, 0, 0, 0, 0], 48), // RFC 8215 local NAT64
|
|
161
|
+
cidr6([0x100, 0, 0, 0, 0, 0, 0, 0], 64), // discard (RFC 6666)
|
|
162
|
+
cidr6([0xfc00, 0, 0, 0, 0, 0, 0, 0], 7), // unique local (fc00::/7)
|
|
163
|
+
cidr6([0xfe80, 0, 0, 0, 0, 0, 0, 0], 10), // link-local
|
|
164
|
+
cidr6([0xff00, 0, 0, 0, 0, 0, 0, 0], 8), // multicast
|
|
165
|
+
cidr6([0, 0, 0, 0, 0, 0xffff, 0, 0], 96), // IPv4-mapped (::ffff:0:0/96)
|
|
166
|
+
cidr6([0x2001, 0, 0, 0, 0, 0, 0, 0], 23), // IANA special (includes teredo, benchmarking, etc.)
|
|
167
|
+
cidr6([0x2001, 0x0db8, 0, 0, 0, 0, 0, 0], 32), // documentation (RFC 3849)
|
|
168
|
+
cidr6([0x2002, 0, 0, 0, 0, 0, 0, 0], 16), // 6to4
|
|
169
|
+
cidr6([0x2620, 0x4f, 0x8000, 0, 0, 0, 0, 0], 48), // AS112-v6
|
|
170
|
+
];
|
|
171
|
+
function isInRange(n, ranges) {
|
|
172
|
+
for (const r of ranges) {
|
|
173
|
+
if (n >= r.lo && n <= r.hi)
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
// IPAddress class
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
/** Matches ::a.b.c.d (deprecated IPv4-compatible) — no ffff groups. */
|
|
182
|
+
const IPV4_COMPAT_RE = /^::(\d+\.\d+\.\d+\.\d+)(%.*)?$/i;
|
|
183
|
+
export class IPAddress {
|
|
184
|
+
version;
|
|
185
|
+
_int;
|
|
186
|
+
_scopeId;
|
|
187
|
+
/** True when parsed from ::a.b.c.d (deprecated IPv4-compatible) notation. */
|
|
188
|
+
_isIPv4Compat;
|
|
189
|
+
constructor(int, version, scopeId, isIPv4Compat = false) {
|
|
190
|
+
this._int = int;
|
|
191
|
+
this.version = version;
|
|
192
|
+
this._scopeId = scopeId;
|
|
193
|
+
this._isIPv4Compat = isIPv4Compat;
|
|
194
|
+
}
|
|
195
|
+
// ---- Static factories --------------------------------------------------
|
|
196
|
+
static of(input) {
|
|
197
|
+
const result = IPAddress._parse(input);
|
|
198
|
+
if (result === null) {
|
|
199
|
+
throw new TypeError(`"${input}" is not a valid IP address`);
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
static fromInt(n, version) {
|
|
204
|
+
return new IPAddress(n, version);
|
|
205
|
+
}
|
|
206
|
+
static _parse(input) {
|
|
207
|
+
if (typeof input !== 'string')
|
|
208
|
+
return null;
|
|
209
|
+
// Try IPv4 first (no colon present)
|
|
210
|
+
if (!input.includes(':')) {
|
|
211
|
+
const n = parseIPv4Int(input);
|
|
212
|
+
return n !== null ? new IPAddress(n, 4) : null;
|
|
213
|
+
}
|
|
214
|
+
// IPv6 (may have embedded IPv4, scope ID)
|
|
215
|
+
const scopeId = extractScopeId(input);
|
|
216
|
+
const n = parseIPv6Int(input);
|
|
217
|
+
if (n === null)
|
|
218
|
+
return null;
|
|
219
|
+
const isIPv4Compat = IPV4_COMPAT_RE.test(input);
|
|
220
|
+
return new IPAddress(n, 6, scopeId, isIPv4Compat);
|
|
221
|
+
}
|
|
222
|
+
// ---- Static validators -------------------------------------------------
|
|
223
|
+
static isValid(input) {
|
|
224
|
+
return typeof input === 'string' && IPAddress._parse(input) !== null;
|
|
225
|
+
}
|
|
226
|
+
static isIPv4(input) {
|
|
227
|
+
if (typeof input !== 'string')
|
|
228
|
+
return false;
|
|
229
|
+
return parseIPv4Int(input) !== null;
|
|
230
|
+
}
|
|
231
|
+
static isIPv6(input) {
|
|
232
|
+
if (typeof input !== 'string')
|
|
233
|
+
return false;
|
|
234
|
+
if (!input.includes(':'))
|
|
235
|
+
return false;
|
|
236
|
+
return parseIPv6Int(input) !== null;
|
|
237
|
+
}
|
|
238
|
+
static ipVersion(input) {
|
|
239
|
+
if (IPAddress.isIPv4(input))
|
|
240
|
+
return 4;
|
|
241
|
+
if (IPAddress.isIPv6(input))
|
|
242
|
+
return 6;
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
// ---- Instance methods --------------------------------------------------
|
|
246
|
+
toInt() {
|
|
247
|
+
return this._int;
|
|
248
|
+
}
|
|
249
|
+
toString() {
|
|
250
|
+
if (this.version === 4) {
|
|
251
|
+
return intToIPv4String(this._int);
|
|
252
|
+
}
|
|
253
|
+
const base = intToIPv6String(this._int);
|
|
254
|
+
return this._scopeId ? `${base}%${this._scopeId}` : base;
|
|
255
|
+
}
|
|
256
|
+
/** Normalized full-groups string (no :: compression). Used by reverseIP. */
|
|
257
|
+
toNormalizedString() {
|
|
258
|
+
if (this.version === 4)
|
|
259
|
+
return this.toString();
|
|
260
|
+
const groups = [];
|
|
261
|
+
for (let i = 7; i >= 0; i--) {
|
|
262
|
+
groups.push(((this._int >> BigInt(i * 16)) & 0xffffn).toString(16));
|
|
263
|
+
}
|
|
264
|
+
return groups.join(':');
|
|
265
|
+
}
|
|
266
|
+
compare(other) {
|
|
267
|
+
if (this._int < other._int)
|
|
268
|
+
return -1;
|
|
269
|
+
if (this._int > other._int)
|
|
270
|
+
return 1;
|
|
271
|
+
return 0;
|
|
272
|
+
}
|
|
273
|
+
offset(n) {
|
|
274
|
+
return new IPAddress(this._int + n, this.version);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Returns true for ::ffff:a.b.c.d (IPv4-mapped) addresses.
|
|
278
|
+
* Note: ::a.b.c.d is rewritten to ::ffff:a.b.c.d during parsing,
|
|
279
|
+
* so those also return true (matching ipaddr.js behaviour).
|
|
280
|
+
*/
|
|
281
|
+
isMappedIPv4() {
|
|
282
|
+
if (this.version !== 6)
|
|
283
|
+
return false;
|
|
284
|
+
// ::a.b.c.d (IPv4-compatible, deprecated) — treated as mapped per ipaddr.js
|
|
285
|
+
if (this._isIPv4Compat)
|
|
286
|
+
return true;
|
|
287
|
+
// IPv4-mapped range: ::ffff:0:0/96
|
|
288
|
+
// First 80 bits must be 0, next 16 bits must be 0xffff
|
|
289
|
+
const high80 = this._int >> 48n;
|
|
290
|
+
const ffff = (this._int >> 32n) & 0xffffn;
|
|
291
|
+
return high80 === 0n && ffff === 0xffffn;
|
|
292
|
+
}
|
|
293
|
+
/** Extract the embedded IPv4 from an IPv4-mapped IPv6 address. */
|
|
294
|
+
toMappedIPv4() {
|
|
295
|
+
if (!this.isMappedIPv4()) {
|
|
296
|
+
throw new Error('input must be an IPv4 address mapped to an IPv6 address');
|
|
297
|
+
}
|
|
298
|
+
return new IPAddress(this._int & 0xffffffffn, 4);
|
|
299
|
+
}
|
|
300
|
+
isRoutable() {
|
|
301
|
+
if (this.version === 4) {
|
|
302
|
+
return !isInRange(this._int, NON_ROUTABLE_IPV4);
|
|
303
|
+
}
|
|
304
|
+
// For IPv6, if it's IPv4-mapped, classify the embedded IPv4
|
|
305
|
+
if (this.isMappedIPv4()) {
|
|
306
|
+
return !isInRange(this._int & 0xffffffffn, NON_ROUTABLE_IPV4);
|
|
307
|
+
}
|
|
308
|
+
return !isInRange(this._int, NON_ROUTABLE_IPV6);
|
|
309
|
+
}
|
|
310
|
+
/** Returns DNS PTR reverse format. */
|
|
311
|
+
reverse() {
|
|
312
|
+
if (this.version === 4) {
|
|
313
|
+
return intToIPv4String(this._int)
|
|
314
|
+
.split('.')
|
|
315
|
+
.reverse()
|
|
316
|
+
.join('.');
|
|
317
|
+
}
|
|
318
|
+
return _reverseIPv6(this);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function _reverseIPv6(ip) {
|
|
322
|
+
// Expand to full 32 hex nibbles, then reverse with dots
|
|
323
|
+
return ip
|
|
324
|
+
.toNormalizedString()
|
|
325
|
+
.split(':')
|
|
326
|
+
.map((g) => g.padStart(4, '0'))
|
|
327
|
+
.join('')
|
|
328
|
+
.split('')
|
|
329
|
+
.reverse()
|
|
330
|
+
.join('.');
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=ip-address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-address.js","sourceRoot":"","sources":["../../../src/utils/ip-address.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IPAddress } from './ip-address.js';
|
|
2
|
+
import { CIDRBlock } from './cidr-block.js';
|
|
3
|
+
export declare class IPRange {
|
|
4
|
+
readonly minValue: IPAddress;
|
|
5
|
+
readonly maxValue: IPAddress;
|
|
6
|
+
readonly version: 4 | 6;
|
|
7
|
+
private constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Build an IPRange from two IPAddress boundary values (inclusive).
|
|
10
|
+
* Both must be the same IP version and min must be <= max.
|
|
11
|
+
*/
|
|
12
|
+
static from(min: IPAddress, max: IPAddress): IPRange;
|
|
13
|
+
toString(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Returns true if the given IP address falls within this range (inclusive).
|
|
16
|
+
* The IP version must match the range version exactly.
|
|
17
|
+
*/
|
|
18
|
+
contains(input: IPAddress | string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Returns true if the given CIDR block is fully contained within this range.
|
|
21
|
+
* Both the CIDR's network address (first) and broadcast address (last) must
|
|
22
|
+
* fall within [minValue, maxValue]. This ensures exclusive range bounds are
|
|
23
|
+
* respected for the entire CIDR, not just the usable host addresses.
|
|
24
|
+
*/
|
|
25
|
+
containsCIDR(cidr: CIDRBlock): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=ip-range.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-range.d.ts","sourceRoot":"","sources":["../../../src/utils/ip-range.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,OAAO;IAChB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IAExB,OAAO;IAQP;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO;IAiBpD,QAAQ,IAAI,MAAM;IAIlB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO;IAY5C;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;CAQzC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { IPAddress } from './ip-address.js';
|
|
2
|
+
export class IPRange {
|
|
3
|
+
minValue;
|
|
4
|
+
maxValue;
|
|
5
|
+
version;
|
|
6
|
+
constructor(min, max) {
|
|
7
|
+
this.minValue = min;
|
|
8
|
+
this.maxValue = max;
|
|
9
|
+
this.version = min.version;
|
|
10
|
+
}
|
|
11
|
+
// ---- Static factories --------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Build an IPRange from two IPAddress boundary values (inclusive).
|
|
14
|
+
* Both must be the same IP version and min must be <= max.
|
|
15
|
+
*/
|
|
16
|
+
static from(min, max) {
|
|
17
|
+
if (min.version !== max.version) {
|
|
18
|
+
throw new Error(`IPRange boundaries must be the same version: got IPv${min.version} and IPv${max.version}`);
|
|
19
|
+
}
|
|
20
|
+
if (min.toInt() > max.toInt()) {
|
|
21
|
+
throw new Error(`IPRange min (${min.toString()}) must be <= max (${max.toString()})`);
|
|
22
|
+
}
|
|
23
|
+
return new IPRange(min, max);
|
|
24
|
+
}
|
|
25
|
+
// ---- Instance methods --------------------------------------------------
|
|
26
|
+
toString() {
|
|
27
|
+
return `${this.minValue.toString()} - ${this.maxValue.toString()}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns true if the given IP address falls within this range (inclusive).
|
|
31
|
+
* The IP version must match the range version exactly.
|
|
32
|
+
*/
|
|
33
|
+
contains(input) {
|
|
34
|
+
try {
|
|
35
|
+
const ip = typeof input === 'string' ? IPAddress.of(input) : input;
|
|
36
|
+
if (ip.version !== this.version)
|
|
37
|
+
return false;
|
|
38
|
+
const n = ip.toInt();
|
|
39
|
+
return n >= this.minValue.toInt() && n <= this.maxValue.toInt();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the given CIDR block is fully contained within this range.
|
|
47
|
+
* Both the CIDR's network address (first) and broadcast address (last) must
|
|
48
|
+
* fall within [minValue, maxValue]. This ensures exclusive range bounds are
|
|
49
|
+
* respected for the entire CIDR, not just the usable host addresses.
|
|
50
|
+
*/
|
|
51
|
+
containsCIDR(cidr) {
|
|
52
|
+
if (cidr.version !== this.version)
|
|
53
|
+
return false;
|
|
54
|
+
return (cidr.first().toInt() >= this.minValue.toInt()
|
|
55
|
+
&& cidr.last().toInt() <= this.maxValue.toInt());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ip-range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-range.js","sourceRoot":"","sources":["../../../src/utils/ip-range.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,OAAO,OAAO;IACP,QAAQ,CAAY;IACpB,QAAQ,CAAY;IACpB,OAAO,CAAQ;IAExB,YAAoB,GAAc,EAAE,GAAc;QAC9C,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,2EAA2E;IAE3E;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,GAAc,EAAE,GAAc;QACtC,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACX,uDAAuD,GAAG,CAAC,OAAO,WAAW,GAAG,CAAC,OAAO,EAAE,CAC7F,CAAC;QACN,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACX,gBAAgB,GAAG,CAAC,QAAQ,EAAE,qBAAqB,GAAG,CAAC,QAAQ,EAAE,GAAG,CACvE,CAAC;QACN,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,2EAA2E;IAE3E,QAAQ;QACJ,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;IACvE,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAyB;QAC9B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACnE,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC;YAE9C,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,IAAe;QACxB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAEhD,OAAO,CACH,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;eAC1C,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAClD,CAAC;IACN,CAAC;CACJ"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terascope/ip-utils",
|
|
3
3
|
"displayName": "IP Utils",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"description": "A collection of Teraslice IP Utilities",
|
|
6
6
|
"homepage": "https://github.com/terascope/teraslice/tree/master/packages/ip-utils#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -18,19 +18,9 @@
|
|
|
18
18
|
"dist/src/**/*"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@chainsafe/is-ip": "~2.1.0",
|
|
22
|
-
"cidr-calc": "^1.0.4",
|
|
23
|
-
"ip-bigint": "~8.2.7",
|
|
24
|
-
"ip-cidr": "~4.0.2",
|
|
25
|
-
"ip6addr": "~0.2.5",
|
|
26
|
-
"ipaddr.js": "~2.3.0",
|
|
27
|
-
"is-cidr": "~6.0.3",
|
|
28
21
|
"@terascope/core-utils": "~2.3.2",
|
|
29
22
|
"@terascope/types": "~2.3.1"
|
|
30
23
|
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@types/ip6addr": "~0.2.6"
|
|
33
|
-
},
|
|
34
24
|
"engines": {
|
|
35
25
|
"node": ">=22.0.0",
|
|
36
26
|
"pnpm": ">=10.25.0"
|