mybase 1.1.28 → 1.1.30
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/package.json +9 -9
- package/ts/funcs/isLANIp.js +12 -12
- package/ts/funcs/isLANIp.ts +15 -16
- package/ts/funcs/isLoopbackIP.js +14 -12
- package/ts/funcs/isLoopbackIP.ts +12 -12
- package/ts/index.test.ts +1 -1
- package/ts/models/IPAddress.js +113 -28
- package/ts/models/IPAddress.test.ts +134 -15
- package/ts/models/IPAddress.ts +102 -7
- package/tsconfig.json +2 -1
- package/types/ip6addr.d.ts +46 -0
- package/ts/models/IPAddress.jest.js +0 -165
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mybase",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "mybase.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,25 +10,25 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@7c/validurl": "0.0.3",
|
|
13
|
+
"@types/debug": "^4.1.12",
|
|
14
|
+
"@types/ip6addr": "^0.2.6",
|
|
15
|
+
"@types/mysql": "^2.15.25",
|
|
16
|
+
"@types/node": "^20.11.5",
|
|
17
|
+
"@types/request": "^2.48.12",
|
|
18
|
+
"@types/validator": "^13.11.8",
|
|
13
19
|
"aes-js": "^3.1.2",
|
|
14
20
|
"chalk": "^3.0.0",
|
|
15
21
|
"debug": "^4.3.4",
|
|
16
22
|
"ip-range-check": "^0.2.0",
|
|
17
23
|
"ip6": "=0.2.7",
|
|
18
|
-
"ip6addr": "
|
|
24
|
+
"ip6addr": "github:7c/node-ip6addr#db6d558af1f314bcb0a733fd61611fa85e1a3eff",
|
|
19
25
|
"js-sha512": "^0.8.0",
|
|
20
26
|
"mysql": "^2.18.1",
|
|
21
27
|
"mysql2": "^3.9.1",
|
|
22
28
|
"node-vault": "^0.10.2",
|
|
23
29
|
"psl": "^1.9.0",
|
|
24
30
|
"punycode": "^2.1.1",
|
|
25
|
-
"validator": "^13.7.0"
|
|
26
|
-
"@types/debug": "^4.1.12",
|
|
27
|
-
"@types/ip6addr": "^0.2.6",
|
|
28
|
-
"@types/mysql": "^2.15.25",
|
|
29
|
-
"@types/node": "^20.11.5",
|
|
30
|
-
"@types/validator": "^13.11.8",
|
|
31
|
-
"@types/request": "^2.48.12"
|
|
31
|
+
"validator": "^13.7.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@jest/globals": "^29.7.0",
|
package/ts/funcs/isLANIp.js
CHANGED
|
@@ -3,24 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isLANIp = void 0;
|
|
6
|
+
exports.isLANIp = exports.private_network_cidrs = void 0;
|
|
7
7
|
const ip6addr_1 = __importDefault(require("ip6addr"));
|
|
8
8
|
const net_1 = __importDefault(require("net"));
|
|
9
|
-
|
|
9
|
+
exports.private_network_cidrs = [
|
|
10
|
+
ip6addr_1.default.createCIDR('10.0.0.0/8'),
|
|
10
11
|
ip6addr_1.default.createCIDR('172.16.0.0/12'),
|
|
11
12
|
ip6addr_1.default.createCIDR('192.168.0.0/16'),
|
|
12
13
|
ip6addr_1.default.createCIDR('fd00::/8'), // Reserved by IETF for future use, but not currently in active use.
|
|
13
|
-
,
|
|
14
14
|
ip6addr_1.default.createCIDR('fc00::/8'), // The range currently in use for local communications within a site or organization.
|
|
15
15
|
];
|
|
16
|
-
function normalizeIp(ip) {
|
|
17
|
-
// also support ipv6
|
|
18
|
-
if (net_1.default.isIP(ip) === 0)
|
|
19
|
-
return '';
|
|
20
|
-
if (net_1.default.isIPv6(ip))
|
|
21
|
-
return ip.toLowerCase().replace(/^::ffff:/, '');
|
|
22
|
-
return ip;
|
|
23
|
-
}
|
|
24
16
|
function isLANIp(ip) {
|
|
25
17
|
ip = normalizeIp(ip);
|
|
26
18
|
if (net_1.default.isIP(ip) === 0)
|
|
@@ -28,7 +20,7 @@ function isLANIp(ip) {
|
|
|
28
20
|
try {
|
|
29
21
|
// speed optimized
|
|
30
22
|
let ipVersion = net_1.default.isIPv4(ip) ? 'ipv4' : 'ipv6';
|
|
31
|
-
for (let cidr of private_network_cidrs) {
|
|
23
|
+
for (let cidr of exports.private_network_cidrs) {
|
|
32
24
|
if (!cidr)
|
|
33
25
|
continue;
|
|
34
26
|
let first = cidr.first();
|
|
@@ -44,4 +36,12 @@ function isLANIp(ip) {
|
|
|
44
36
|
return false;
|
|
45
37
|
}
|
|
46
38
|
exports.isLANIp = isLANIp;
|
|
39
|
+
function normalizeIp(ip) {
|
|
40
|
+
// also support ipv6
|
|
41
|
+
if (net_1.default.isIP(ip) === 0)
|
|
42
|
+
return '';
|
|
43
|
+
if (net_1.default.isIPv6(ip))
|
|
44
|
+
return ip.toLowerCase().replace(/^::ffff:/, '');
|
|
45
|
+
return ip;
|
|
46
|
+
}
|
|
47
47
|
//# sourceMappingURL=isLANIp.js.map
|
package/ts/funcs/isLANIp.ts
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
import ip6addr from 'ip6addr'
|
|
2
2
|
import net from 'net'
|
|
3
3
|
|
|
4
|
-
const private_network_cidrs = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function normalizeIp(ip:string):string {
|
|
13
|
-
// also support ipv6
|
|
14
|
-
if (net.isIP(ip) === 0) return ''
|
|
15
|
-
if (net.isIPv6(ip)) return ip.toLowerCase().replace(/^::ffff:/, '')
|
|
16
|
-
return ip
|
|
17
|
-
}
|
|
18
|
-
|
|
4
|
+
export const private_network_cidrs = [
|
|
5
|
+
ip6addr.createCIDR('10.0.0.0/8'),
|
|
6
|
+
ip6addr.createCIDR('172.16.0.0/12'),
|
|
7
|
+
ip6addr.createCIDR('192.168.0.0/16'),
|
|
8
|
+
ip6addr.createCIDR('fd00::/8'), // Reserved by IETF for future use, but not currently in active use.
|
|
9
|
+
ip6addr.createCIDR('fc00::/8'), // The range currently in use for local communications within a site or organization.
|
|
10
|
+
]
|
|
19
11
|
|
|
20
12
|
export function isLANIp(ip:string) : boolean {
|
|
21
13
|
ip=normalizeIp(ip)
|
|
22
|
-
if (net.isIP(ip)
|
|
14
|
+
if (net.isIP(ip)===0) return false
|
|
23
15
|
try {
|
|
24
16
|
// speed optimized
|
|
25
17
|
let ipVersion = net.isIPv4(ip) ? 'ipv4' : 'ipv6'
|
|
@@ -36,3 +28,10 @@ export function isLANIp(ip:string) : boolean {
|
|
|
36
28
|
}
|
|
37
29
|
return false
|
|
38
30
|
}
|
|
31
|
+
|
|
32
|
+
function normalizeIp(ip:string):string {
|
|
33
|
+
// also support ipv6
|
|
34
|
+
if (net.isIP(ip) === 0) return ''
|
|
35
|
+
if (net.isIPv6(ip)) return ip.toLowerCase().replace(/^::ffff:/, '')
|
|
36
|
+
return ip
|
|
37
|
+
}
|
package/ts/funcs/isLoopbackIP.js
CHANGED
|
@@ -3,19 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isLoopbackIP = void 0;
|
|
6
|
+
exports.isLoopbackIP = exports.local_network_cidrs = void 0;
|
|
7
7
|
const ip6addr_1 = __importDefault(require("ip6addr"));
|
|
8
8
|
const net_1 = __importDefault(require("net"));
|
|
9
|
-
|
|
10
|
-
ip6addr_1.default.createCIDR('
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (net_1.default.isIP(ip) === 0)
|
|
14
|
-
return '';
|
|
15
|
-
if (net_1.default.isIPv6(ip))
|
|
16
|
-
return ip.toLowerCase().replace(/^::ffff:/, '');
|
|
17
|
-
return ip;
|
|
18
|
-
}
|
|
9
|
+
exports.local_network_cidrs = [
|
|
10
|
+
ip6addr_1.default.createCIDR('127.0.0.0/8'),
|
|
11
|
+
ip6addr_1.default.createCIDR('::1/128')
|
|
12
|
+
];
|
|
19
13
|
function isLoopbackIP(ip) {
|
|
20
14
|
ip = normalizeIp(ip);
|
|
21
15
|
if (net_1.default.isIP(ip) === 0)
|
|
@@ -23,7 +17,7 @@ function isLoopbackIP(ip) {
|
|
|
23
17
|
try {
|
|
24
18
|
// speed optimized
|
|
25
19
|
let ipVersion = net_1.default.isIPv4(ip) ? 'ipv4' : 'ipv6';
|
|
26
|
-
for (let cidr of local_network_cidrs) {
|
|
20
|
+
for (let cidr of exports.local_network_cidrs) {
|
|
27
21
|
let first = cidr.first();
|
|
28
22
|
if (first.kind() !== ipVersion)
|
|
29
23
|
continue;
|
|
@@ -37,4 +31,12 @@ function isLoopbackIP(ip) {
|
|
|
37
31
|
return false;
|
|
38
32
|
}
|
|
39
33
|
exports.isLoopbackIP = isLoopbackIP;
|
|
34
|
+
function normalizeIp(ip) {
|
|
35
|
+
// also support ipv6
|
|
36
|
+
if (net_1.default.isIP(ip) === 0)
|
|
37
|
+
return '';
|
|
38
|
+
if (net_1.default.isIPv6(ip))
|
|
39
|
+
return ip.toLowerCase().replace(/^::ffff:/, '');
|
|
40
|
+
return ip;
|
|
41
|
+
}
|
|
40
42
|
//# sourceMappingURL=isLoopbackIP.js.map
|
package/ts/funcs/isLoopbackIP.ts
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import ip6addr from 'ip6addr'
|
|
2
2
|
import net from 'net'
|
|
3
3
|
|
|
4
|
-
const local_network_cidrs = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function normalizeIp(ip:string):string {
|
|
9
|
-
// also support ipv6
|
|
10
|
-
if (net.isIP(ip) === 0) return ''
|
|
11
|
-
if (net.isIPv6(ip)) return ip.toLowerCase().replace(/^::ffff:/, '')
|
|
12
|
-
return ip
|
|
13
|
-
}
|
|
14
|
-
|
|
4
|
+
export const local_network_cidrs = [
|
|
5
|
+
ip6addr.createCIDR('127.0.0.0/8'),
|
|
6
|
+
ip6addr.createCIDR('::1/128')
|
|
7
|
+
]
|
|
15
8
|
|
|
16
9
|
export function isLoopbackIP(ip:string) : boolean {
|
|
17
10
|
ip=normalizeIp(ip)
|
|
18
|
-
if (net.isIP(ip)
|
|
11
|
+
if (net.isIP(ip)===0) return false
|
|
19
12
|
try {
|
|
20
13
|
// speed optimized
|
|
21
14
|
let ipVersion = net.isIPv4(ip) ? 'ipv4' : 'ipv6'
|
|
@@ -30,3 +23,10 @@ export function isLoopbackIP(ip:string) : boolean {
|
|
|
30
23
|
}
|
|
31
24
|
return false
|
|
32
25
|
}
|
|
26
|
+
|
|
27
|
+
function normalizeIp(ip:string):string {
|
|
28
|
+
// also support ipv6
|
|
29
|
+
if (net.isIP(ip) === 0) return ''
|
|
30
|
+
if (net.isIPv6(ip)) return ip.toLowerCase().replace(/^::ffff:/, '')
|
|
31
|
+
return ip
|
|
32
|
+
}
|
package/ts/index.test.ts
CHANGED
package/ts/models/IPAddress.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
-
};
|
|
7
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
4
|
};
|
|
10
|
-
var _IPAddress_instances, _IPAddress_padIp6, _IPAddress_padIp4;
|
|
11
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
6
|
exports.IPAddress = void 0;
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
13
8
|
const __1 = require("./../");
|
|
14
9
|
const ip6addr_1 = __importDefault(require("ip6addr"));
|
|
10
|
+
const net_1 = __importDefault(require("net"));
|
|
15
11
|
const ip6 = require('ip6'); // "url": "https://github.com/elgs/ip6"
|
|
12
|
+
const dbg = (0, debug_1.default)('_IPAddress');
|
|
13
|
+
dbg.enabled = true;
|
|
16
14
|
// need version "ip6": "0.2.7",!!
|
|
17
15
|
class IPAddress {
|
|
18
16
|
constructor(ip) {
|
|
19
|
-
_IPAddress_instances.add(this);
|
|
20
17
|
if (ip === '-')
|
|
21
18
|
ip = '0.0.0.0';
|
|
22
19
|
try {
|
|
@@ -58,10 +55,33 @@ class IPAddress {
|
|
|
58
55
|
return new IPAddress('0.0.0.0');
|
|
59
56
|
}
|
|
60
57
|
isLoopbackIP() {
|
|
61
|
-
return
|
|
58
|
+
return this.partOfCIDR(IPAddress.loopback_cidrs);
|
|
62
59
|
}
|
|
63
60
|
isLANIP() {
|
|
64
|
-
return
|
|
61
|
+
return this.partOfCIDR(IPAddress.lan_cidrs);
|
|
62
|
+
}
|
|
63
|
+
isLocalIP() {
|
|
64
|
+
return this.partOfCIDR(IPAddress.local_cidrs);
|
|
65
|
+
}
|
|
66
|
+
partOfCIDR(cidr_networks) {
|
|
67
|
+
const ipNormalized = this.toString();
|
|
68
|
+
let ipVersion = net_1.default.isIPv4(ipNormalized) ? 'ipv4' : 'ipv6';
|
|
69
|
+
for (let cidr of cidr_networks) {
|
|
70
|
+
if (!cidr)
|
|
71
|
+
continue;
|
|
72
|
+
let first = cidr.first();
|
|
73
|
+
if (first.kind() !== ipVersion)
|
|
74
|
+
continue;
|
|
75
|
+
if (cidr.contains(ipNormalized))
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
static partOfCIDR(_ip, cidr_networks) {
|
|
81
|
+
const ip = IPAddress.try(_ip);
|
|
82
|
+
if (ip === undefined)
|
|
83
|
+
return false;
|
|
84
|
+
return ip.partOfCIDR(cidr_networks);
|
|
65
85
|
}
|
|
66
86
|
isPublicIP() {
|
|
67
87
|
return this.toString() !== '0.0.0.0' && !this.isLoopbackIP() && !this.isLANIP();
|
|
@@ -89,6 +109,50 @@ class IPAddress {
|
|
|
89
109
|
static randomIP6() {
|
|
90
110
|
return new IPAddress((0, __1.randomIP6)());
|
|
91
111
|
}
|
|
112
|
+
static randomCIDRIp(cidr) {
|
|
113
|
+
if (cidr === 'loopback')
|
|
114
|
+
cidr = IPAddress.loopback_cidrs;
|
|
115
|
+
if (cidr === 'loopback4')
|
|
116
|
+
cidr = IPAddress.loopback_cidrs4;
|
|
117
|
+
if (cidr === 'loopback6')
|
|
118
|
+
cidr = IPAddress.loopback_cidrs6;
|
|
119
|
+
if (cidr === 'lan')
|
|
120
|
+
cidr = IPAddress.lan_cidrs;
|
|
121
|
+
if (cidr === 'lan4')
|
|
122
|
+
cidr = IPAddress.lan_cidrs4;
|
|
123
|
+
if (cidr === 'lan6')
|
|
124
|
+
cidr = IPAddress.lan_cidrs6;
|
|
125
|
+
if (cidr === 'local')
|
|
126
|
+
cidr = IPAddress.local_cidrs;
|
|
127
|
+
if (cidr === 'local4')
|
|
128
|
+
cidr = IPAddress.local_cidrs4;
|
|
129
|
+
if (cidr === 'local6')
|
|
130
|
+
cidr = IPAddress.local_cidrs6;
|
|
131
|
+
// dbg('randomCIDRIp', cidr)
|
|
132
|
+
if (cidr.length === 0)
|
|
133
|
+
throw new Error('CIDR array is empty');
|
|
134
|
+
// Pick a random CIDR network
|
|
135
|
+
const network = cidr[Math.floor(Math.random() * cidr.length)];
|
|
136
|
+
// dbg('randomCIDRIp:network', network)
|
|
137
|
+
// Get the range of IPs in this CIDR
|
|
138
|
+
const start = network.first().toBigInt();
|
|
139
|
+
// dbg('randomCIDRIp:first', network.first().toString(),start)
|
|
140
|
+
const end = network.last().toBigInt();
|
|
141
|
+
// dbg('randomCIDRIp:last', network.last().toString(),end)
|
|
142
|
+
let range = end - start;
|
|
143
|
+
// dbg('randomCIDRIp:first:last', start, end)
|
|
144
|
+
// Generate a random Long between the start and end
|
|
145
|
+
// if start-end > Maximum integer number
|
|
146
|
+
// we need to use BigInt
|
|
147
|
+
if (range > BigInt(Number.MAX_SAFE_INTEGER))
|
|
148
|
+
range = (Number.MAX_SAFE_INTEGER);
|
|
149
|
+
const randomBigInt = BigInt(Math.floor(Math.random() * (Number(range) + 1))) + start;
|
|
150
|
+
// dbg('randomBigInt', randomBigInt)
|
|
151
|
+
// Convert the BigInt back to an IP address
|
|
152
|
+
const randomIp = ip6addr_1.default.parse(randomBigInt);
|
|
153
|
+
// dbg('randomCIDRIp', randomIp.toString())
|
|
154
|
+
return new IPAddress(randomIp.toString());
|
|
155
|
+
}
|
|
92
156
|
serialize() {
|
|
93
157
|
if (this.kind() === 4) {
|
|
94
158
|
// zero pad ipv4
|
|
@@ -109,8 +173,8 @@ class IPAddress {
|
|
|
109
173
|
}
|
|
110
174
|
randomPad() {
|
|
111
175
|
if (this.kind() === 4)
|
|
112
|
-
return
|
|
113
|
-
return
|
|
176
|
+
return this.padIp4();
|
|
177
|
+
return this.padIp6();
|
|
114
178
|
}
|
|
115
179
|
normalized() {
|
|
116
180
|
if (this.kind() === 4)
|
|
@@ -122,6 +186,24 @@ class IPAddress {
|
|
|
122
186
|
return this._ip.toString();
|
|
123
187
|
return ip6.abbreviate(this._ip.toString());
|
|
124
188
|
}
|
|
189
|
+
padIp6() {
|
|
190
|
+
const hextets = this.normalized().split(':'); // we need to have the full form
|
|
191
|
+
const paddedHextets = hextets.map(hextet => {
|
|
192
|
+
const cleanHextet = Number(`0x${hextet}`).toString(16);
|
|
193
|
+
const padLength = Math.floor(Math.random() * (4 - cleanHextet.length));
|
|
194
|
+
return cleanHextet.padStart(padLength + cleanHextet.length, '0');
|
|
195
|
+
});
|
|
196
|
+
return paddedHextets.join(':');
|
|
197
|
+
}
|
|
198
|
+
padIp4() {
|
|
199
|
+
const octets = this._ip.toString().split('.');
|
|
200
|
+
const paddedOctets = octets.map(octet => {
|
|
201
|
+
const cleanOctet = String(Number(octet));
|
|
202
|
+
const padLength = Math.floor(Math.random() * (3 - cleanOctet.length));
|
|
203
|
+
return cleanOctet.padStart(padLength + cleanOctet.length, '0');
|
|
204
|
+
});
|
|
205
|
+
return paddedOctets.join('.');
|
|
206
|
+
}
|
|
125
207
|
asciiChecksum() {
|
|
126
208
|
// support ipv4 and ipv6
|
|
127
209
|
// FNV-1a hash parameters
|
|
@@ -147,21 +229,24 @@ class IPAddress {
|
|
|
147
229
|
}
|
|
148
230
|
}
|
|
149
231
|
exports.IPAddress = IPAddress;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
232
|
+
IPAddress.loopback_cidrs4 = [
|
|
233
|
+
ip6addr_1.default.createCIDR('127.0.0.0/8'),
|
|
234
|
+
];
|
|
235
|
+
IPAddress.loopback_cidrs6 = [
|
|
236
|
+
ip6addr_1.default.createCIDR('::1/128') // yes ipv6 has single address
|
|
237
|
+
];
|
|
238
|
+
IPAddress.loopback_cidrs = IPAddress.loopback_cidrs4.concat(IPAddress.loopback_cidrs6);
|
|
239
|
+
IPAddress.lan_cidrs4 = [
|
|
240
|
+
ip6addr_1.default.createCIDR('10.0.0.0/8'),
|
|
241
|
+
ip6addr_1.default.createCIDR('172.16.0.0/12'),
|
|
242
|
+
ip6addr_1.default.createCIDR('192.168.0.0/16'),
|
|
243
|
+
];
|
|
244
|
+
IPAddress.lan_cidrs6 = [
|
|
245
|
+
ip6addr_1.default.createCIDR('fd00::/8'), // Reserved by IETF for future use, but not currently in active use.
|
|
246
|
+
ip6addr_1.default.createCIDR('fc00::/8'), // The range currently in use for local communications within a site or organization.
|
|
247
|
+
];
|
|
248
|
+
IPAddress.lan_cidrs = IPAddress.lan_cidrs4.concat(IPAddress.lan_cidrs6);
|
|
249
|
+
IPAddress.local_cidrs = IPAddress.loopback_cidrs.concat(IPAddress.lan_cidrs);
|
|
250
|
+
IPAddress.local_cidrs4 = IPAddress.loopback_cidrs4.concat(IPAddress.lan_cidrs4);
|
|
251
|
+
IPAddress.local_cidrs6 = IPAddress.loopback_cidrs6.concat(IPAddress.lan_cidrs6);
|
|
167
252
|
//# sourceMappingURL=IPAddress.js.map
|
|
@@ -63,22 +63,22 @@ describe('IPAddress', () => {
|
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
it('randomly generated ipv4 serialization', () => {
|
|
66
|
-
for(let i = 0; i < 100; i++) {
|
|
66
|
+
for (let i = 0; i < 100; i++) {
|
|
67
67
|
const ip = randomIP()
|
|
68
68
|
expect(IPAddress.unserialize(IPAddress.fromString(ip).serialize()).toString()).toBe(ip)
|
|
69
69
|
}
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
it('randomly generated ipv6 serialization and unserialization', () => {
|
|
73
|
-
for(let i = 0; i < 100; i++) {
|
|
73
|
+
for (let i = 0; i < 100; i++) {
|
|
74
74
|
const ip = randomIP6()
|
|
75
75
|
let ip2 = IPAddress.unserialize(IPAddress.fromString(ip).serialize()).toString()
|
|
76
|
-
expect(ip6addr.compare(ip, ip2)).toEqual(0)
|
|
76
|
+
expect(ip6addr.compare(ip, ip2)).toEqual(0)
|
|
77
77
|
}
|
|
78
78
|
})
|
|
79
79
|
|
|
80
80
|
it('it should detect the kind of ip4', () => {
|
|
81
|
-
for(let i = 0; i < 100; i++)
|
|
81
|
+
for (let i = 0; i < 100; i++)
|
|
82
82
|
expect(IPAddress.randomIP4().kind()).toBe(4)
|
|
83
83
|
})
|
|
84
84
|
|
|
@@ -88,10 +88,10 @@ describe('IPAddress', () => {
|
|
|
88
88
|
|
|
89
89
|
it('randomPad return valid ipv4 results', () => {
|
|
90
90
|
let compared = 0
|
|
91
|
-
while(compared<100) {
|
|
91
|
+
while (compared < 100) {
|
|
92
92
|
const ip1 = IPAddress.randomIP4()
|
|
93
93
|
const ip2 = ip1.randomPad()
|
|
94
|
-
if (ip1.toString()!==ip2) { // find ips they are padded from the original
|
|
94
|
+
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
95
95
|
compared++
|
|
96
96
|
}
|
|
97
97
|
expect(IPAddress.validate(ip2)).toBe(true)
|
|
@@ -100,10 +100,10 @@ describe('IPAddress', () => {
|
|
|
100
100
|
|
|
101
101
|
it('compare ipv4 should detect equality even if they are padded', () => {
|
|
102
102
|
let compared = 0
|
|
103
|
-
while(compared<100) {
|
|
103
|
+
while (compared < 100) {
|
|
104
104
|
const ip1 = IPAddress.randomIP4()
|
|
105
105
|
const ip2 = ip1.randomPad()
|
|
106
|
-
if (ip1.toString()!==ip2) { // find ips they are padded from the original
|
|
106
|
+
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
107
107
|
compared++
|
|
108
108
|
}
|
|
109
109
|
expect(ip1.equals(IPAddress.fromString(ip2))).toBe(true)
|
|
@@ -137,20 +137,20 @@ describe('IPAddress IPv6', () => {
|
|
|
137
137
|
|
|
138
138
|
it('it should detect the kind of ip6', () => {
|
|
139
139
|
expect(new IPAddress('2605:2700:0000:0003:a800:00ff:fe10:f0d3').kind()).toBe(6);
|
|
140
|
-
for(let i = 0; i < 100; i++)
|
|
140
|
+
for (let i = 0; i < 100; i++)
|
|
141
141
|
expect(IPAddress.randomIP6().kind()).toBe(6)
|
|
142
142
|
})
|
|
143
143
|
|
|
144
144
|
it('randomPad return valid ipv6 results be compareable with equals', () => {
|
|
145
145
|
let compared = 0
|
|
146
|
-
while(compared<500) {
|
|
146
|
+
while (compared < 500) {
|
|
147
147
|
const ip1 = IPAddress.randomIP6()
|
|
148
148
|
const ip2 = ip1.randomPad()
|
|
149
149
|
expect(ip1.kind()).toBe(6)
|
|
150
|
-
if (ip1.toString()!==ip2) { // find ips they are padded from the original
|
|
150
|
+
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
151
151
|
compared++
|
|
152
152
|
}
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
expect(IPAddress.validate(ip2)).toBe(true)
|
|
155
155
|
expect(ip1.equals(IPAddress.fromString(ip2))).toBe(true)
|
|
156
156
|
}
|
|
@@ -173,16 +173,135 @@ describe('IPAddress asciiChecksum', () => {
|
|
|
173
173
|
})
|
|
174
174
|
|
|
175
175
|
it('it should always return a single character ipv4/v6', () => {
|
|
176
|
-
for(let i=0;i<10000;i++) {
|
|
176
|
+
for (let i = 0; i < 10000; i++) {
|
|
177
177
|
expect(new IPAddress(randomIP()).asciiChecksum().length).toBe(1)
|
|
178
178
|
expect(new IPAddress(randomIP6()).asciiChecksum().length).toBe(1)
|
|
179
179
|
}
|
|
180
180
|
})
|
|
181
181
|
|
|
182
|
-
it('it should return a-z0-9 ascii only',()=>{
|
|
183
|
-
for(let i=0;i<10000;i++) {
|
|
182
|
+
it('it should return a-z0-9 ascii only', () => {
|
|
183
|
+
for (let i = 0; i < 10000; i++) {
|
|
184
184
|
expect('abcdefghijklmnopqrstuvwxyz0123456789').toContain(new IPAddress(randomIP()).asciiChecksum())
|
|
185
185
|
expect('abcdefghijklmnopqrstuvwxyz0123456789').toContain(new IPAddress(randomIP6()).asciiChecksum())
|
|
186
186
|
}
|
|
187
187
|
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
describe('IPAddress partOfCIDR', () => {
|
|
191
|
+
it('should detect cidrs in ipv4', () => {
|
|
192
|
+
expect(IPAddress.partOfCIDR('127.0.0.1', [ip6addr.createCIDR('127.0.0.0/8')])).toBe(true)
|
|
193
|
+
expect(IPAddress.partOfCIDR('127.0.0.1', [ip6addr.createCIDR('128.0.0.0/8')])).toBe(false)
|
|
194
|
+
expect(IPAddress.partOfCIDR('127.0.0.1', [ip6addr.createCIDR('126.0.0.0/8')])).toBe(false)
|
|
195
|
+
})
|
|
196
|
+
it('should detect cidrs in ipv6', () => {
|
|
197
|
+
expect(IPAddress.partOfCIDR('::1', [ip6addr.createCIDR('::/8')])).toBe(true)
|
|
198
|
+
expect(IPAddress.partOfCIDR('::1', [ip6addr.createCIDR('2ff0::1:0/8')])).toBe(false)
|
|
199
|
+
expect(IPAddress.partOfCIDR('::1', [ip6addr.createCIDR('3ff0::2:0/8')])).toBe(false)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('should also work non-static', () => {
|
|
203
|
+
expect(new IPAddress('::1').partOfCIDR([ip6addr.createCIDR('::/8')])).toBe(true)
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
describe('IPAddress randomCIDRIp', () => {
|
|
208
|
+
const testCount = 25000
|
|
209
|
+
|
|
210
|
+
it('"loopback" should return random loopback ip4/6', () => {
|
|
211
|
+
const stats:any={
|
|
212
|
+
'4':0,
|
|
213
|
+
'6':0
|
|
214
|
+
}
|
|
215
|
+
for(var i=0;i<testCount;i++) {
|
|
216
|
+
const rip = IPAddress.randomCIDRIp('loopback')
|
|
217
|
+
stats[rip.kind().toString()]++
|
|
218
|
+
expect(rip.isLoopbackIP()).toBe(true)
|
|
219
|
+
}
|
|
220
|
+
// we need to have at least 30% of ipv4 and ipv6
|
|
221
|
+
expect(stats['4']).toBeGreaterThan(testCount*0.3)
|
|
222
|
+
expect(stats['6']).toBeGreaterThan(testCount*0.3)
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('"loopback4" should return random loopback ip4', () => {
|
|
226
|
+
for(var i=0;i<testCount;i++) {
|
|
227
|
+
const rip = IPAddress.randomCIDRIp('loopback4')
|
|
228
|
+
expect(rip.kind()).toBe(4)
|
|
229
|
+
expect(rip.isLoopbackIP()).toBe(true)
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
it('"loopback6" should return random loopback ip6', () => {
|
|
235
|
+
for(var i=0;i<testCount;i++) {
|
|
236
|
+
const rip = IPAddress.randomCIDRIp('loopback6')
|
|
237
|
+
expect(rip.kind()).toBe(6)
|
|
238
|
+
expect(rip.isLoopbackIP()).toBe(true)
|
|
239
|
+
// ipv6 has single loopback address
|
|
240
|
+
expect(rip.toString()).toBe('::1')
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('"lan" should return random LAN ip4/6', () => {
|
|
245
|
+
const stats:any={
|
|
246
|
+
'4':0,
|
|
247
|
+
'6':0
|
|
248
|
+
}
|
|
249
|
+
for(var i=0;i<testCount;i++) {
|
|
250
|
+
const rip = IPAddress.randomCIDRIp('lan')
|
|
251
|
+
stats[rip.kind().toString()]++
|
|
252
|
+
// if (!rip.isLANIP()) console.log(rip.toString(),`must be lan but it is not`)
|
|
253
|
+
expect(rip.isLANIP()).toBe(true)
|
|
254
|
+
}
|
|
255
|
+
// we need to have at least 30% of ipv4 and ipv6
|
|
256
|
+
expect(stats['4']).toBeGreaterThan(testCount*0.3)
|
|
257
|
+
expect(stats['6']).toBeGreaterThan(testCount*0.3)
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
it('"lan6" should return random lan ip6', () => {
|
|
262
|
+
for(var i=0;i<testCount;i++) {
|
|
263
|
+
const rip = IPAddress.randomCIDRIp('lan6')
|
|
264
|
+
expect(rip.kind()).toBe(6)
|
|
265
|
+
expect(rip.isLANIP()).toBe(true)
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it('"lan4" should return random lan ip4', () => {
|
|
270
|
+
for(var i=0;i<testCount;i++) {
|
|
271
|
+
const rip = IPAddress.randomCIDRIp('lan4')
|
|
272
|
+
expect(rip.kind()).toBe(4)
|
|
273
|
+
expect(rip.isLANIP()).toBe(true)
|
|
274
|
+
}
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
it('"local" should return random local ip4/6', () => {
|
|
278
|
+
const stats:any={
|
|
279
|
+
'4':0,
|
|
280
|
+
'6':0
|
|
281
|
+
}
|
|
282
|
+
for(var i=0;i<testCount;i++) {
|
|
283
|
+
const rip = IPAddress.randomCIDRIp('local')
|
|
284
|
+
stats[rip.kind().toString()]++
|
|
285
|
+
expect(rip.isLocalIP()).toBe(true)
|
|
286
|
+
}
|
|
287
|
+
// we need to have at least 30% of ipv4 and ipv6
|
|
288
|
+
expect(stats['4']).toBeGreaterThan(testCount*0.3)
|
|
289
|
+
expect(stats['6']).toBeGreaterThan(testCount*0.3)
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
it('"local4" should return random local ip4', () => {
|
|
293
|
+
for(var i=0;i<testCount;i++) {
|
|
294
|
+
const rip = IPAddress.randomCIDRIp('local4')
|
|
295
|
+
expect(rip.kind()).toBe(4)
|
|
296
|
+
expect(rip.isLocalIP()).toBe(true)
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('"local6" should return random local ip6', () => {
|
|
301
|
+
for(var i=0;i<testCount;i++) {
|
|
302
|
+
const rip = IPAddress.randomCIDRIp('local6')
|
|
303
|
+
expect(rip.kind()).toBe(6)
|
|
304
|
+
expect(rip.isLocalIP()).toBe(true)
|
|
305
|
+
}
|
|
306
|
+
})
|
|
188
307
|
})
|
package/ts/models/IPAddress.ts
CHANGED
|
@@ -1,11 +1,43 @@
|
|
|
1
|
-
import
|
|
1
|
+
import debug from 'debug'
|
|
2
|
+
import { randomIP, randomIP6, } from "./../"
|
|
2
3
|
import ip6addr, { Addr, ToStringOpts } from 'ip6addr'
|
|
4
|
+
import net from 'net'
|
|
3
5
|
const ip6 = require('ip6') // "url": "https://github.com/elgs/ip6"
|
|
6
|
+
const dbg = debug('_IPAddress')
|
|
7
|
+
dbg.enabled = true
|
|
4
8
|
// need version "ip6": "0.2.7",!!
|
|
5
9
|
|
|
6
10
|
export class IPAddress {
|
|
7
11
|
private _ip: Addr
|
|
8
12
|
|
|
13
|
+
public static loopback_cidrs4 = [
|
|
14
|
+
ip6addr.createCIDR('127.0.0.0/8'),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
public static loopback_cidrs6 = [
|
|
18
|
+
ip6addr.createCIDR('::1/128') // yes ipv6 has single address
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
public static loopback_cidrs = IPAddress.loopback_cidrs4.concat(IPAddress.loopback_cidrs6)
|
|
22
|
+
|
|
23
|
+
public static lan_cidrs4 = [
|
|
24
|
+
ip6addr.createCIDR('10.0.0.0/8'),
|
|
25
|
+
ip6addr.createCIDR('172.16.0.0/12'),
|
|
26
|
+
ip6addr.createCIDR('192.168.0.0/16'),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
public static lan_cidrs6 = [
|
|
30
|
+
ip6addr.createCIDR('fd00::/8'), // Reserved by IETF for future use, but not currently in active use.
|
|
31
|
+
ip6addr.createCIDR('fc00::/8'), // The range currently in use for local communications within a site or organization.
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
public static lan_cidrs = IPAddress.lan_cidrs4.concat(IPAddress.lan_cidrs6)
|
|
35
|
+
|
|
36
|
+
public static local_cidrs = IPAddress.loopback_cidrs.concat(IPAddress.lan_cidrs)
|
|
37
|
+
public static local_cidrs4 = IPAddress.loopback_cidrs4.concat(IPAddress.lan_cidrs4)
|
|
38
|
+
public static local_cidrs6 = IPAddress.loopback_cidrs6.concat(IPAddress.lan_cidrs6)
|
|
39
|
+
|
|
40
|
+
|
|
9
41
|
constructor(ip: string) { // may throw
|
|
10
42
|
if (ip === '-') ip = '0.0.0.0'
|
|
11
43
|
|
|
@@ -51,11 +83,34 @@ export class IPAddress {
|
|
|
51
83
|
}
|
|
52
84
|
|
|
53
85
|
public isLoopbackIP(): boolean {
|
|
54
|
-
return
|
|
86
|
+
return this.partOfCIDR(IPAddress.loopback_cidrs)
|
|
55
87
|
}
|
|
56
88
|
|
|
57
89
|
public isLANIP(): boolean {
|
|
58
|
-
return
|
|
90
|
+
return this.partOfCIDR(IPAddress.lan_cidrs)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public isLocalIP(): boolean {
|
|
94
|
+
return this.partOfCIDR(IPAddress.local_cidrs)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
partOfCIDR(cidr_networks: ip6addr.CIDR[]): boolean {
|
|
98
|
+
const ipNormalized = this.toString()
|
|
99
|
+
let ipVersion = net.isIPv4(ipNormalized) ? 'ipv4' : 'ipv6'
|
|
100
|
+
for (let cidr of cidr_networks) {
|
|
101
|
+
if (!cidr) continue
|
|
102
|
+
let first = cidr.first()
|
|
103
|
+
if (first.kind() !== ipVersion) continue
|
|
104
|
+
if (cidr.contains(ipNormalized))
|
|
105
|
+
return true
|
|
106
|
+
}
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static partOfCIDR(_ip: string, cidr_networks: ip6addr.CIDR[]): boolean {
|
|
111
|
+
const ip = IPAddress.try(_ip)
|
|
112
|
+
if (ip === undefined) return false
|
|
113
|
+
return ip.partOfCIDR(cidr_networks)
|
|
59
114
|
}
|
|
60
115
|
|
|
61
116
|
public isPublicIP(): boolean {
|
|
@@ -86,6 +141,46 @@ export class IPAddress {
|
|
|
86
141
|
return new IPAddress(randomIP6())
|
|
87
142
|
}
|
|
88
143
|
|
|
144
|
+
|
|
145
|
+
public static randomCIDRIp(cidr: ip6addr.CIDR[] | 'loopback' | 'lan' | 'local' | 'loopback4' | 'loopback6' | 'lan4' | 'lan6' | 'local4' | 'local6'): IPAddress {
|
|
146
|
+
if (cidr === 'loopback') cidr = IPAddress.loopback_cidrs
|
|
147
|
+
if (cidr === 'loopback4') cidr = IPAddress.loopback_cidrs4
|
|
148
|
+
if (cidr === 'loopback6') cidr = IPAddress.loopback_cidrs6
|
|
149
|
+
if (cidr === 'lan') cidr = IPAddress.lan_cidrs
|
|
150
|
+
if (cidr === 'lan4') cidr = IPAddress.lan_cidrs4
|
|
151
|
+
if (cidr === 'lan6') cidr = IPAddress.lan_cidrs6
|
|
152
|
+
if (cidr === 'local') cidr = IPAddress.local_cidrs
|
|
153
|
+
if (cidr === 'local4') cidr = IPAddress.local_cidrs4
|
|
154
|
+
if (cidr === 'local6') cidr = IPAddress.local_cidrs6
|
|
155
|
+
// dbg('randomCIDRIp', cidr)
|
|
156
|
+
if (cidr.length === 0) throw new Error('CIDR array is empty')
|
|
157
|
+
// Pick a random CIDR network
|
|
158
|
+
const network = cidr[Math.floor(Math.random() * cidr.length)];
|
|
159
|
+
// dbg('randomCIDRIp:network', network)
|
|
160
|
+
// Get the range of IPs in this CIDR
|
|
161
|
+
const start = network.first().toBigInt()
|
|
162
|
+
// dbg('randomCIDRIp:first', network.first().toString(),start)
|
|
163
|
+
const end = network.last().toBigInt();
|
|
164
|
+
// dbg('randomCIDRIp:last', network.last().toString(),end)
|
|
165
|
+
let range : any = end-start
|
|
166
|
+
// dbg('randomCIDRIp:first:last', start, end)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
// Generate a random Long between the start and end
|
|
170
|
+
// if start-end > Maximum integer number
|
|
171
|
+
// we need to use BigInt
|
|
172
|
+
if (range > BigInt(Number.MAX_SAFE_INTEGER)) range=(Number.MAX_SAFE_INTEGER)
|
|
173
|
+
|
|
174
|
+
const randomBigInt = BigInt(Math.floor(Math.random() * (Number(range) + 1))) + start;
|
|
175
|
+
// dbg('randomBigInt', randomBigInt)
|
|
176
|
+
|
|
177
|
+
// Convert the BigInt back to an IP address
|
|
178
|
+
const randomIp = ip6addr.parse(randomBigInt)
|
|
179
|
+
// dbg('randomCIDRIp', randomIp.toString())
|
|
180
|
+
|
|
181
|
+
return new IPAddress(randomIp.toString())
|
|
182
|
+
}
|
|
183
|
+
|
|
89
184
|
public serialize(): string {
|
|
90
185
|
if (this.kind() === 4) {
|
|
91
186
|
// zero pad ipv4
|
|
@@ -109,8 +204,8 @@ export class IPAddress {
|
|
|
109
204
|
}
|
|
110
205
|
|
|
111
206
|
public randomPad(): string {
|
|
112
|
-
if (this.kind() === 4) return this
|
|
113
|
-
return this
|
|
207
|
+
if (this.kind() === 4) return this.padIp4()
|
|
208
|
+
return this.padIp6()
|
|
114
209
|
}
|
|
115
210
|
|
|
116
211
|
public normalized(): string {
|
|
@@ -123,7 +218,7 @@ export class IPAddress {
|
|
|
123
218
|
return ip6.abbreviate(this._ip.toString())
|
|
124
219
|
}
|
|
125
220
|
|
|
126
|
-
|
|
221
|
+
private padIp6(): string {
|
|
127
222
|
const hextets = this.normalized().split(':') // we need to have the full form
|
|
128
223
|
const paddedHextets = hextets.map(hextet => {
|
|
129
224
|
const cleanHextet = Number(`0x${hextet}`).toString(16)
|
|
@@ -134,7 +229,7 @@ export class IPAddress {
|
|
|
134
229
|
return paddedHextets.join(':')
|
|
135
230
|
}
|
|
136
231
|
|
|
137
|
-
|
|
232
|
+
private padIp4(): string {
|
|
138
233
|
const octets = this._ip.toString().split('.')
|
|
139
234
|
const paddedOctets = octets.map(octet => {
|
|
140
235
|
const cleanOctet = String(Number(octet))
|
package/tsconfig.json
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
declare module 'ip6addr' {
|
|
2
|
+
export interface ToStringOpts {
|
|
3
|
+
format?: "auto" | "v4" | "v4-mapped" | "v6" | undefined;
|
|
4
|
+
zeroElide?: boolean | undefined;
|
|
5
|
+
zeroPad?: boolean | undefined;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Addr {
|
|
9
|
+
kind: () => "ipv4" | "ipv6";
|
|
10
|
+
toString: (opts?: ToStringOpts) => string;
|
|
11
|
+
toBuffer: (buff?: Uint8Array) => Uint8Array;
|
|
12
|
+
toLong: () => number;
|
|
13
|
+
toBigInt: () => bigint;
|
|
14
|
+
offset: (num: number) => Addr | null;
|
|
15
|
+
compare: (other: string | Addr) => number;
|
|
16
|
+
clone: () => Addr;
|
|
17
|
+
and: (input: string | Addr) => Addr;
|
|
18
|
+
or: (input: string | Addr) => Addr;
|
|
19
|
+
not: () => Addr;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AddrRange {
|
|
23
|
+
contains: (input: string | Addr) => boolean;
|
|
24
|
+
first: () => Addr;
|
|
25
|
+
last: () => Addr;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CIDR extends AddrRange {
|
|
29
|
+
broadcast: () => Addr;
|
|
30
|
+
compare: (other: string | CIDR) => number;
|
|
31
|
+
prefixLength: (format?: "auto" | "v4" | "v6") => number;
|
|
32
|
+
address: () => Addr;
|
|
33
|
+
toString: (opts?: ToStringOpts) => string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function compare(addr1: string | Addr, addr2: string | Addr): number;
|
|
37
|
+
|
|
38
|
+
export function compareCIDR(cidr1: string | CIDR, cidr2: string | CIDR): number;
|
|
39
|
+
|
|
40
|
+
export function createAddrRange(begin: string | Addr, end: string | Addr): AddrRange;
|
|
41
|
+
|
|
42
|
+
export function createCIDR(addr: string | Addr, len?: number): CIDR;
|
|
43
|
+
|
|
44
|
+
export function parse(input: string | number | Addr | BigInt): Addr;
|
|
45
|
+
|
|
46
|
+
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const ip6addr_1 = __importDefault(require("ip6addr"));
|
|
7
|
-
const IPAddress_1 = require("./IPAddress");
|
|
8
|
-
const __1 = require("../");
|
|
9
|
-
describe('IPAddress', () => {
|
|
10
|
-
it('should create an instance of IPAddress', () => {
|
|
11
|
-
const ipAddress = new IPAddress_1.IPAddress('192.168.0.1');
|
|
12
|
-
expect(ipAddress).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
13
|
-
});
|
|
14
|
-
it('should convert IPAddress to string', () => {
|
|
15
|
-
const ipAddress = new IPAddress_1.IPAddress('192.168.0.1');
|
|
16
|
-
const result = ipAddress.toString();
|
|
17
|
-
expect(result).toBe('192.168.0.1');
|
|
18
|
-
});
|
|
19
|
-
it('should create an instance of IPAddress from string', () => {
|
|
20
|
-
const ipAddress = IPAddress_1.IPAddress.fromString('192.168.0.1');
|
|
21
|
-
expect(ipAddress).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
22
|
-
});
|
|
23
|
-
it('should throw an error when creating an instance of IPAddress from invalid string', () => {
|
|
24
|
-
expect(() => IPAddress_1.IPAddress.fromString('192.168.0')).toThrow();
|
|
25
|
-
expect(() => IPAddress_1.IPAddress.fromString('0.0.0')).toThrow();
|
|
26
|
-
expect(() => IPAddress_1.IPAddress.fromString('')).toThrow();
|
|
27
|
-
//@ts-ignore
|
|
28
|
-
expect(() => IPAddress_1.IPAddress.fromString(null)).toThrow();
|
|
29
|
-
//@ts-ignore
|
|
30
|
-
expect(() => IPAddress_1.IPAddress.fromString(undefined)).toThrow();
|
|
31
|
-
});
|
|
32
|
-
it('should serialize ipv4 to string', () => {
|
|
33
|
-
expect(IPAddress_1.IPAddress.fromString('192.168.0.1').serialize()).toBe('192168000001');
|
|
34
|
-
expect(IPAddress_1.IPAddress.fromString('0.0.0.0').serialize()).toBe('000000000000');
|
|
35
|
-
expect(IPAddress_1.IPAddress.fromString('0.0.0.1').serialize()).toBe('000000000001');
|
|
36
|
-
expect(IPAddress_1.IPAddress.fromString('0.00.000.01').serialize()).toBe('000000000001');
|
|
37
|
-
expect(IPAddress_1.IPAddress.fromString('0.10.0.0').serialize()).toBe('000010000000');
|
|
38
|
-
expect(IPAddress_1.IPAddress.fromString('255.255.255.255').serialize()).toBe('255255255255');
|
|
39
|
-
});
|
|
40
|
-
it('should serialize ipv6 to string', () => {
|
|
41
|
-
expect(IPAddress_1.IPAddress.fromString('::').serialize()).toBe('00000000000000000000000000000000');
|
|
42
|
-
expect(IPAddress_1.IPAddress.fromString('::1').serialize()).toBe('00000000000000000000000000000001');
|
|
43
|
-
expect(IPAddress_1.IPAddress.fromString('::01').serialize()).toBe('00000000000000000000000000000001');
|
|
44
|
-
expect(IPAddress_1.IPAddress.fromString('::001').serialize()).toBe('00000000000000000000000000000001');
|
|
45
|
-
expect(IPAddress_1.IPAddress.fromString('::0001').serialize()).toBe('00000000000000000000000000000001');
|
|
46
|
-
expect(IPAddress_1.IPAddress.fromString('::1:1').serialize()).toBe('00000000000000000000000000010001');
|
|
47
|
-
expect(IPAddress_1.IPAddress.fromString('::2:1').serialize()).toBe('00000000000000000000000000020001');
|
|
48
|
-
});
|
|
49
|
-
// testing unserialize
|
|
50
|
-
it('should unserialize ipv4 from string', () => {
|
|
51
|
-
expect(IPAddress_1.IPAddress.unserialize('192168000001').toString()).toBe('192.168.0.1');
|
|
52
|
-
expect(IPAddress_1.IPAddress.unserialize('192168000002').toString()).toBe('192.168.0.2');
|
|
53
|
-
expect(IPAddress_1.IPAddress.unserialize('000000000000').toString()).toBe('0.0.0.0');
|
|
54
|
-
});
|
|
55
|
-
it('should throw invalid serialization string', () => {
|
|
56
|
-
expect(() => IPAddress_1.IPAddress.unserialize('92168000001')).toThrow(Error);
|
|
57
|
-
expect(() => IPAddress_1.IPAddress.unserialize('168000001')).toThrow(Error);
|
|
58
|
-
expect(() => IPAddress_1.IPAddress.unserialize('292168000002')).toThrow(Error);
|
|
59
|
-
});
|
|
60
|
-
it('randomly generated ipv4 serialization', () => {
|
|
61
|
-
for (let i = 0; i < 100; i++) {
|
|
62
|
-
const ip = (0, __1.randomIP)();
|
|
63
|
-
expect(IPAddress_1.IPAddress.unserialize(IPAddress_1.IPAddress.fromString(ip).serialize()).toString()).toBe(ip);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
it('randomly generated ipv6 serialization and unserialization', () => {
|
|
67
|
-
for (let i = 0; i < 100; i++) {
|
|
68
|
-
const ip = (0, __1.randomIP6)();
|
|
69
|
-
let ip2 = IPAddress_1.IPAddress.unserialize(IPAddress_1.IPAddress.fromString(ip).serialize()).toString();
|
|
70
|
-
expect(ip6addr_1.default.compare(ip, ip2)).toEqual(0);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
it('it should detect the kind of ip4', () => {
|
|
74
|
-
for (let i = 0; i < 100; i++)
|
|
75
|
-
expect(IPAddress_1.IPAddress.randomIP4().kind()).toBe(4);
|
|
76
|
-
});
|
|
77
|
-
it('should return shortened address by default toString', () => {
|
|
78
|
-
expect(new IPAddress_1.IPAddress('001.02.3.004').toString()).toBe('1.2.3.4');
|
|
79
|
-
});
|
|
80
|
-
it('randomPad return valid ipv4 results', () => {
|
|
81
|
-
let compared = 0;
|
|
82
|
-
while (compared < 100) {
|
|
83
|
-
const ip1 = IPAddress_1.IPAddress.randomIP4();
|
|
84
|
-
const ip2 = ip1.randomPad();
|
|
85
|
-
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
86
|
-
compared++;
|
|
87
|
-
}
|
|
88
|
-
expect(IPAddress_1.IPAddress.validate(ip2)).toBe(true);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
it('compare ipv4 should detect equality even if they are padded', () => {
|
|
92
|
-
let compared = 0;
|
|
93
|
-
while (compared < 100) {
|
|
94
|
-
const ip1 = IPAddress_1.IPAddress.randomIP4();
|
|
95
|
-
const ip2 = ip1.randomPad();
|
|
96
|
-
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
97
|
-
compared++;
|
|
98
|
-
}
|
|
99
|
-
expect(ip1.equals(IPAddress_1.IPAddress.fromString(ip2))).toBe(true);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe('IPAddress IPv6', () => {
|
|
104
|
-
it('should work with any form of valid ipv6, prefixed or not', () => {
|
|
105
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:0003:a800:00ff:fe10:f0d3')).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
106
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:003:a800:00ff:fe10:f0d3')).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
107
|
-
expect(new IPAddress_1.IPAddress('2605:2700:000:003:a800:00ff:fe10:f0d3')).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
108
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0:003:a800:00ff:fe10:f0d3')).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
109
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0:003:a800:0ff:fe10:f0d3')).toBeInstanceOf(IPAddress_1.IPAddress);
|
|
110
|
-
});
|
|
111
|
-
it('should return shortened address by default toString', () => {
|
|
112
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:0003:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
113
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:003:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
114
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:03:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
115
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:03:a800:ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
116
|
-
});
|
|
117
|
-
it('ip6 addresses should be lowercased', () => {
|
|
118
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:0003:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
119
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:003:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
120
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:03:a800:00ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
121
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:03:a800:ff:fe10:f0d3').toString()).toBe('2605:2700::3:a800:ff:fe10:f0d3');
|
|
122
|
-
});
|
|
123
|
-
it('it should detect the kind of ip6', () => {
|
|
124
|
-
expect(new IPAddress_1.IPAddress('2605:2700:0000:0003:a800:00ff:fe10:f0d3').kind()).toBe(6);
|
|
125
|
-
for (let i = 0; i < 100; i++)
|
|
126
|
-
expect(IPAddress_1.IPAddress.randomIP6().kind()).toBe(6);
|
|
127
|
-
});
|
|
128
|
-
it('randomPad return valid ipv6 results be compareable with equals', () => {
|
|
129
|
-
let compared = 0;
|
|
130
|
-
while (compared < 500) {
|
|
131
|
-
const ip1 = IPAddress_1.IPAddress.randomIP6();
|
|
132
|
-
const ip2 = ip1.randomPad();
|
|
133
|
-
expect(ip1.kind()).toBe(6);
|
|
134
|
-
if (ip1.toString() !== ip2) { // find ips they are padded from the original
|
|
135
|
-
compared++;
|
|
136
|
-
}
|
|
137
|
-
expect(IPAddress_1.IPAddress.validate(ip2)).toBe(true);
|
|
138
|
-
expect(ip1.equals(IPAddress_1.IPAddress.fromString(ip2))).toBe(true);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe('IPAddress asciiChecksum', () => {
|
|
143
|
-
it('should return the correct checksum for ipv4', () => {
|
|
144
|
-
expect(new IPAddress_1.IPAddress('1.2.3.4').asciiChecksum()).toBe('e');
|
|
145
|
-
expect(new IPAddress_1.IPAddress('1.2.3.6').asciiChecksum()).toBe('i');
|
|
146
|
-
});
|
|
147
|
-
it('should return the correct checksum for ipv6', () => {
|
|
148
|
-
expect(new IPAddress_1.IPAddress('::').asciiChecksum()).toBe('a');
|
|
149
|
-
expect(new IPAddress_1.IPAddress('::1').asciiChecksum()).toBe('a');
|
|
150
|
-
expect(new IPAddress_1.IPAddress('::f').asciiChecksum()).toBe('s');
|
|
151
|
-
});
|
|
152
|
-
it('it should always return a single character ipv4/v6', () => {
|
|
153
|
-
for (let i = 0; i < 10000; i++) {
|
|
154
|
-
expect(new IPAddress_1.IPAddress((0, __1.randomIP)()).asciiChecksum().length).toBe(1);
|
|
155
|
-
expect(new IPAddress_1.IPAddress((0, __1.randomIP6)()).asciiChecksum().length).toBe(1);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
it('it should return a-z0-9 ascii only', () => {
|
|
159
|
-
for (let i = 0; i < 10000; i++) {
|
|
160
|
-
expect('abcdefghijklmnopqrstuvwxyz0123456789').toContain(new IPAddress_1.IPAddress((0, __1.randomIP)()).asciiChecksum());
|
|
161
|
-
expect('abcdefghijklmnopqrstuvwxyz0123456789').toContain(new IPAddress_1.IPAddress((0, __1.randomIP6)()).asciiChecksum());
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
//# sourceMappingURL=IPAddress.jest.js.map
|