Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Aug 15, 2012
0 parents commit bedc9da
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
npm-debug.log
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# IP
104 changes: 104 additions & 0 deletions lib/ip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
var ip = exports,
Buffer = require('buffer').Buffer;

ip.toBuffer = function toBuffer(ip) {
var result;

if (/^(\d{1,3}\.){3,3}\d{1,3}$/.test(ip)) {
result = new Buffer(ip.split(/\./g).map(function(byte) {
return parseInt(byte, 10) & 0xff;
}));
} else if (/^[a-f0-9:]+$/.test(ip)) {
var s = ip.split(/::/g, 2),
head = (s[0] || '').split(/:/g, 8),
tail = (s[1] || '').split(/:/g, 8);

if (tail.length === 0) {
// xxxx::
while (head.length < 8) head.push('0000');
} else if (head.length === 0) {
// ::xxxx
while (tail.length < 8) tail.unshift('0000');
} else {
// xxxx::xxxx
while (head.length + tail.length < 8) head.push('0000');
}

result = new Buffer(head.concat(tail).map(function(word) {
word = parseInt(word, 16);
return [(word >> 8) & 0xff, word & 0xff];
}).reduce(function(prev, next) {
return prev.concat(next);
}));
} else {
throw Error('Invalid ip address: ' + ip);
}

return result;
};

ip.toString = function toString(buff) {
var result = [];
if (buff.length === 4) {
// IPv4
for (var i = 0; i < buff.length; i++) {
result.push(buff[i]);
}
result = result.join('.');
} else if (buff.length === 16) {
// IPv6
for (var i = 0; i < buff.length; i += 2) {
result.push(buff.readUInt16BE(i).toString(16));
}
result = result.join(':');
result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');
result = result.replace(/:{3,4}/, '::');
}

return result;
};

ip.mask = function mask(addr, mask) {
addr = ip.toBuffer(addr);
mask = ip.toBuffer(mask);

var result = new Buffer(Math.max(addr.length, mask.length));

// Same protocol - do bitwise and
if (addr.length === mask.length) {
for (var i = 0; i < addr.length; i++) {
result[i] = addr[i] & mask[i];
}
} else if (mask.length === 4) {
// IPv6 address and IPv4 mask
// (Mask low bits)
for (var i = 0; i < mask.length; i++) {
result[i] = addr[addr.length - 4 + i] & mask[i];
}
} else {
// IPv6 mask and IPv4 addr
for (var i = 0; i < result.length - 6; i++) {
result[i] = 0;
}

// ::ffff:ipv4
result[10] = 0xff;
result[11] = 0xff;
for (var i = 0; i < addr.length; i++) {
result[i + 12] = addr[i] & mask[i + 12];
}
}

return ip.toString(result);
};

ip.not = function not(addr) {
var buff = ip.toBuffer(addr);
for (var i = 0; i < buff.length; i++) {
buff[i] = 0xff ^ buff[i];
}
return ip.toString(buff);
};

ip.isEqual = function isEqual(a, b) {
};
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "ip",
"version": "0.0.1",
"author": "Fedor Indutny <[email protected]>",
"homepage": "https://github.com/indutny/node-ip",
"repository": {
"type": "git",
"url": "http://github.com/indutny/node-ip.git"
},
"main": "lib/ip",
"devDependencies": {
"mocha": "~1.3.2"
},
"scripts": {
"test": "mocha --reporter spec test/*-test.js"
}
}
33 changes: 33 additions & 0 deletions test/api-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var ip = require('..'),
assert = require('assert');

describe('IP library for node.js', function() {
describe('toBuffer()/toString() methods', function() {
it('should convert to buffer IPv4 address', function() {
var buf = ip.toBuffer('127.0.0.1');
assert.equal(buf.toString('hex'), '7f000001');
assert.equal(ip.toString(buf), '127.0.0.1');
});

it('should convert to buffer IPv6 address', function() {
var buf = ip.toBuffer('::1');
assert(/(00){15,15}01/.test(buf.toString('hex')));
assert.equal(ip.toString(buf), '::1');
assert.equal(ip.toString(ip.toBuffer('1::')), '1::');
assert.equal(ip.toString(ip.toBuffer('abcd::dcba')), 'abcd::dcba');
});
});

describe('not() method', function() {
it('should reverse bits in address', function() {
assert.equal(ip.not('255.255.255.0'), '0.0.0.255');
});
});

describe('mask() method', function() {
it('should mask bits in address', function() {
assert.equal(ip.mask('192.168.1.134', '255.255.255.0'), '192.168.1.0');
assert.equal(ip.mask('192.168.1.134', '::ffff:ff00'), '::ffff:c0a8:100');
});
});
});

0 comments on commit bedc9da

Please sign in to comment.