• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3var ip = require('..');
4var assert = require('assert');
5var net = require('net');
6var os = require('os');
7
8describe('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});
408