diff --git a/packages/utils/package.json b/packages/utils/package.json index 66c5160083..feb753eb82 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -84,6 +84,10 @@ "types": "./dist/src/is-promise.d.ts", "import": "./dist/src/is-promise.js" }, + "./link-local-ip": { + "types": "./dist/src/link-local-ip.d.ts", + "import": "./dist/src/link-local-ip.js" + }, "./moving-average": { "types": "./dist/src/moving-average.d.ts", "import": "./dist/src/moving-average.js" diff --git a/packages/utils/src/link-local-ip.ts b/packages/utils/src/link-local-ip.ts new file mode 100644 index 0000000000..e5a64a8e52 --- /dev/null +++ b/packages/utils/src/link-local-ip.ts @@ -0,0 +1,13 @@ +import { isIPv4, isIPv6 } from '@chainsafe/is-ip' + +export function isLinkLocalIp (ip: string): boolean { + if (isIPv4(ip)) { + return ip.startsWith('169.254.') + } + + if (isIPv6(ip)) { + return ip.toLowerCase().startsWith('fe80') + } + + return false +} diff --git a/packages/utils/test/link-local-ip.spec.ts b/packages/utils/test/link-local-ip.spec.ts new file mode 100644 index 0000000000..66b9c7e94d --- /dev/null +++ b/packages/utils/test/link-local-ip.spec.ts @@ -0,0 +1,58 @@ +/* eslint-env mocha */ + +import { expect } from 'aegir/chai' +import { isLinkLocalIp } from '../src/link-local-ip.js' + +describe('isLinkLocalIp', () => { + it('identifies link-local ip4 multiaddrs', () => { + [ + '169.254.35.4', + '169.254.35.4', + '169.254.0.0', + '169.254.255.255' + ].forEach(ma => { + expect(isLinkLocalIp(ma)).to.be.true() + }) + }) + + it('identifies non link-local ip4 multiaddrs', () => { + [ + '101.0.26.90', + '10.0.0.1', + '192.168.0.1', + '172.16.0.1' + ].forEach(ma => { + expect(isLinkLocalIp(ma)).to.be.false() + }) + }) + + it('identifies link-local ip6 multiaddrs', () => { + [ + 'fe80::1%lo0', + 'fe80::1%lo0', + 'fe80::1893:def4:af04:635a%en', + 'fe80::1893:def4:af04:635a', + 'fe80::1893:def4:af04:635a' + ].forEach(ma => { + expect(isLinkLocalIp(ma)).to.be.true() + }) + }) + + it('identifies non link-local ip6 multiaddrs', () => { + [ + '2001:8a0:7ac5:4201:3ac9:86ff:fe31', + '::' + ].forEach(ma => { + expect(isLinkLocalIp(ma)).to.be.false() + }) + }) + + it('identifies other multiaddrs as not link-local addresses', () => { + [ + 'wss0.bootstrap.libp2p.io', + 'wss0.bootstrap.libp2p.io' + ].forEach(ma => { + expect(isLinkLocalIp(ma)).to.be.false() + }) + }) +})