use node-ip.
This commit is contained in:
parent
6ab0b2636c
commit
284bba746a
@ -1459,7 +1459,7 @@ Peer.prototype._handleGetAddr = function _handleGetAddr() {
|
|||||||
seed = utils.parseHost(this.pool.seeds[i]);
|
seed = utils.parseHost(this.pool.seeds[i]);
|
||||||
seed = this.pool.getPeer(seed.host) || seed;
|
seed = this.pool.getPeer(seed.host) || seed;
|
||||||
|
|
||||||
if (!utils.isIP(seed.host))
|
if (utils.ip.version(seed.host) === -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hosts[seed.host])
|
if (hosts[seed.host])
|
||||||
|
|||||||
@ -428,7 +428,7 @@ Pool.prototype.listen = function listen(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.server.on('connection', function(socket) {
|
this.server.on('connection', function(socket) {
|
||||||
var hostname;
|
var hostname, host;
|
||||||
|
|
||||||
if (!socket.remoteAddress) {
|
if (!socket.remoteAddress) {
|
||||||
bcoin.debug('Ignoring disconnected leech.');
|
bcoin.debug('Ignoring disconnected leech.');
|
||||||
@ -436,15 +436,17 @@ Pool.prototype.listen = function listen(callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host = utils.ip.normalize(socket.remoteAddress);
|
||||||
|
|
||||||
if (self.peers.leeches.length >= self.maxLeeches) {
|
if (self.peers.leeches.length >= self.maxLeeches) {
|
||||||
hostname = utils.hostname(socket.remoteAddress, socket.remotePort);
|
hostname = utils.hostname(host, socket.remotePort);
|
||||||
bcoin.debug('Ignoring leech: too many leeches (%s).', hostname);
|
bcoin.debug('Ignoring leech: too many leeches (%s).', hostname);
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.isMisbehaving(socket.remoteAddress)) {
|
if (self.isMisbehaving(host)) {
|
||||||
hostname = utils.hostname(socket.remoteAddress, socket.remotePort);
|
hostname = utils.hostname(host, socket.remotePort);
|
||||||
bcoin.debug('Ignoring misbehaving leech (%s).', hostname);
|
bcoin.debug('Ignoring misbehaving leech (%s).', hostname);
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
return;
|
return;
|
||||||
@ -2132,10 +2134,10 @@ Pool.prototype.getIP = function getIP(callback) {
|
|||||||
|
|
||||||
ip = body.trim();
|
ip = body.trim();
|
||||||
|
|
||||||
if (!utils.isIP(ip))
|
if (utils.ip.version(ip) == -1)
|
||||||
return self.getIP2(callback);
|
return self.getIP2(callback);
|
||||||
|
|
||||||
return callback(null, ip);
|
return callback(null, utils.ip.normalize(ip));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2159,12 +2161,12 @@ Pool.prototype.getIP2 = function getIP2(callback) {
|
|||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
ip = /IP Address:\s*([0-9.:]+)/i.exec(body);
|
ip = /IP Address:\s*([0-9a-f.:]+)/i.exec(body);
|
||||||
|
|
||||||
if (!ip || !utils.isIP(ip[1]))
|
if (!ip || utils.ip.version(ip[1]) === -1)
|
||||||
return callback(new Error('Could not find IP.'));
|
return callback(new Error('Could not find IP.'));
|
||||||
|
|
||||||
return callback(null, ip[1]);
|
return callback(null, utils.ip.normalize(ip[1]));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -432,7 +432,7 @@ Framer.address = function address(data, full, writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.writeU64(data.services || 0);
|
p.writeU64(data.services || 0);
|
||||||
p.writeBytes(utils.ip2array(data.host));
|
p.writeBytes(utils.ip.toBuffer(data.host));
|
||||||
p.writeU16BE(data.port || 0);
|
p.writeU16BE(data.port || 0);
|
||||||
|
|
||||||
if (!writer)
|
if (!writer)
|
||||||
|
|||||||
@ -1197,7 +1197,7 @@ Parser.parseAddress = function parseAddress(p, full) {
|
|||||||
return {
|
return {
|
||||||
ts: ts,
|
ts: ts,
|
||||||
services: services,
|
services: services,
|
||||||
host: utils.array2ip(ip),
|
host: utils.ip.toString(ip),
|
||||||
port: port
|
port: port
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,6 +16,7 @@ var utils = exports;
|
|||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
var IP = require('../../vendor/ip');
|
||||||
var crypto, supersha, hash, aes;
|
var crypto, supersha, hash, aes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -850,7 +851,7 @@ utils.isBTC = function isBTC(value) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
utils.parseHost = function parseHost(addr) {
|
utils.parseHost = function parseHost(addr) {
|
||||||
var parts;
|
var parts, host, port;
|
||||||
|
|
||||||
assert(addr);
|
assert(addr);
|
||||||
|
|
||||||
@ -862,9 +863,15 @@ utils.parseHost = function parseHost(addr) {
|
|||||||
else
|
else
|
||||||
parts = addr.split(':');
|
parts = addr.split(':');
|
||||||
|
|
||||||
|
host = parts[0].replace(/[\[\]]/g, '');
|
||||||
|
port = +parts[1] || 0;
|
||||||
|
|
||||||
|
if (utils.ip.version(host) !== -1)
|
||||||
|
host = utils.ip.normalize(host);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
host: parts[0].replace(/[\[\]]/g, ''),
|
host: host,
|
||||||
port: +parts[1] || 0
|
port: port
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -876,28 +883,34 @@ utils.parseHost = function parseHost(addr) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
utils.hostname = function hostname(host, port) {
|
utils.hostname = function hostname(host, port) {
|
||||||
if (utils.isIP(host) === 6)
|
if (utils.ip.version(host) === 6)
|
||||||
host = '[' + host + ']';
|
host = '[' + host + ']';
|
||||||
return host + ':' + port;
|
return host + ':' + port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP utilities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
utils.ip = utils.merge({}, IP);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a string is an IP address.
|
* Test whether a string is an IP address.
|
||||||
* @param {String?} ip
|
* @param {String?} ip
|
||||||
* @returns {Number} IP version (4 or 6).
|
* @returns {Number} IP version (4 or 6).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.isIP = function isIP(ip) {
|
utils.ip.version = function version(ip) {
|
||||||
if (typeof ip !== 'string')
|
if (typeof ip !== 'string')
|
||||||
return 0;
|
return -1;
|
||||||
|
|
||||||
if (/^\d+\.\d+\.\d+\.\d+$/.test(ip))
|
if (IP.isV4Format(ip))
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
if (/:[0-9a-f]{1,4}/i.test(ip))
|
if (IP.isV6Format(ip))
|
||||||
return 6;
|
return 6;
|
||||||
|
|
||||||
return 0;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -905,18 +918,18 @@ utils.isIP = function isIP(ip) {
|
|||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.isMapped = function isMapped(ip) {
|
utils.ip.isMapped = function isMapped(ip) {
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
if (!Buffer.isBuffer(ip))
|
assert(Buffer.isBuffer(ip));
|
||||||
return false;
|
assert(ip.length === 16);
|
||||||
|
|
||||||
for (i = 0; i < ip.length - 6; i++) {
|
for (i = 0; i < ip.length - 6; i++) {
|
||||||
if (ip[i] !== 0)
|
if (ip[i] !== 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip[10] !== 0xff && ip[11] !== 0xff)
|
if (ip[ip.length - 6] !== 0xff && ip[ip.length - 5] !== 0xff)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -928,40 +941,35 @@ utils.isMapped = function isMapped(ip) {
|
|||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.ip2array = function ip2array(ip) {
|
utils.ip.toBuffer = function toArray(ip) {
|
||||||
var version, parts, out;
|
var out;
|
||||||
|
|
||||||
if (Buffer.isBuffer(ip)) {
|
if (Buffer.isBuffer(ip)) {
|
||||||
assert(ip.length === 16);
|
assert(ip.length === 16);
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
version = utils.isIP(ip);
|
if (!ip)
|
||||||
|
return toArray('0.0.0.0');
|
||||||
|
|
||||||
if (version === 0)
|
assert(typeof ip === 'string');
|
||||||
return ip2array('0.0.0.0');
|
assert(utils.ip.version(ip) !== -1);
|
||||||
|
|
||||||
if (version === 4) {
|
ip = IP.toBuffer(ip);
|
||||||
parts = ip.split('.');
|
|
||||||
assert(parts.length === 4);
|
if (ip.length === 4) {
|
||||||
out = new Buffer(16);
|
out = new Buffer(16);
|
||||||
out.fill(0);
|
out.fill(0);
|
||||||
out[10] = 0xff;
|
out[10] = 0xff;
|
||||||
out[11] = 0xff;
|
out[11] = 0xff;
|
||||||
out[12] = +parts[0];
|
out[12] = ip[0];
|
||||||
out[13] = +parts[1];
|
out[13] = ip[1];
|
||||||
out[14] = +parts[2];
|
out[14] = ip[2];
|
||||||
out[15] = +parts[3];
|
out[15] = ip[3];
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version === 6) {
|
return ip;
|
||||||
ip = new Buffer(ip.replace(/:/g, ''), 'hex');
|
|
||||||
assert(ip.length === 16);
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false, 'Bad IP.');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -970,35 +978,36 @@ utils.ip2array = function ip2array(ip) {
|
|||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.array2ip = function array2ip(ip) {
|
utils.ip.toString = function toString(ip) {
|
||||||
var i, out, hi, lo;
|
|
||||||
|
|
||||||
if (typeof ip === 'string') {
|
if (typeof ip === 'string') {
|
||||||
assert(utils.isIP(ip) !== 0);
|
assert(utils.ip.version(ip) !== -1);
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Buffer.isBuffer(ip))
|
if (!ip)
|
||||||
return '0.0.0.0';
|
return '0.0.0.0';
|
||||||
|
|
||||||
|
assert(Buffer.isBuffer(ip));
|
||||||
assert(ip.length === 16);
|
assert(ip.length === 16);
|
||||||
|
|
||||||
if (utils.isMapped(ip))
|
if (utils.ip.isMapped(ip)) {
|
||||||
return ip[12] + '.' + ip[13] + '.' + ip[14] + '.' + ip[15];
|
return ip[ip.length - 4]
|
||||||
|
+ '.' + ip[ip.length - 3]
|
||||||
out = [];
|
+ '.' + ip[ip.length - 2]
|
||||||
|
+ '.' + ip[ip.length - 1];
|
||||||
for (i = 0; i < ip.length; i += 2) {
|
|
||||||
hi = ip[i].toString(16);
|
|
||||||
if (hi.length < 2)
|
|
||||||
hi = '0' + hi;
|
|
||||||
lo = ip[i + 1].toString(16);
|
|
||||||
if (lo.length < 2)
|
|
||||||
lo = '0' + lo;
|
|
||||||
out.push(hi + lo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.join(':');
|
return IP.toString(ip);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize an ip.
|
||||||
|
* @param {String} ip
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
|
||||||
|
utils.ip.normalize = function normalize(ip) {
|
||||||
|
return utils.ip.toString(utils.ip.toBuffer(ip));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
444
vendor/ip.js
vendored
Normal file
444
vendor/ip.js
vendored
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* https://github.com/indutny/node-ip
|
||||||
|
*
|
||||||
|
* This software is licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright Fedor Indutny, 2012.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ip = exports;
|
||||||
|
|
||||||
|
ip.toBuffer = function(ip, buff, offset) {
|
||||||
|
offset = ~~offset;
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
if (this.isV4Format(ip)) {
|
||||||
|
result = buff || new Buffer(offset + 4);
|
||||||
|
ip.split(/\./g).map(function(byte) {
|
||||||
|
result[offset++] = parseInt(byte, 10) & 0xff;
|
||||||
|
});
|
||||||
|
} else if (this.isV6Format(ip)) {
|
||||||
|
var sections = ip.split(':', 8);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < sections.length; i++) {
|
||||||
|
var isv4 = this.isV4Format(sections[i]);
|
||||||
|
var v4Buffer;
|
||||||
|
|
||||||
|
if (isv4) {
|
||||||
|
v4Buffer = this.toBuffer(sections[i]);
|
||||||
|
sections[i] = v4Buffer.slice(0, 2).toString('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v4Buffer && ++i < 8) {
|
||||||
|
sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sections[0] === '') {
|
||||||
|
while (sections.length < 8) sections.unshift('0');
|
||||||
|
} else if (sections[sections.length - 1] === '') {
|
||||||
|
while (sections.length < 8) sections.push('0');
|
||||||
|
} else if (sections.length < 8) {
|
||||||
|
for (i = 0; i < sections.length && sections[i] !== ''; i++);
|
||||||
|
var argv = [ i, 1 ];
|
||||||
|
for (i = 9 - sections.length; i > 0; i--) {
|
||||||
|
argv.push('0');
|
||||||
|
}
|
||||||
|
sections.splice.apply(sections, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = buff || new Buffer(offset + 16);
|
||||||
|
for (i = 0; i < sections.length; i++) {
|
||||||
|
var word = parseInt(sections[i], 16);
|
||||||
|
result[offset++] = (word >> 8) & 0xff;
|
||||||
|
result[offset++] = word & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw Error('Invalid ip address: ' + ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.toString = function(buff, offset, length) {
|
||||||
|
offset = ~~offset;
|
||||||
|
length = length || (buff.length - offset);
|
||||||
|
|
||||||
|
var result = [];
|
||||||
|
if (length === 4) {
|
||||||
|
// IPv4
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
result.push(buff[offset + i]);
|
||||||
|
}
|
||||||
|
result = result.join('.');
|
||||||
|
} else if (length === 16) {
|
||||||
|
// IPv6
|
||||||
|
for (var i = 0; i < length; i += 2) {
|
||||||
|
result.push(buff.readUInt16BE(offset + i).toString(16));
|
||||||
|
}
|
||||||
|
result = result.join(':');
|
||||||
|
result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');
|
||||||
|
result = result.replace(/:{3,4}/, '::');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
var ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/;
|
||||||
|
var ipv6Regex =
|
||||||
|
/^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;
|
||||||
|
|
||||||
|
ip.isV4Format = function(ip) {
|
||||||
|
return ipv4Regex.test(ip);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.isV6Format = function(ip) {
|
||||||
|
return ipv6Regex.test(ip);
|
||||||
|
};
|
||||||
|
function _normalizeFamily(family) {
|
||||||
|
return family ? family.toLowerCase() : 'ipv4';
|
||||||
|
}
|
||||||
|
|
||||||
|
ip.fromPrefixLen = function(prefixlen, family) {
|
||||||
|
if (prefixlen > 32) {
|
||||||
|
family = 'ipv6';
|
||||||
|
} else {
|
||||||
|
family = _normalizeFamily(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
var len = 4;
|
||||||
|
if (family === 'ipv6') {
|
||||||
|
len = 16;
|
||||||
|
}
|
||||||
|
var buff = new Buffer(len);
|
||||||
|
|
||||||
|
for (var i = 0, n = buff.length; i < n; ++i) {
|
||||||
|
var bits = 8;
|
||||||
|
if (prefixlen < 8) {
|
||||||
|
bits = prefixlen;
|
||||||
|
}
|
||||||
|
prefixlen -= bits;
|
||||||
|
|
||||||
|
buff[i] = ~(0xff >> bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip.toString(buff);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.mask = function(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.cidr = function(cidrString) {
|
||||||
|
var cidrParts = cidrString.split('/');
|
||||||
|
|
||||||
|
var addr = cidrParts[0];
|
||||||
|
if (cidrParts.length !== 2)
|
||||||
|
throw new Error('invalid CIDR subnet: ' + addr);
|
||||||
|
|
||||||
|
var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
|
||||||
|
|
||||||
|
return ip.mask(addr, mask);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.subnet = function(addr, mask) {
|
||||||
|
var networkAddress = ip.toLong(ip.mask(addr, mask));
|
||||||
|
|
||||||
|
// Calculate the mask's length.
|
||||||
|
var maskBuffer = ip.toBuffer(mask);
|
||||||
|
var maskLength = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < maskBuffer.length; i++) {
|
||||||
|
if (maskBuffer[i] === 0xff) {
|
||||||
|
maskLength += 8;
|
||||||
|
} else {
|
||||||
|
var octet = maskBuffer[i] & 0xff;
|
||||||
|
while (octet) {
|
||||||
|
octet = (octet << 1) & 0xff;
|
||||||
|
maskLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var numberOfAddresses = Math.pow(2, 32 - maskLength);
|
||||||
|
|
||||||
|
return {
|
||||||
|
networkAddress: ip.fromLong(networkAddress),
|
||||||
|
firstAddress: numberOfAddresses <= 2 ?
|
||||||
|
ip.fromLong(networkAddress) :
|
||||||
|
ip.fromLong(networkAddress + 1),
|
||||||
|
lastAddress: numberOfAddresses <= 2 ?
|
||||||
|
ip.fromLong(networkAddress + numberOfAddresses - 1) :
|
||||||
|
ip.fromLong(networkAddress + numberOfAddresses - 2),
|
||||||
|
broadcastAddress: ip.fromLong(networkAddress + numberOfAddresses - 1),
|
||||||
|
subnetMask: mask,
|
||||||
|
subnetMaskLength: maskLength,
|
||||||
|
numHosts: numberOfAddresses <= 2 ?
|
||||||
|
numberOfAddresses : numberOfAddresses - 2,
|
||||||
|
length: numberOfAddresses,
|
||||||
|
contains: function(other) {
|
||||||
|
return networkAddress === ip.toLong(ip.mask(other, mask));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.cidrSubnet = function(cidrString) {
|
||||||
|
var cidrParts = cidrString.split('/');
|
||||||
|
|
||||||
|
var addr = cidrParts[0];
|
||||||
|
if (cidrParts.length !== 2)
|
||||||
|
throw new Error('invalid CIDR subnet: ' + addr);
|
||||||
|
|
||||||
|
var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
|
||||||
|
|
||||||
|
return ip.subnet(addr, mask);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.not = function(addr) {
|
||||||
|
var buff = ip.toBuffer(addr);
|
||||||
|
for (var i = 0; i < buff.length; i++) {
|
||||||
|
buff[i] = 0xff ^ buff[i];
|
||||||
|
}
|
||||||
|
return ip.toString(buff);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.or = function(a, b) {
|
||||||
|
a = ip.toBuffer(a);
|
||||||
|
b = ip.toBuffer(b);
|
||||||
|
|
||||||
|
// same protocol
|
||||||
|
if (a.length === b.length) {
|
||||||
|
for (var i = 0; i < a.length; ++i) {
|
||||||
|
a[i] |= b[i];
|
||||||
|
}
|
||||||
|
return ip.toString(a);
|
||||||
|
|
||||||
|
// mixed protocols
|
||||||
|
} else {
|
||||||
|
var buff = a;
|
||||||
|
var other = b;
|
||||||
|
if (b.length > a.length) {
|
||||||
|
buff = b;
|
||||||
|
other = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = buff.length - other.length;
|
||||||
|
for (var i = offset; i < buff.length; ++i) {
|
||||||
|
buff[i] |= other[i - offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip.toString(buff);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.isEqual = function(a, b) {
|
||||||
|
a = ip.toBuffer(a);
|
||||||
|
b = ip.toBuffer(b);
|
||||||
|
|
||||||
|
// Same protocol
|
||||||
|
if (a.length === b.length) {
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] !== b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap
|
||||||
|
if (b.length === 4) {
|
||||||
|
var t = b;
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a - IPv4, b - IPv6
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
if (b[i] !== 0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var word = b.readUInt16BE(10);
|
||||||
|
if (word !== 0 && word !== 0xffff) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
if (a[i] !== b[i + 12]) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.isPrivate = function(addr) {
|
||||||
|
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i
|
||||||
|
.test(addr) ||
|
||||||
|
/^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||||
|
/^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i
|
||||||
|
.test(addr) ||
|
||||||
|
/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||||
|
/^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||||
|
/^f[cd][0-9a-f]{2}:/i.test(addr) ||
|
||||||
|
/^fe80:/i.test(addr) ||
|
||||||
|
/^::1$/.test(addr) ||
|
||||||
|
/^::$/.test(addr);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.isPublic = function(addr) {
|
||||||
|
return !ip.isPrivate(addr);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.isLoopback = function(addr) {
|
||||||
|
return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/
|
||||||
|
.test(addr) ||
|
||||||
|
/^fe80::1$/.test(addr) ||
|
||||||
|
/^::1$/.test(addr) ||
|
||||||
|
/^::$/.test(addr);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.loopback = function(family) {
|
||||||
|
//
|
||||||
|
// Default to `ipv4`
|
||||||
|
//
|
||||||
|
family = _normalizeFamily(family);
|
||||||
|
|
||||||
|
if (family !== 'ipv4' && family !== 'ipv6') {
|
||||||
|
throw new Error('family must be ipv4 or ipv6');
|
||||||
|
}
|
||||||
|
|
||||||
|
return family === 'ipv4' ? '127.0.0.1' : 'fe80::1';
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// ### function address (name, family)
|
||||||
|
// #### @name {string|'public'|'private'} **Optional** Name or security
|
||||||
|
// of the network interface.
|
||||||
|
// #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults
|
||||||
|
// to ipv4).
|
||||||
|
//
|
||||||
|
// Returns the address for the network interface on the current system with
|
||||||
|
// the specified `name`:
|
||||||
|
// * String: First `family` address of the interface.
|
||||||
|
// If not found see `undefined`.
|
||||||
|
// * 'public': the first public ip address of family.
|
||||||
|
// * 'private': the first private ip address of family.
|
||||||
|
// * undefined: First address with `ipv4` or loopback address `127.0.0.1`.
|
||||||
|
//
|
||||||
|
ip.address = function(name, family) {
|
||||||
|
var os;
|
||||||
|
|
||||||
|
try {
|
||||||
|
os = require('o' + 's');
|
||||||
|
} catch (e) {
|
||||||
|
return '127.0.0.1';
|
||||||
|
}
|
||||||
|
|
||||||
|
var interfaces = os.networkInterfaces();
|
||||||
|
var all;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default to `ipv4`
|
||||||
|
//
|
||||||
|
family = _normalizeFamily(family);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If a specific network interface has been named,
|
||||||
|
// return the address.
|
||||||
|
//
|
||||||
|
if (name && name !== 'private' && name !== 'public') {
|
||||||
|
var res = interfaces[name].filter(function(details) {
|
||||||
|
var itemFamily = details.family.toLowerCase();
|
||||||
|
return itemFamily === family;
|
||||||
|
});
|
||||||
|
if (res.length === 0)
|
||||||
|
return undefined;
|
||||||
|
return res[0].address;
|
||||||
|
}
|
||||||
|
|
||||||
|
var all = Object.keys(interfaces).map(function (nic) {
|
||||||
|
//
|
||||||
|
// Note: name will only be `public` or `private`
|
||||||
|
// when this is called.
|
||||||
|
//
|
||||||
|
var addresses = interfaces[nic].filter(function (details) {
|
||||||
|
details.family = details.family.toLowerCase();
|
||||||
|
if (details.family !== family || ip.isLoopback(details.address)) {
|
||||||
|
return false;
|
||||||
|
} else if (!name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name === 'public' ? ip.isPrivate(details.address) :
|
||||||
|
ip.isPublic(details.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
return addresses.length ? addresses[0].address : undefined;
|
||||||
|
}).filter(Boolean);
|
||||||
|
|
||||||
|
return !all.length ? ip.loopback(family) : all[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.toLong = function(ip) {
|
||||||
|
var ipl = 0;
|
||||||
|
ip.split('.').forEach(function(octet) {
|
||||||
|
ipl <<= 8;
|
||||||
|
ipl += parseInt(octet);
|
||||||
|
});
|
||||||
|
return(ipl >>> 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
ip.fromLong = function(ipl) {
|
||||||
|
return ((ipl >>> 24) + '.' +
|
||||||
|
(ipl >> 16 & 255) + '.' +
|
||||||
|
(ipl >> 8 & 255) + '.' +
|
||||||
|
(ipl & 255) );
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user