diff --git a/src/network.ts b/src/network.ts index bbc9f047..6201843a 100644 --- a/src/network.ts +++ b/src/network.ts @@ -120,6 +120,12 @@ const IP_REGEX = /^(?:(?:balena|docker|rce|tun)[0-9]+|tun[0-9]+|resin-vpn|lo|res export const shouldReportInterface = (intf: string) => !IP_REGEX.test(intf); +const shouldReportIPv6 = (ip: os.NetworkInterfaceInfo) => + ip.family === 'IPv6' && !ip.internal && ip.scopeid === 0; + +const shouldReportIPv4 = (ip: os.NetworkInterfaceInfo) => + ip.family === 'IPv4' && !ip.internal; + export function getIPAddresses(): string[] { // We get IP addresses but ignore: // - docker and balena bridges (docker0, docker1, balena0, etc) @@ -130,17 +136,18 @@ export function getIPAddresses(): string[] { // - the bridge for dnsmasq (resin-dns) // - the docker network for the supervisor API (supervisor0) // - custom docker network bridges (br- + 12 hex characters) - return _(os.networkInterfaces()) - .filter((_interfaceFields, interfaceName) => - shouldReportInterface(interfaceName), - ) + const networkInterfaces = os.networkInterfaces(); + return Object.keys(networkInterfaces) + .filter((iface) => shouldReportInterface(iface)) + .map((iface) => networkInterfaces[iface]) .flatMap((validInterfaces) => { - return _(validInterfaces) - .pickBy({ family: 'IPv4', internal: false }) - .map('address') - .value(); - }) - .value(); + return ( + validInterfaces + // Only report valid ipv6 and ipv4 addresses + .filter((ip) => shouldReportIPv6(ip) || shouldReportIPv4(ip)) + .map(({ address }) => address) + ); + }); } export function startIPAddressUpdate(): ( diff --git a/test/09-network.spec.ts b/test/09-network.spec.ts index 6fa6d6a8..9bf4cf95 100644 --- a/test/09-network.spec.ts +++ b/test/09-network.spec.ts @@ -61,6 +61,16 @@ describe('network', () => { internal: false, }, ], + eth0: [ + { + address: 'fe80::9992:76e3:c2e1:8a02', + netmask: 'ffff:ffff:ffff:ffff::', + family: 'IPv6', + mac: '58:6d:c7:c6:44:3d', + scopeid: 9, + internal: false, + }, + ], 'resin-vpn': [ { address: '10.10.2.14', @@ -77,7 +87,10 @@ describe('network', () => { after(() => os.networkInterfaces.restore()); it('returns only the relevant IP addresses', () => - expect(network.getIPAddresses()).to.deep.equal(['192.168.1.137'])); + expect(network.getIPAddresses()).to.deep.equal([ + '192.168.1.137', + '2605:9080:1103:3011:2dbe:35e3:1b5a:b99', + ])); }); it('checks VPN connection status', async () => {