JAVASCRIPT 27
Ip.js Guest on 20th April 2021 04:50:58 PM
  1. 'use strict';
  2.  
  3. var ip = exports;
  4. var Buffer = require('buffer').Buffer;
  5. var os = require('os');
  6.  
  7. ip.toBuffer = function(ip, buff, offset) {
  8.   offset = ~~offset;
  9.  
  10.   var result;
  11.  
  12.   if (this.isV4Format(ip)) {
  13.     result = buff || new Buffer(offset + 4);
  14.     ip.split(/\./g).map(function(byte) {
  15.       result[offset++] = parseInt(byte, 10) & 0xff;
  16.     });
  17.   } else if (this.isV6Format(ip)) {
  18.     var sections = ip.split(':', 8);
  19.  
  20.     var i;
  21.     for (i = 0; i < sections.length; i++) {
  22.       var isv4 = this.isV4Format(sections[i]);
  23.       var v4Buffer;
  24.  
  25.       if (isv4) {
  26.         v4Buffer = this.toBuffer(sections[i]);
  27.         sections[i] = v4Buffer.slice(0, 2).toString('hex');
  28.       }
  29.  
  30.       if (v4Buffer && ++i < 8) {
  31.         sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex'));
  32.       }
  33.     }
  34.  
  35.     if (sections[0] === '') {
  36.       while (sections.length < 8) sections.unshift('0');
  37.     } else if (sections[sections.length - 1] === '') {
  38.       while (sections.length < 8) sections.push('0');
  39.     } else if (sections.length < 8) {
  40.       for (i = 0; i < sections.length && sections[i] !== ''; i++);
  41.       var argv = [ i, 1 ];
  42.       for (i = 9 - sections.length; i > 0; i--) {
  43.         argv.push('0');
  44.       }
  45.       sections.splice.apply(sections, argv);
  46.     }
  47.  
  48.     result = buff || new Buffer(offset + 16);
  49.     for (i = 0; i < sections.length; i++) {
  50.       var word = parseInt(sections[i], 16);
  51.       result[offset++] = (word >> 8) & 0xff;
  52.       result[offset++] = word & 0xff;
  53.     }
  54.   }
  55.  
  56.   if (!result) {
  57.     throw Error('Invalid ip address: ' + ip);
  58.   }
  59.  
  60.   return result;
  61. };
  62.  
  63. ip.toString = function(buff, offset, length) {
  64.   offset = ~~offset;
  65.   length = length || (buff.length - offset);
  66.  
  67.   var result = [];
  68.   if (length === 4) {
  69.     // IPv4
  70.     for (var i = 0; i < length; i++) {
  71.       result.push(buff[offset + i]);
  72.     }
  73.     result = result.join('.');
  74.   } else if (length === 16) {
  75.     // IPv6
  76.     for (var i = 0; i < length; i += 2) {
  77.       result.push(buff.readUInt16BE(offset + i).toString(16));
  78.     }
  79.     result = result.join(':');
  80.     result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');
  81.     result = result.replace(/:{3,4}/, '::');
  82.   }
  83.  
  84.   return result;
  85. };
  86.  
  87. var ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/;
  88. var ipv6Regex =
  89.     /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;
  90.  
  91. ip.isV4Format = function(ip) {
  92.   return ipv4Regex.test(ip);
  93. };
  94.  
  95. ip.isV6Format = function(ip) {
  96.   return ipv6Regex.test(ip);
  97. };
  98. function _normalizeFamily(family) {
  99.   return family ? family.toLowerCase() : 'ipv4';
  100. }
  101.  
  102. ip.fromPrefixLen = function(prefixlen, family) {
  103.   if (prefixlen > 32) {
  104.     family = 'ipv6';
  105.   } else {
  106.     family = _normalizeFamily(family);
  107.   }
  108.  
  109.   var len = 4;
  110.   if (family === 'ipv6') {
  111.     len = 16;
  112.   }
  113.   var buff = new Buffer(len);
  114.  
  115.   for (var i = 0, n = buff.length; i < n; ++i) {
  116.     var bits = 8;
  117.     if (prefixlen < 8) {
  118.       bits = prefixlen;
  119.     }
  120.     prefixlen -= bits;
  121.  
  122.     buff[i] = ~(0xff >> bits) & 0xff;
  123.   }
  124.  
  125.   return ip.toString(buff);
  126. };
  127.  
  128. ip.mask = function(addr, mask) {
  129.   addr = ip.toBuffer(addr);
  130.   mask = ip.toBuffer(mask);
  131.  
  132.   var result = new Buffer(Math.max(addr.length, mask.length));
  133.  
  134.   var i = 0;
  135.   // Same protocol - do bitwise and
  136.   if (addr.length === mask.length) {
  137.     for (i = 0; i < addr.length; i++) {
  138.       result[i] = addr[i] & mask[i];
  139.     }
  140.   } else if (mask.length === 4) {
  141.     // IPv6 address and IPv4 mask
  142.     // (Mask low bits)
  143.     for (i = 0; i < mask.length; i++) {
  144.       result[i] = addr[addr.length - 4  + i] & mask[i];
  145.     }
  146.   } else {
  147.     // IPv6 mask and IPv4 addr
  148.     for (var i = 0; i < result.length - 6; i++) {
  149.       result[i] = 0;
  150.     }
  151.  
  152.     // ::ffff:ipv4
  153.     result[10] = 0xff;
  154.     result[11] = 0xff;
  155.     for (i = 0; i < addr.length; i++) {
  156.       result[i + 12] = addr[i] & mask[i + 12];
  157.     }
  158.     i = i + 12;
  159.   }
  160.   for (; i < result.length; i++)
  161.     result[i] = 0;
  162.  
  163.   return ip.toString(result);
  164. };
  165.  
  166. ip.cidr = function(cidrString) {
  167.   var cidrParts = cidrString.split('/');
  168.  
  169.   var addr = cidrParts[0];
  170.   if (cidrParts.length !== 2)
  171.     throw new Error('invalid CIDR subnet: ' + addr);
  172.  
  173.   var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
  174.  
  175.   return ip.mask(addr, mask);
  176. };
  177.  
  178. ip.subnet = function(addr, mask) {
  179.   var networkAddress = ip.toLong(ip.mask(addr, mask));
  180.  
  181.   // Calculate the mask's length.
  182.   var maskBuffer = ip.toBuffer(mask);
  183.   var maskLength = 0;
  184.  
  185.   for (var i = 0; i < maskBuffer.length; i++) {
  186.     if (maskBuffer[i] === 0xff) {
  187.       maskLength += 8;
  188.     } else {
  189.       var octet = maskBuffer[i] & 0xff;
  190.       while (octet) {
  191.         octet = (octet << 1) & 0xff;
  192.         maskLength++;
  193.       }
  194.     }
  195.   }
  196.  
  197.   var numberOfAddresses = Math.pow(2, 32 - maskLength);
  198.  
  199.   return {
  200.     networkAddress: ip.fromLong(networkAddress),
  201.     firstAddress: numberOfAddresses <= 2 ?
  202.                     ip.fromLong(networkAddress) :
  203.                     ip.fromLong(networkAddress + 1),
  204.     lastAddress: numberOfAddresses <= 2 ?
  205.                     ip.fromLong(networkAddress + numberOfAddresses - 1) :
  206.                     ip.fromLong(networkAddress + numberOfAddresses - 2),
  207.     broadcastAddress: ip.fromLong(networkAddress + numberOfAddresses - 1),
  208.     subnetMask: mask,
  209.     subnetMaskLength: maskLength,
  210.     numHosts: numberOfAddresses <= 2 ?
  211.                 numberOfAddresses : numberOfAddresses - 2,
  212.     length: numberOfAddresses,
  213.     contains: function(other) {
  214.       return networkAddress === ip.toLong(ip.mask(other, mask));
  215.     }
  216.   };
  217. };
  218.  
  219. ip.cidrSubnet = function(cidrString) {
  220.   var cidrParts = cidrString.split('/');
  221.  
  222.   var addr = cidrParts[0];
  223.   if (cidrParts.length !== 2)
  224.     throw new Error('invalid CIDR subnet: ' + addr);
  225.  
  226.   var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
  227.  
  228.   return ip.subnet(addr, mask);
  229. };
  230.  
  231. ip.not = function(addr) {
  232.   var buff = ip.toBuffer(addr);
  233.   for (var i = 0; i < buff.length; i++) {
  234.     buff[i] = 0xff ^ buff[i];
  235.   }
  236.   return ip.toString(buff);
  237. };
  238.  
  239. ip.or = function(a, b) {
  240.   a = ip.toBuffer(a);
  241.   b = ip.toBuffer(b);
  242.  
  243.   // same protocol
  244.   if (a.length === b.length) {
  245.     for (var i = 0; i < a.length; ++i) {
  246.       a[i] |= b[i];
  247.     }
  248.     return ip.toString(a);
  249.  
  250.   // mixed protocols
  251.   } else {
  252.     var buff = a;
  253.     var other = b;
  254.     if (b.length > a.length) {
  255.       buff = b;
  256.       other = a;
  257.     }
  258.  
  259.     var offset = buff.length - other.length;
  260.     for (var i = offset; i < buff.length; ++i) {
  261.       buff[i] |= other[i - offset];
  262.     }
  263.  
  264.     return ip.toString(buff);
  265.   }
  266. };
  267.  
  268. ip.isEqual = function(a, b) {
  269.   a = ip.toBuffer(a);
  270.   b = ip.toBuffer(b);
  271.  
  272.   // Same protocol
  273.   if (a.length === b.length) {
  274.     for (var i = 0; i < a.length; i++) {
  275.       if (a[i] !== b[i]) return false;
  276.     }
  277.     return true;
  278.   }
  279.  
  280.   // Swap
  281.   if (b.length === 4) {
  282.     var t = b;
  283.     b = a;
  284.     a = t;
  285.   }
  286.  
  287.   // a - IPv4, b - IPv6
  288.   for (var i = 0; i < 10; i++) {
  289.     if (b[i] !== 0) return false;
  290.   }
  291.  
  292.   var word = b.readUInt16BE(10);
  293.   if (word !== 0 && word !== 0xffff) return false;
  294.  
  295.   for (var i = 0; i < 4; i++) {
  296.     if (a[i] !== b[i + 12]) return false;
  297.   }
  298.  
  299.   return true;
  300. };
  301.  
  302. ip.isPrivate = function(addr) {
  303.   return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i
  304.       .test(addr) ||
  305.     /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
  306.     /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i
  307.       .test(addr) ||
  308.     /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
  309.     /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
  310.     /^f[cd][0-9a-f]{2}:/i.test(addr) ||
  311.     /^fe80:/i.test(addr) ||
  312.     /^::1$/.test(addr) ||
  313.     /^::$/.test(addr);
  314. };
  315.  
  316. ip.isPublic = function(addr) {
  317.   return !ip.isPrivate(addr);
  318. };
  319.  
  320. ip.isLoopback = function(addr) {
  321.   return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/
  322.       .test(addr) ||
  323.     /^fe80::1$/.test(addr) ||
  324.     /^::1$/.test(addr) ||
  325.     /^::$/.test(addr);
  326. };
  327.  
  328. ip.loopback = function(family) {
  329.   //
  330.   // Default to `ipv4`
  331.   //
  332.   family = _normalizeFamily(family);
  333.  
  334.   if (family !== 'ipv4' && family !== 'ipv6') {
  335.     throw new Error('family must be ipv4 or ipv6');
  336.   }
  337.  
  338.   return family === 'ipv4' ? '127.0.0.1' : 'fe80::1';
  339. };
  340.  
  341. //
  342. // ### function address (name, family)
  343. // #### @name {string|'public'|'private'} **Optional** Name or security
  344. //      of the network interface.
  345. // #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults
  346. //      to ipv4).
  347. //
  348. // Returns the address for the network interface on the current system with
  349. // the specified `name`:
  350. //   * String: First `family` address of the interface.
  351. //             If not found see `undefined`.
  352. //   * 'public': the first public ip address of family.
  353. //   * 'private': the first private ip address of family.
  354. //   * undefined: First address with `ipv4` or loopback address `127.0.0.1`.
  355. //
  356. ip.address = function(name, family) {
  357.   var interfaces = os.networkInterfaces();
  358.   var all;
  359.  
  360.   //
  361.   // Default to `ipv4`
  362.   //
  363.   family = _normalizeFamily(family);
  364.  
  365.   //
  366.   // If a specific network interface has been named,
  367.   // return the address.
  368.   //
  369.   if (name && name !== 'private' && name !== 'public') {
  370.     var res = interfaces[name].filter(function(details) {
  371.       var itemFamily = details.family.toLowerCase();
  372.       return itemFamily === family;
  373.     });
  374.     if (res.length === 0)
  375.       return undefined;
  376.     return res[0].address;
  377.   }
  378.  
  379.   var all = Object.keys(interfaces).map(function (nic) {
  380.     //
  381.     // Note: name will only be `public` or `private`
  382.     // when this is called.
  383.     //
  384.     var addresses = interfaces[nic].filter(function (details) {
  385.       details.family = details.family.toLowerCase();
  386.       if (details.family !== family || ip.isLoopback(details.address)) {
  387.         return false;
  388.       } else if (!name) {
  389.         return true;
  390.       }
  391.  
  392.       return name === 'public' ? ip.isPrivate(details.address) :
  393.           ip.isPublic(details.address);
  394.     });
  395.  
  396.     return addresses.length ? addresses[0].address : undefined;
  397.   }).filter(Boolean);
  398.  
  399.   return !all.length ? ip.loopback(family) : all[0];
  400. };
  401.  
  402. ip.toLong = function(ip) {
  403.   var ipl = 0;
  404.   ip.split('.').forEach(function(octet) {
  405.     ipl <<= 8;
  406.     ipl += parseInt(octet);
  407.   });
  408.   return(ipl >>> 0);
  409. };
  410.  
  411. ip.fromLong = function(ipl) {
  412.   return ((ipl >>> 24) + '.' +
  413.       (ipl >> 16 & 255) + '.' +
  414.       (ipl >> 8 & 255) + '.' +
  415.       (ipl & 255) );
  416. };

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.