From fcbcb7bf10393d19fc972d5a6197e4d97a319819 Mon Sep 17 00:00:00 2001 From: Ben Francis Date: Tue, 8 Oct 2024 18:31:58 +0100 Subject: [PATCH] Get IP addresses for Ethernet and Wi-Fi --- src/controllers/settings_controller.ts | 8 +- src/platform.ts | 1 + src/platforms/linux-ubuntu.ts | 126 ++++++++++++++++++++----- 3 files changed, 107 insertions(+), 28 deletions(-) diff --git a/src/controllers/settings_controller.ts b/src/controllers/settings_controller.ts index 9b803fcfb..87269b335 100644 --- a/src/controllers/settings_controller.ts +++ b/src/controllers/settings_controller.ts @@ -22,7 +22,7 @@ import TunnelService from '../tunnel-service'; import * as CertificateManager from '../certificate-manager'; import pkg from '../package.json'; import { HttpErrorWithCode } from '../errors'; -import { LanMode } from '../platforms/types'; +import { LanMode, NetworkAddresses } from '../platforms/types'; function build(): express.Router { const auth = jwtMiddleware.middleware(); @@ -468,7 +468,11 @@ function build(): express.Router { }); controller.get('/network/addresses', auth, (_request, response) => { - if (Platform.implemented('getNetworkAddresses')) { + if (Platform.implemented('getNetworkAddressesAsync')) { + Platform.getNetworkAddressesAsync().then((networkAddresses: NetworkAddresses) => { + response.json(networkAddresses); + }); + } else if (Platform.implemented('getNetworkAddresses')) { response.json(Platform.getNetworkAddresses()); } else { response.status(500).send('Network addresses not implemented'); diff --git a/src/platform.ts b/src/platform.ts index 8d7817dea..6784f4a12 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -211,6 +211,7 @@ export const getMacAddress = wrapPlatform(platform, 'getMacAddres export const getMdnsServerStatus = wrapPlatform(platform, 'getMdnsServerStatus'); export const setMdnsServerStatus = wrapPlatform(platform, 'setMdnsServerStatus'); export const getNetworkAddresses = wrapPlatform(platform, 'getNetworkAddresses'); +export const getNetworkAddressesAsync = wrapPlatform>(platform, 'getNetworkAddressesAsync'); export const getSshServerStatus = wrapPlatform(platform, 'getSshServerStatus'); export const setSshServerStatus = wrapPlatform(platform, 'setSshServerStatus'); export const getWirelessMode = wrapPlatform(platform, 'getWirelessMode'); diff --git a/src/platforms/linux-ubuntu.ts b/src/platforms/linux-ubuntu.ts index 92382c357..c1f9b3bc8 100644 --- a/src/platforms/linux-ubuntu.ts +++ b/src/platforms/linux-ubuntu.ts @@ -8,7 +8,7 @@ import BasePlatform from './base'; import DBus from 'dbus'; -import {LanMode} from './types'; +import {LanMode, NetworkAddresses} from './types'; class LinuxUbuntuPlatform extends BasePlatform { @@ -69,7 +69,7 @@ class LinuxUbuntuPlatform extends BasePlatform { } /** - * Get a list of network Ethernet adapters from the system network manager. + * Get a list of Ethernet network adapters from the system network manager. * * @returns {Promise>} A promise which resolves with an array * of DBus object paths. @@ -88,6 +88,26 @@ class LinuxUbuntuPlatform extends BasePlatform { return ethernetDevices; } + /** + * Get a list of Wi-Fi network adapters from the system network manager. + * + * @returns {Promise>} A promise which resolves with an array + * of DBus object paths. + */ + private async getWifiDevices(): Promise { + // Get a list of all network adapter devices + let devices = await this.getDevices(); + let wifiDevices: string[] = []; + // Filter by type + for (const device of devices) { + const type = await this.getDeviceType(device); + if (type == 2) { + wifiDevices.push(device); + } + } + return wifiDevices; + } + /** * Get the active connection associated with a device. * @@ -159,6 +179,49 @@ class LinuxUbuntuPlatform extends BasePlatform { }); } + /** + * Get an IPv4 configuration for a given device path. + * + * @param {String} path Object path for a device. + * @returns {Promise} Promise resolves with IP4Config object. + */ + private getDeviceIp4Config(path: string): Promise { + const systemBus = this.systemBus; + return new Promise((resolve, reject) => { + systemBus.getInterface('org.freedesktop.NetworkManager', + path, + 'org.freedesktop.NetworkManager.Device', + function(error, iface) { + if (error) { + console.error(error); + reject(); + } + iface.getProperty('Ip4Config', function(error, ip4ConfigPath) { + if (error) { + console.error(error); + reject(); + } + systemBus.getInterface('org.freedesktop.NetworkManager', + ip4ConfigPath, + 'org.freedesktop.NetworkManager.IP4Config', + function(error, iface) { + if (error) { + console.error(error); + reject(); + } + iface.getProperty('AddressData', function(error, value) { + if (error) { + console.error(error); + reject(); + } + resolve(value); + }); + }); + }); + }); + }); + } + /** * Get the LAN mode and options. * @@ -188,34 +251,45 @@ class LinuxUbuntuPlatform extends BasePlatform { }); } - // Currently unused code... - /** - * Get the path to the IPv4 configuration for a given network adapter. + * Get the current addresses for Wi-Fi and LAN. * - * @param {String} path Object path for a device. - * @returns {Promise} Promise resolves with path to configuration object. + * @returns {Promise} Promise that resolves with + * { + * lan: '...', + * wlan: { + * ip: '...', + * ssid: '...', + * } + * } */ - /*getDeviceIp4ConfigPath(path: string) { - return new Promise((resolve, reject) => { - this.systemBus.getInterface('org.freedesktop.NetworkManager', - path, - 'org.freedesktop.NetworkManager.Device', - function(error, iface) { - if (error) { - console.error(error); - reject(); - } - iface.getProperty('Ip4Config', function(error, value) { - if (error) { - console.error(error); - reject(); - } - resolve(value); - }); - }); + async getNetworkAddressesAsync(): Promise { + // TODO: Handle the case where there is no Ethernet adapter or no Wi-Fi + // adapter or one of them isn't assigned an IP + let result: NetworkAddresses = { + lan: '', + wlan: { + ip: '', + ssid: '' + } + }; + return this.getEthernetDevices().then((ethernetDevices) => { + return this.getDeviceIp4Config(ethernetDevices[0]); + }).then((ethernetIp4Config) => { + result.lan = ethernetIp4Config[0].address; + return this.getWifiDevices(); + }).then((wifiDevices) => { + return this.getDeviceIp4Config(wifiDevices[0]); + }).then((wifiIp4Config) => { + result.wlan.ip = wifiIp4Config[0].address; + return result; + }).catch((error) => { + console.error('Error getting IP addresses from NetworkManager: ' + error); + return result; }); - }*/ + } + + // Currently unused code... /** * Get the DHCP configuration for a given network adapter.