/*! * 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;