Skip to content

webpod/ip

Repository files navigation

@webpod/ip

Lite IP tools

This lib is an alternative for the ip package which resolves many upstream issues.

  • Rewritten in TypeScript
  • Provides both ESM and CJS entries
  • Eliminates annoying vulnerability CVE-2024-29415
  • Brings various fixes and improvements

Install

npm i @webpod/ip

Drop-in

- const ip = require('ip')
+ const ip = require('@webpod/ip')

Temporary workaround to avoid refactoring is using overrides / resolutions in your package.json:

{
  "overrides": {
    "ip": "@webpod/ip"
  }
}

Browser-compatible core build is available as @webpod/ip/core: it omits node:os dependency and polyfills the Buffer API.

Usage

The API is fully compatible with the latest [email protected]

import ip from '@webpod/ip'

// -------------------------------------------------------
// Addresses & formats
// -------------------------------------------------------

ip.address()                              // '192.168.1.50'  (example local address)
ip.isPrivate('127.0.0.1')                 // true
ip.isV4Format('127.0.0.1')                // true
ip.isV6Format('::ffff:127.0.0.1')         // true
ip.isEqual('::1', '::0:1')                // true

// -------------------------------------------------------
// Conversions
// -------------------------------------------------------

ip.toBuffer('127.0.0.1')                  // <Buffer 7f 00 00 01>
ip.toString(Buffer.from([127, 0, 0, 1]))  // '127.0.0.1'

ip.toLong('127.0.0.1')                    // 2130706433
ip.fromLong(2130706433)                   // '127.0.0.1'

ip.fromPrefixLen(24)                      // '255.255.255.0'

// in-place buffer usage
const buf = Buffer.alloc(128)
const offset = 64
ip.toBuffer('127.0.0.1', buf, offset)     // writes [127, 0, 0, 1] at offset 64
ip.toString(buf, offset, 4)               // '127.0.0.1'

// -------------------------------------------------------
// Masking, bitwise, and ranges
// -------------------------------------------------------

ip.mask('192.168.1.134', '255.255.255.0') // '192.168.1.0'
ip.cidr('192.168.1.134/26')               // '192.168.1.128'
ip.not('255.255.255.0')                   // '0.0.0.255'
ip.or('192.168.1.134', '0.0.0.255')       // '192.168.1.255'

// -------------------------------------------------------
// Subnets
// -------------------------------------------------------

ip.subnet('192.168.1.134', '255.255.255.192')
/*
{
  networkAddress:   '192.168.1.128',
  firstAddress:     '192.168.1.129',
  lastAddress:      '192.168.1.190',
  broadcastAddress: '192.168.1.191',
  subnetMask:       '255.255.255.192',
  subnetMaskLength: 26,
  numHosts:         62,
  length:           64,
  contains: [Function: contains]
}
*/

ip.cidrSubnet('192.168.1.134/26').contains('192.168.1.190') // true

Address class

import { Address } from '@webpod/ip'

// -------------------------------------------------------
// Prototype methods
// -------------------------------------------------------

const addr4 = Address.from('192.168.1.134')

addr4.family        // 4
addr4.big           // 323223590n
addr4.toString()    // '192.168.1.134'
addr4.toLong()      // 323223590
addr4.toBuffer()    // <Buffer c0 a8 01 86>
addr4.toArray()     // [192, 168, 1, 134]

const addr6 = Address.from('::1')

addr6.family        // 6
addr6.big           // 1n
addr6.toString()    // '::1'
addr6.toString(4)   // '0.0.0.1'

// -------------------------------------------------------
// Specific ranges check
// -------------------------------------------------------

Address.isSpecial('127.0.0.1')                    // true
Address.isSpecial('127.0.0.1', 'loopback')        // true
Address.isSpecial('127.0.0.1', 'documentation')   // false

Address.isSpecial('1.2.3.4')                      // false

License

MIT