[6a3a178] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | var ip = require('..');
|
---|
| 4 | var assert = require('assert');
|
---|
| 5 | var net = require('net');
|
---|
| 6 | var os = require('os');
|
---|
| 7 |
|
---|
| 8 | describe('IP library for node.js', function() {
|
---|
| 9 | describe('toBuffer()/toString() methods', function() {
|
---|
| 10 | it('should convert to buffer IPv4 address', function() {
|
---|
| 11 | var buf = ip.toBuffer('127.0.0.1');
|
---|
| 12 | assert.equal(buf.toString('hex'), '7f000001');
|
---|
| 13 | assert.equal(ip.toString(buf), '127.0.0.1');
|
---|
| 14 | });
|
---|
| 15 |
|
---|
| 16 | it('should convert to buffer IPv4 address in-place', function() {
|
---|
| 17 | var buf = new Buffer(128);
|
---|
| 18 | var offset = 64;
|
---|
| 19 | ip.toBuffer('127.0.0.1', buf, offset);
|
---|
| 20 | assert.equal(buf.toString('hex', offset, offset + 4), '7f000001');
|
---|
| 21 | assert.equal(ip.toString(buf, offset, 4), '127.0.0.1');
|
---|
| 22 | });
|
---|
| 23 |
|
---|
| 24 | it('should convert to buffer IPv6 address', function() {
|
---|
| 25 | var buf = ip.toBuffer('::1');
|
---|
| 26 | assert(/(00){15,15}01/.test(buf.toString('hex')));
|
---|
| 27 | assert.equal(ip.toString(buf), '::1');
|
---|
| 28 | assert.equal(ip.toString(ip.toBuffer('1::')), '1::');
|
---|
| 29 | assert.equal(ip.toString(ip.toBuffer('abcd::dcba')), 'abcd::dcba');
|
---|
| 30 | });
|
---|
| 31 |
|
---|
| 32 | it('should convert to buffer IPv6 address in-place', function() {
|
---|
| 33 | var buf = new Buffer(128);
|
---|
| 34 | var offset = 64;
|
---|
| 35 | ip.toBuffer('::1', buf, offset);
|
---|
| 36 | assert(/(00){15,15}01/.test(buf.toString('hex', offset, offset + 16)));
|
---|
| 37 | assert.equal(ip.toString(buf, offset, 16), '::1');
|
---|
| 38 | assert.equal(ip.toString(ip.toBuffer('1::', buf, offset),
|
---|
| 39 | offset, 16), '1::');
|
---|
| 40 | assert.equal(ip.toString(ip.toBuffer('abcd::dcba', buf, offset),
|
---|
| 41 | offset, 16), 'abcd::dcba');
|
---|
| 42 | });
|
---|
| 43 |
|
---|
| 44 | it('should convert to buffer IPv6 mapped IPv4 address', function() {
|
---|
| 45 | var buf = ip.toBuffer('::ffff:127.0.0.1');
|
---|
| 46 | assert.equal(buf.toString('hex'), '00000000000000000000ffff7f000001');
|
---|
| 47 | assert.equal(ip.toString(buf), '::ffff:7f00:1');
|
---|
| 48 |
|
---|
| 49 | buf = ip.toBuffer('ffff::127.0.0.1');
|
---|
| 50 | assert.equal(buf.toString('hex'), 'ffff000000000000000000007f000001');
|
---|
| 51 | assert.equal(ip.toString(buf), 'ffff::7f00:1');
|
---|
| 52 |
|
---|
| 53 | buf = ip.toBuffer('0:0:0:0:0:ffff:127.0.0.1');
|
---|
| 54 | assert.equal(buf.toString('hex'), '00000000000000000000ffff7f000001');
|
---|
| 55 | assert.equal(ip.toString(buf), '::ffff:7f00:1');
|
---|
| 56 | });
|
---|
| 57 | });
|
---|
| 58 |
|
---|
| 59 | describe('fromPrefixLen() method', function() {
|
---|
| 60 | it('should create IPv4 mask', function() {
|
---|
| 61 | assert.equal(ip.fromPrefixLen(24), '255.255.255.0');
|
---|
| 62 | });
|
---|
| 63 | it('should create IPv6 mask', function() {
|
---|
| 64 | assert.equal(ip.fromPrefixLen(64), 'ffff:ffff:ffff:ffff::');
|
---|
| 65 | });
|
---|
| 66 | it('should create IPv6 mask explicitly', function() {
|
---|
| 67 | assert.equal(ip.fromPrefixLen(24, 'IPV6'), 'ffff:ff00::');
|
---|
| 68 | });
|
---|
| 69 | });
|
---|
| 70 |
|
---|
| 71 | describe('not() method', function() {
|
---|
| 72 | it('should reverse bits in address', function() {
|
---|
| 73 | assert.equal(ip.not('255.255.255.0'), '0.0.0.255');
|
---|
| 74 | });
|
---|
| 75 | });
|
---|
| 76 |
|
---|
| 77 | describe('or() method', function() {
|
---|
| 78 | it('should or bits in ipv4 addresses', function() {
|
---|
| 79 | assert.equal(ip.or('0.0.0.255', '192.168.1.10'), '192.168.1.255');
|
---|
| 80 | });
|
---|
| 81 | it('should or bits in ipv6 addresses', function() {
|
---|
| 82 | assert.equal(ip.or('::ff', '::abcd:dcba:abcd:dcba'),
|
---|
| 83 | '::abcd:dcba:abcd:dcff');
|
---|
| 84 | });
|
---|
| 85 | it('should or bits in mixed addresses', function() {
|
---|
| 86 | assert.equal(ip.or('0.0.0.255', '::abcd:dcba:abcd:dcba'),
|
---|
| 87 | '::abcd:dcba:abcd:dcff');
|
---|
| 88 | });
|
---|
| 89 | });
|
---|
| 90 |
|
---|
| 91 | describe('mask() method', function() {
|
---|
| 92 | it('should mask bits in address', function() {
|
---|
| 93 | assert.equal(ip.mask('192.168.1.134', '255.255.255.0'), '192.168.1.0');
|
---|
| 94 | assert.equal(ip.mask('192.168.1.134', '::ffff:ff00'), '::ffff:c0a8:100');
|
---|
| 95 | });
|
---|
| 96 |
|
---|
| 97 | it('should not leak data', function() {
|
---|
| 98 | for (var i = 0; i < 10; i++)
|
---|
| 99 | assert.equal(ip.mask('::1', '0.0.0.0'), '::');
|
---|
| 100 | });
|
---|
| 101 | });
|
---|
| 102 |
|
---|
| 103 | describe('subnet() method', function() {
|
---|
| 104 | // Test cases calculated with http://www.subnet-calculator.com/
|
---|
| 105 | var ipv4Subnet = ip.subnet('192.168.1.134', '255.255.255.192');
|
---|
| 106 |
|
---|
| 107 | it('should compute ipv4 network address', function() {
|
---|
| 108 | assert.equal(ipv4Subnet.networkAddress, '192.168.1.128');
|
---|
| 109 | });
|
---|
| 110 |
|
---|
| 111 | it('should compute ipv4 network\'s first address', function() {
|
---|
| 112 | assert.equal(ipv4Subnet.firstAddress, '192.168.1.129');
|
---|
| 113 | });
|
---|
| 114 |
|
---|
| 115 | it('should compute ipv4 network\'s last address', function() {
|
---|
| 116 | assert.equal(ipv4Subnet.lastAddress, '192.168.1.190');
|
---|
| 117 | });
|
---|
| 118 |
|
---|
| 119 | it('should compute ipv4 broadcast address', function() {
|
---|
| 120 | assert.equal(ipv4Subnet.broadcastAddress, '192.168.1.191');
|
---|
| 121 | });
|
---|
| 122 |
|
---|
| 123 | it('should compute ipv4 subnet number of addresses', function() {
|
---|
| 124 | assert.equal(ipv4Subnet.length, 64);
|
---|
| 125 | });
|
---|
| 126 |
|
---|
| 127 | it('should compute ipv4 subnet number of addressable hosts', function() {
|
---|
| 128 | assert.equal(ipv4Subnet.numHosts, 62);
|
---|
| 129 | });
|
---|
| 130 |
|
---|
| 131 | it('should compute ipv4 subnet mask', function() {
|
---|
| 132 | assert.equal(ipv4Subnet.subnetMask, '255.255.255.192');
|
---|
| 133 | });
|
---|
| 134 |
|
---|
| 135 | it('should compute ipv4 subnet mask\'s length', function() {
|
---|
| 136 | assert.equal(ipv4Subnet.subnetMaskLength, 26);
|
---|
| 137 | });
|
---|
| 138 |
|
---|
| 139 | it('should know whether a subnet contains an address', function() {
|
---|
| 140 | assert.equal(ipv4Subnet.contains('192.168.1.180'), true);
|
---|
| 141 | });
|
---|
| 142 |
|
---|
| 143 | it('should know whether a subnet does not contain an address', function() {
|
---|
| 144 | assert.equal(ipv4Subnet.contains('192.168.1.195'), false);
|
---|
| 145 | });
|
---|
| 146 | });
|
---|
| 147 |
|
---|
| 148 | describe('subnet() method with mask length 32', function() {
|
---|
| 149 | // Test cases calculated with http://www.subnet-calculator.com/
|
---|
| 150 | var ipv4Subnet = ip.subnet('192.168.1.134', '255.255.255.255');
|
---|
| 151 | it('should compute ipv4 network\'s first address', function() {
|
---|
| 152 | assert.equal(ipv4Subnet.firstAddress, '192.168.1.134');
|
---|
| 153 | });
|
---|
| 154 |
|
---|
| 155 | it('should compute ipv4 network\'s last address', function() {
|
---|
| 156 | assert.equal(ipv4Subnet.lastAddress, '192.168.1.134');
|
---|
| 157 | });
|
---|
| 158 |
|
---|
| 159 | it('should compute ipv4 subnet number of addressable hosts', function() {
|
---|
| 160 | assert.equal(ipv4Subnet.numHosts, 1);
|
---|
| 161 | });
|
---|
| 162 | });
|
---|
| 163 |
|
---|
| 164 | describe('subnet() method with mask length 31', function() {
|
---|
| 165 | // Test cases calculated with http://www.subnet-calculator.com/
|
---|
| 166 | var ipv4Subnet = ip.subnet('192.168.1.134', '255.255.255.254');
|
---|
| 167 | it('should compute ipv4 network\'s first address', function() {
|
---|
| 168 | assert.equal(ipv4Subnet.firstAddress, '192.168.1.134');
|
---|
| 169 | });
|
---|
| 170 |
|
---|
| 171 | it('should compute ipv4 network\'s last address', function() {
|
---|
| 172 | assert.equal(ipv4Subnet.lastAddress, '192.168.1.135');
|
---|
| 173 | });
|
---|
| 174 |
|
---|
| 175 | it('should compute ipv4 subnet number of addressable hosts', function() {
|
---|
| 176 | assert.equal(ipv4Subnet.numHosts, 2);
|
---|
| 177 | });
|
---|
| 178 | });
|
---|
| 179 |
|
---|
| 180 | describe('cidrSubnet() method', function() {
|
---|
| 181 | // Test cases calculated with http://www.subnet-calculator.com/
|
---|
| 182 | var ipv4Subnet = ip.cidrSubnet('192.168.1.134/26');
|
---|
| 183 |
|
---|
| 184 | it('should compute an ipv4 network address', function() {
|
---|
| 185 | assert.equal(ipv4Subnet.networkAddress, '192.168.1.128');
|
---|
| 186 | });
|
---|
| 187 |
|
---|
| 188 | it('should compute an ipv4 network\'s first address', function() {
|
---|
| 189 | assert.equal(ipv4Subnet.firstAddress, '192.168.1.129');
|
---|
| 190 | });
|
---|
| 191 |
|
---|
| 192 | it('should compute an ipv4 network\'s last address', function() {
|
---|
| 193 | assert.equal(ipv4Subnet.lastAddress, '192.168.1.190');
|
---|
| 194 | });
|
---|
| 195 |
|
---|
| 196 | it('should compute an ipv4 broadcast address', function() {
|
---|
| 197 | assert.equal(ipv4Subnet.broadcastAddress, '192.168.1.191');
|
---|
| 198 | });
|
---|
| 199 |
|
---|
| 200 | it('should compute an ipv4 subnet number of addresses', function() {
|
---|
| 201 | assert.equal(ipv4Subnet.length, 64);
|
---|
| 202 | });
|
---|
| 203 |
|
---|
| 204 | it('should compute an ipv4 subnet number of addressable hosts', function() {
|
---|
| 205 | assert.equal(ipv4Subnet.numHosts, 62);
|
---|
| 206 | });
|
---|
| 207 |
|
---|
| 208 | it('should compute an ipv4 subnet mask', function() {
|
---|
| 209 | assert.equal(ipv4Subnet.subnetMask, '255.255.255.192');
|
---|
| 210 | });
|
---|
| 211 |
|
---|
| 212 | it('should compute an ipv4 subnet mask\'s length', function() {
|
---|
| 213 | assert.equal(ipv4Subnet.subnetMaskLength, 26);
|
---|
| 214 | });
|
---|
| 215 |
|
---|
| 216 | it('should know whether a subnet contains an address', function() {
|
---|
| 217 | assert.equal(ipv4Subnet.contains('192.168.1.180'), true);
|
---|
| 218 | });
|
---|
| 219 |
|
---|
| 220 | it('should know whether a subnet contains an address', function() {
|
---|
| 221 | assert.equal(ipv4Subnet.contains('192.168.1.195'), false);
|
---|
| 222 | });
|
---|
| 223 |
|
---|
| 224 | });
|
---|
| 225 |
|
---|
| 226 | describe('cidr() method', function() {
|
---|
| 227 | it('should mask address in CIDR notation', function() {
|
---|
| 228 | assert.equal(ip.cidr('192.168.1.134/26'), '192.168.1.128');
|
---|
| 229 | assert.equal(ip.cidr('2607:f0d0:1002:51::4/56'), '2607:f0d0:1002::');
|
---|
| 230 | });
|
---|
| 231 | });
|
---|
| 232 |
|
---|
| 233 | describe('isEqual() method', function() {
|
---|
| 234 | it('should check if addresses are equal', function() {
|
---|
| 235 | assert(ip.isEqual('127.0.0.1', '::7f00:1'));
|
---|
| 236 | assert(!ip.isEqual('127.0.0.1', '::7f00:2'));
|
---|
| 237 | assert(ip.isEqual('127.0.0.1', '::ffff:7f00:1'));
|
---|
| 238 | assert(!ip.isEqual('127.0.0.1', '::ffaf:7f00:1'));
|
---|
| 239 | assert(ip.isEqual('::ffff:127.0.0.1', '::ffff:127.0.0.1'));
|
---|
| 240 | assert(ip.isEqual('::ffff:127.0.0.1', '127.0.0.1'));
|
---|
| 241 | });
|
---|
| 242 | });
|
---|
| 243 |
|
---|
| 244 |
|
---|
| 245 | describe('isPrivate() method', function() {
|
---|
| 246 | it('should check if an address is localhost', function() {
|
---|
| 247 | assert.equal(ip.isPrivate('127.0.0.1'), true);
|
---|
| 248 | });
|
---|
| 249 |
|
---|
| 250 | it('should check if an address is from a 192.168.x.x network', function() {
|
---|
| 251 | assert.equal(ip.isPrivate('192.168.0.123'), true);
|
---|
| 252 | assert.equal(ip.isPrivate('192.168.122.123'), true);
|
---|
| 253 | assert.equal(ip.isPrivate('192.162.1.2'), false);
|
---|
| 254 | });
|
---|
| 255 |
|
---|
| 256 | it('should check if an address is from a 172.16.x.x network', function() {
|
---|
| 257 | assert.equal(ip.isPrivate('172.16.0.5'), true);
|
---|
| 258 | assert.equal(ip.isPrivate('172.16.123.254'), true);
|
---|
| 259 | assert.equal(ip.isPrivate('171.16.0.5'), false);
|
---|
| 260 | assert.equal(ip.isPrivate('172.25.232.15'), true);
|
---|
| 261 | assert.equal(ip.isPrivate('172.15.0.5'), false);
|
---|
| 262 | assert.equal(ip.isPrivate('172.32.0.5'), false);
|
---|
| 263 | });
|
---|
| 264 |
|
---|
| 265 | it('should check if an address is from a 169.254.x.x network', function() {
|
---|
| 266 | assert.equal(ip.isPrivate('169.254.2.3'), true);
|
---|
| 267 | assert.equal(ip.isPrivate('169.254.221.9'), true);
|
---|
| 268 | assert.equal(ip.isPrivate('168.254.2.3'), false);
|
---|
| 269 | });
|
---|
| 270 |
|
---|
| 271 | it('should check if an address is from a 10.x.x.x network', function() {
|
---|
| 272 | assert.equal(ip.isPrivate('10.0.2.3'), true);
|
---|
| 273 | assert.equal(ip.isPrivate('10.1.23.45'), true);
|
---|
| 274 | assert.equal(ip.isPrivate('12.1.2.3'), false);
|
---|
| 275 | });
|
---|
| 276 |
|
---|
| 277 | it('should check if an address is from a private IPv6 network', function() {
|
---|
| 278 | assert.equal(ip.isPrivate('fd12:3456:789a:1::1'), true);
|
---|
| 279 | assert.equal(ip.isPrivate('fe80::f2de:f1ff:fe3f:307e'), true);
|
---|
| 280 | assert.equal(ip.isPrivate('::ffff:10.100.1.42'), true);
|
---|
| 281 | assert.equal(ip.isPrivate('::FFFF:172.16.200.1'), true);
|
---|
| 282 | assert.equal(ip.isPrivate('::ffff:192.168.0.1'), true);
|
---|
| 283 | });
|
---|
| 284 |
|
---|
| 285 | it('should check if an address is from the internet', function() {
|
---|
| 286 | assert.equal(ip.isPrivate('165.225.132.33'), false); // joyent.com
|
---|
| 287 | });
|
---|
| 288 |
|
---|
| 289 | it('should check if an address is a loopback IPv6 address', function() {
|
---|
| 290 | assert.equal(ip.isPrivate('::'), true);
|
---|
| 291 | assert.equal(ip.isPrivate('::1'), true);
|
---|
| 292 | assert.equal(ip.isPrivate('fe80::1'), true);
|
---|
| 293 | });
|
---|
| 294 | });
|
---|
| 295 |
|
---|
| 296 | describe('loopback() method', function() {
|
---|
| 297 | describe('undefined', function() {
|
---|
| 298 | it('should respond with 127.0.0.1', function() {
|
---|
| 299 | assert.equal(ip.loopback(), '127.0.0.1')
|
---|
| 300 | });
|
---|
| 301 | });
|
---|
| 302 |
|
---|
| 303 | describe('ipv4', function() {
|
---|
| 304 | it('should respond with 127.0.0.1', function() {
|
---|
| 305 | assert.equal(ip.loopback('ipv4'), '127.0.0.1')
|
---|
| 306 | });
|
---|
| 307 | });
|
---|
| 308 |
|
---|
| 309 | describe('ipv6', function() {
|
---|
| 310 | it('should respond with fe80::1', function() {
|
---|
| 311 | assert.equal(ip.loopback('ipv6'), 'fe80::1')
|
---|
| 312 | });
|
---|
| 313 | });
|
---|
| 314 | });
|
---|
| 315 |
|
---|
| 316 | describe('isLoopback() method', function() {
|
---|
| 317 | describe('127.0.0.1', function() {
|
---|
| 318 | it('should respond with true', function() {
|
---|
| 319 | assert.ok(ip.isLoopback('127.0.0.1'))
|
---|
| 320 | });
|
---|
| 321 | });
|
---|
| 322 |
|
---|
| 323 | describe('127.8.8.8', function () {
|
---|
| 324 | it('should respond with true', function () {
|
---|
| 325 | assert.ok(ip.isLoopback('127.8.8.8'))
|
---|
| 326 | });
|
---|
| 327 | });
|
---|
| 328 |
|
---|
| 329 | describe('8.8.8.8', function () {
|
---|
| 330 | it('should respond with false', function () {
|
---|
| 331 | assert.equal(ip.isLoopback('8.8.8.8'), false);
|
---|
| 332 | });
|
---|
| 333 | });
|
---|
| 334 |
|
---|
| 335 | describe('fe80::1', function() {
|
---|
| 336 | it('should respond with true', function() {
|
---|
| 337 | assert.ok(ip.isLoopback('fe80::1'))
|
---|
| 338 | });
|
---|
| 339 | });
|
---|
| 340 |
|
---|
| 341 | describe('::1', function() {
|
---|
| 342 | it('should respond with true', function() {
|
---|
| 343 | assert.ok(ip.isLoopback('::1'))
|
---|
| 344 | });
|
---|
| 345 | });
|
---|
| 346 |
|
---|
| 347 | describe('::', function() {
|
---|
| 348 | it('should respond with true', function() {
|
---|
| 349 | assert.ok(ip.isLoopback('::'))
|
---|
| 350 | });
|
---|
| 351 | });
|
---|
| 352 | });
|
---|
| 353 |
|
---|
| 354 | describe('address() method', function() {
|
---|
| 355 | describe('undefined', function() {
|
---|
| 356 | it('should respond with a private ip', function() {
|
---|
| 357 | assert.ok(ip.isPrivate(ip.address()));
|
---|
| 358 | });
|
---|
| 359 | });
|
---|
| 360 |
|
---|
| 361 | describe('private', function() {
|
---|
| 362 | [ undefined, 'ipv4', 'ipv6' ].forEach(function(family) {
|
---|
| 363 | describe(family, function() {
|
---|
| 364 | it('should respond with a private ip', function() {
|
---|
| 365 | assert.ok(ip.isPrivate(ip.address('private', family)));
|
---|
| 366 | });
|
---|
| 367 | });
|
---|
| 368 | });
|
---|
| 369 | });
|
---|
| 370 |
|
---|
| 371 | var interfaces = os.networkInterfaces();
|
---|
| 372 |
|
---|
| 373 | Object.keys(interfaces).forEach(function(nic) {
|
---|
| 374 | describe(nic, function() {
|
---|
| 375 | [ undefined, 'ipv4' ].forEach(function(family) {
|
---|
| 376 | describe(family, function() {
|
---|
| 377 | it('should respond with an ipv4 address', function() {
|
---|
| 378 | var addr = ip.address(nic, family);
|
---|
| 379 | assert.ok(!addr || net.isIPv4(addr));
|
---|
| 380 | });
|
---|
| 381 | });
|
---|
| 382 | });
|
---|
| 383 |
|
---|
| 384 | describe('ipv6', function() {
|
---|
| 385 | it('should respond with an ipv6 address', function() {
|
---|
| 386 | var addr = ip.address(nic, 'ipv6');
|
---|
| 387 | assert.ok(!addr || net.isIPv6(addr));
|
---|
| 388 | });
|
---|
| 389 | })
|
---|
| 390 | });
|
---|
| 391 | });
|
---|
| 392 | });
|
---|
| 393 |
|
---|
| 394 | describe('toLong() method', function() {
|
---|
| 395 | it('should respond with a int', function() {
|
---|
| 396 | assert.equal(ip.toLong('127.0.0.1'), 2130706433);
|
---|
| 397 | assert.equal(ip.toLong('255.255.255.255'), 4294967295);
|
---|
| 398 | });
|
---|
| 399 | });
|
---|
| 400 |
|
---|
| 401 | describe('fromLong() method', function() {
|
---|
| 402 | it('should repond with ipv4 address', function() {
|
---|
| 403 | assert.equal(ip.fromLong(2130706433), '127.0.0.1');
|
---|
| 404 | assert.equal(ip.fromLong(4294967295), '255.255.255.255');
|
---|
| 405 | });
|
---|
| 406 | })
|
---|
| 407 | });
|
---|