Skip to content

Commit

Permalink
feat: use net_get_interfaces to read network adapter
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
  • Loading branch information
kesselb committed Jan 10, 2023
1 parent b6741b0 commit 35c0c25
Show file tree
Hide file tree
Showing 13 changed files with 471 additions and 197 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# PHP Coding Style
vendor/
.php_cs.cache
/.php_cs.cache
/tests/.phpunit.result.cache
/vendor
102 changes: 64 additions & 38 deletions lib/OperatingSystems/DefaultOs.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@

use OCA\ServerInfo\Resources\Disk;
use OCA\ServerInfo\Resources\Memory;
use OCA\ServerInfo\Resources\NetInterface;
use RuntimeException;

class DefaultOs implements IOperatingSystem {
private const AF_INET = 2;
private const AF_INET6 = 10;

public function supported(): bool {
return true;
}
Expand All @@ -36,7 +41,7 @@ public function getMemory(): Memory {

try {
$meminfo = $this->readContent('/proc/meminfo');
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
return $data;
}

Expand Down Expand Up @@ -79,7 +84,7 @@ public function getCpuName(): string {

try {
$cpuinfo = $this->readContent('/proc/cpuinfo');
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
return $data;
}

Expand All @@ -100,7 +105,7 @@ public function getCpuName(): string {

$pattern = '/processor\s+:\s(.+)/';

$result = preg_match_all($pattern, $cpuinfo, $matches);
preg_match_all($pattern, $cpuinfo, $matches);
$cores = count($matches[1]);

if ($cores === 1) {
Expand All @@ -121,7 +126,7 @@ public function getUptime(): int {

try {
$uptime = $this->readContent('/proc/uptime');
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
return $data;
}

Expand All @@ -141,50 +146,55 @@ public function getNetworkInfo(): array {
}

public function getNetworkInterfaces(): array {
$interfaces = glob('/sys/class/net/*') ?: [];
$result = [];
$data = [];

foreach ($interfaces as $interface) {
$iface = [];
$iface['interface'] = basename($interface);
$iface['mac'] = shell_exec('ip addr show dev ' . $iface['interface'] . ' | grep "link/ether " | cut -d \' \' -f 6 | cut -f 1 -d \'/\'');
$iface['ipv4'] = shell_exec('ip addr show dev ' . $iface['interface'] . ' | grep "inet " | cut -d \' \' -f 6 | cut -f 1 -d \'/\'');
$iface['ipv6'] = shell_exec('ip -o -6 addr show ' . $iface['interface'] . ' | sed -e \'s/^.*inet6 \([^ ]\+\).*/\1/\'');
if ($iface['interface'] !== 'lo') {
$iface['status'] = shell_exec('cat /sys/class/net/' . $iface['interface'] . '/operstate');
$iface['speed'] = (int)shell_exec('cat /sys/class/net/' . $iface['interface'] . '/speed');
if (isset($iface['speed']) && $iface['speed'] > 0) {
if ($iface['speed'] >= 1000) {
$iface['speed'] = $iface['speed'] / 1000 . ' Gbps';
} else {
$iface['speed'] = $iface['speed'] . ' Mbps';
}
} else {
$iface['speed'] = 'unknown';
foreach ($this->getNetInterfaces() as $interfaceName => $interface) {
$netInterface = new NetInterface();
$data[] = $netInterface;

$netInterface->setName($interfaceName);
$netInterface->setUp($interface['up']);

foreach ($interface['unicast'] as $unicast) {
if ($unicast['family'] === self::AF_INET) {
$netInterface->addIPv4($unicast['address']);
}
if ($unicast['family'] === self::AF_INET6) {
$netInterface->addIPv6($unicast['address']);
}
$duplex = shell_exec('cat /sys/class/net/' . $iface['interface'] . '/duplex');
if (isset($duplex) && $duplex !== '') {
$iface['duplex'] = 'Duplex: ' . $duplex;
}

if ($netInterface->isLoopback()) {
continue;
}

$interfacePath = '/sys/class/net/' . $interfaceName;

try {
$netInterface->setMAC($this->readContent($interfacePath . '/address'));

$speed = (int)$this->readContent($interfacePath . '/speed');
if ($speed >= 1000) {
$netInterface->setSpeed($speed / 1000 . ' Gbps');
} else {
$iface['duplex'] = '';
$netInterface->setSpeed($speed . ' Mbps');
}
} else {
$iface['status'] = 'up';
$iface['speed'] = 'unknown';
$iface['duplex'] = '';

$netInterface->setDuplex($this->readContent($interfacePath . '/duplex'));
} catch (RuntimeException $e) {
// unable to read interface data
}
$result[] = $iface;
}

return $result;
return $data;
}

public function getDiskInfo(): array {
$data = [];

try {
$disks = $this->executeCommand('df -TPk');
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
return $data;
}

Expand Down Expand Up @@ -227,7 +237,7 @@ public function getThermalZones(): array {
$tzone['hash'] = md5($thermalZone);
$tzone['type'] = $this->readContent($thermalZone . '/type');
$tzone['temp'] = (float)((int)($this->readContent($thermalZone . '/temp')) / 1000);
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
continue;
}
$result[] = $tzone;
Expand All @@ -236,19 +246,35 @@ public function getThermalZones(): array {
return $result;
}

/**
* @throws RuntimeException
*/
protected function readContent(string $filename): string {
$data = @file_get_contents($filename);
if ($data === false || $data === '') {
throw new \RuntimeException('Unable to read: "' . $filename . '"');
throw new RuntimeException('Unable to read: "' . $filename . '"');
}
return $data;
return trim($data);
}

protected function executeCommand(string $command): string {
$output = @shell_exec(escapeshellcmd($command));
if ($output === false || $output === null || $output === '') {
throw new \RuntimeException('No output for command: "' . $command . '"');
throw new RuntimeException('No output for command: "' . $command . '"');
}
return $output;
}

/**
* Wrapper for net_get_interfaces
*
* @throws RuntimeException
*/
protected function getNetInterfaces(): array {
$data = net_get_interfaces();
if ($data === false) {
throw new RuntimeException('Unable to get network interfaces');
}
return $data;
}
}
Loading

0 comments on commit 35c0c25

Please sign in to comment.