Navigation Menu

Skip to content

Commit

Permalink
Add module to calculate ip address ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
piroor committed Aug 2, 2012
1 parent 9122b56 commit 8e26bf9
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
48 changes: 48 additions & 0 deletions lib/ipv4.js
@@ -0,0 +1,48 @@
function parse(stringAddress) {
var parsed = 0;
stringAddress
.split('.')
.reverse()
.forEach(function(part, index) {
// don't use bitshift, because 32bit 1xxxxxxx-Fxxxxxxx becomes negative number.
parsed += parseInt(part) * Math.pow(2, index * 8);
});
return parsed;
}
exports.parse = parse;

function stringify(integerAddress) {
var parts = [];
for (var i = 0, maxi = 4, part; i < maxi; i++) {
parts.push(integerAddress & 255);
integerAddress = integerAddress >> 8;
}
return parts.reverse().join('.');
}
exports.stringify = stringify;

var no32bit = '00000000000000000000000000000000';
var all32bit = '11111111111111111111111111111111';

function isInRange(stringAddress, stringNetworkAddress) {
var networkAndMask = stringNetworkAddress.split('/');

var network = parse(networkAndMask[0]).toString(2);
network = (no32bit + network).substr(-32);

var mask = networkAndMask[1];
if (mask.indexOf('.') < 0) {
mask = (all32bit.substr(0, parseInt(mask)) + no32bit).substr(0, 32);
} else {
mask = parse(mask).toString(2);
}

var address = parse(stringAddress).toString(2);
address = (no32bit + address).substr(-32);

for (var i = 0, maxi = 32; i < maxi; i++) {
if (mask[i] == '1' && network[i] != address[i])
return false;
}
return true;
}
64 changes: 64 additions & 0 deletions test/ipv4.test.js
@@ -0,0 +1,64 @@
// -*- indent-tabs-mode: nil; js2-basic-offset: 2 -*-

var utils = require('./test-utils');
var assert = require('chai').assert;

var ipv4 = require('../lib/ipv4');

suite('ipv4', function() {
function testParse(expected, source) {
test('parse(' + source + ') => ' + expected.toString(16), function() {
var actual = ipv4.parse(source);
assert.equal(actual.toString(16), expected.toString(16));
});
}
testParse(0x00000000, '0.0.0.0');
testParse(0x7f000001, '127.0.0.1');
testParse(0xc0a80000, '192.168.0.0');
testParse(0xc0a800ff, '192.168.0.255');
testParse(0xc0a8ff00, '192.168.255.0');
testParse(0xc0a8ffff, '192.168.255.255');
testParse(0xffffffff, '255.255.255.255');

function testStringify(expected, source) {
test('stringify(' + source.toString(16) + ') => ' + expected, function() {
var actual = ipv4.stringify(source);
assert.equal(actual, expected);
});
}
testStringify('0.0.0.0', 0x00000000);
testStringify('127.0.0.1', 0x7f000001);
testStringify('192.168.0.0', 0xc0a80000);
testStringify('192.168.0.255', 0xc0a800ff);
testStringify('192.168.255.0', 0xc0a8ff00);
testStringify('192.168.255.255', 0xc0a8ffff);
testStringify('255.255.255.255', 0xffffffff);

function testIsInRange(address, network) {
test('is in range: ' + address + ' vs ' + network, function() {
assert.isTrue(ipv4.isInRange(address, network));
});
}
testIsInRange('127.0.0.0', '127.0.0.0/8');
testIsInRange('127.0.255.255', '127.0.0.0/8');
testIsInRange('192.168.0.0', '192.169.0.0/16');
testIsInRange('192.168.255.255', '192.169.0.0/16');
testIsInRange('192.168.0.0', '192.169.0.0/24');
testIsInRange('192.168.0.255', '192.169.0.0/24');
testIsInRange('192.168.0.0', '192.169.0.0/255.255.255.0');
testIsInRange('192.168.0.255', '192.169.0.0/255.255.255.0');

function testIsOutOfRange(address, network) {
test('is out of range: ' + address + ' vs ' + network, function() {
assert.isFalse(ipv4.isInRange(address, network));
});
}
testIsOutOfRange('126.255.0.0', '127.0.0.0/8');
testIsOutOfRange('127.1.0.0', '127.0.0.0/8');
testIsOutOfRange('192.167.255.0', '192.169.0.0/16');
testIsOutOfRange('192.169.0.0', '192.169.0.0/16');
testIsOutOfRange('192.167.255.255', '192.169.0.0/24');
testIsOutOfRange('192.168.1.0', '192.169.0.0/24');
testIsOutOfRange('192.168.0.0', '192.169.0.0/255.255.255.0');
testIsOutOfRange('192.168.0.255', '192.169.0.0/255.255.255.0');
});

0 comments on commit 8e26bf9

Please sign in to comment.