fcoin/lib/utils/ip.js
2016-08-25 19:30:56 -07:00

207 lines
3.8 KiB
JavaScript

/*!
* ip.js - ip utils for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
var IP = require('../../vendor/ip');
var assert = require('assert');
/**
* Parse a hostname.
* @example
* IP.parseHost('127.0.0.1:3000');
* @param {String} addr
* @returns {Object} Contains `host` and `port`.
*/
exports.parseHost = function parseHost(addr) {
var parts, host, port;
assert(addr);
if (typeof addr === 'object')
return addr;
if (addr[0] === '[') {
addr = addr.substring(1);
parts = addr.split(/\]:?/);
assert(parts.length === 2);
} else {
parts = addr.split(':');
}
host = parts[0];
port = +parts[1] || 0;
if (exports.version(host) !== -1)
host = exports.normalize(host);
return {
host: host,
port: port
};
};
/**
* Concatenate a host and port.
* @param {String} host
* @param {Number} port
* @returns {String}
*/
exports.hostname = function hostname(host, port) {
var version = exports.version(host);
if (version !== -1)
host = exports.normalize(host);
if (version === 6)
host = '[' + host + ']';
return host + ':' + port;
};
/**
* Test whether a string is an IP address.
* @param {String?} ip
* @returns {Number} IP version (4 or 6).
*/
exports.version = function version(ip) {
if (typeof ip !== 'string')
return -1;
if (IP.isV4Format(ip))
return 4;
if (IP.isV6Format(ip))
return 6;
return -1;
};
/**
* Test whether a buffer is an ipv4-mapped ipv6 address.
* @param {Buffer} ip
* @returns {Boolean}
*/
exports.isMapped = function isMapped(ip) {
var i;
assert(Buffer.isBuffer(ip));
assert(ip.length === 16);
for (i = 0; i < ip.length - 6; i++) {
if (ip[i] !== 0)
return false;
}
if (ip[ip.length - 6] !== 0xff && ip[ip.length - 5] !== 0xff)
return false;
return true;
};
/**
* Convert an IP string to a buffer.
* @param {String} ip
* @returns {Buffer}
*/
exports.toBuffer = function toBuffer(ip) {
var out;
if (Buffer.isBuffer(ip)) {
assert(ip.length === 16);
return ip;
}
if (!ip)
return toBuffer('0.0.0.0');
assert(typeof ip === 'string');
assert(exports.version(ip) !== -1);
ip = IP.toBuffer(ip);
if (ip.length === 4) {
out = new Buffer(16);
out.fill(0);
out[10] = 0xff;
out[11] = 0xff;
out[12] = ip[0];
out[13] = ip[1];
out[14] = ip[2];
out[15] = ip[3];
return out;
}
return ip;
};
/**
* Convert a buffer to an ip string.
* @param {Buffer} ip
* @returns {String}
*/
exports.toString = function toString(ip) {
if (typeof ip === 'string') {
assert(exports.version(ip) !== -1);
return ip;
}
if (!ip)
return '0.0.0.0';
assert(Buffer.isBuffer(ip));
assert(ip.length === 16);
if (exports.isMapped(ip)) {
return ip[ip.length - 4]
+ '.' + ip[ip.length - 3]
+ '.' + ip[ip.length - 2]
+ '.' + ip[ip.length - 1];
}
return IP.toString(ip);
};
/**
* Normalize an ip.
* @param {String} ip
* @returns {String}
*/
exports.normalize = function normalize(ip) {
if (Buffer.isBuffer(ip)) {
assert(ip.length === 16);
return exports.toString(ip);
}
return exports.toString(exports.toBuffer(ip));
};
/*
* Expose IP functions.
*/
exports.isV4Format = IP.isV4Format;
exports.isV6Format = IP.isV6Format;
exports.fromPrefixLen = IP.fromPrefixLen;
exports.mask = IP.mask;
exports.cidr = IP.cidr;
exports.subnet = IP.subnet;
exports.cidrSubnet = IP.cidrSubnet;
exports.not = IP.not;
exports.or = IP.or;
exports.isEqual = IP.isEqual;
exports.isPrivate = IP.isPrivate;
exports.isPublic = IP.isPublic;
exports.isLoopback = IP.isLoopback;
exports.loopback = IP.loopback;
exports.address = IP.address;
exports.toLong = IP.toLong;
exports.fromLong = IP.fromLong;