Viewing file: SystemNodeProvider.php (4.89 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * This file is part of the ramsey/uuid library * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT */
declare(strict_types=1);
namespace Ramsey\Uuid\Provider\Node;
use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal;
use function array_filter; use function array_map; use function array_walk; use function count; use function ob_get_clean; use function ob_start; use function preg_match; use function preg_match_all; use function reset; use function str_contains; use function str_replace; use function strtolower; use function strtoupper; use function substr;
use const GLOB_NOSORT; use const PREG_PATTERN_ORDER;
/** * SystemNodeProvider retrieves the system node ID, if possible * * The system node ID, or host ID, is often the same as the MAC address for a * network interface on the host. */ class SystemNodeProvider implements NodeProviderInterface { /** * Pattern to match nodes in ifconfig and ipconfig output. */ private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i';
/** * Pattern to match nodes in sysfs stream output. */ private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i';
public function getNode(): Hexadecimal { $node = $this->getNodeFromSystem();
if ($node === '') { throw new NodeException( 'Unable to fetch a node for this system' ); }
return new Hexadecimal($node); }
/** * Returns the system node, if it can find it */ protected function getNodeFromSystem(): string { static $node = null;
if ($node !== null) { return (string) $node; }
// First, try a Linux-specific approach. $node = $this->getSysfs();
if ($node === '') { // Search ifconfig output for MAC addresses & return the first one. $node = $this->getIfconfig(); }
$node = str_replace([':', '-'], '', $node);
return $node; }
/** * Returns the network interface configuration for the system * * @codeCoverageIgnore */ protected function getIfconfig(): string { $disabledFunctions = strtolower((string) ini_get('disable_functions'));
if (str_contains($disabledFunctions, 'passthru')) { return ''; }
/** * @psalm-suppress UnnecessaryVarAnnotation * @var string $phpOs */ $phpOs = constant('PHP_OS');
ob_start(); switch (strtoupper(substr($phpOs, 0, 3))) { case 'WIN': passthru('ipconfig /all 2>&1');
break; case 'DAR': passthru('ifconfig 2>&1');
break; case 'FRE': passthru('netstat -i -f link 2>&1');
break; case 'LIN': default: passthru('netstat -ie 2>&1');
break; }
$ifconfig = (string) ob_get_clean();
if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) { foreach ($matches[1] as $iface) { if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') { return $iface; } } }
return ''; }
/** * Returns MAC address from the first system interface via the sysfs interface */ protected function getSysfs(): string { $mac = '';
/** * @psalm-suppress UnnecessaryVarAnnotation * @var string $phpOs */ $phpOs = constant('PHP_OS');
if (strtoupper($phpOs) === 'LINUX') { $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT);
if ($addressPaths === false || count($addressPaths) === 0) { return ''; }
/** @var array<array-key, string> $macs */ $macs = [];
array_walk($addressPaths, function (string $addressPath) use (&$macs): void { if (is_readable($addressPath)) { $macs[] = file_get_contents($addressPath); } });
/** @var callable $trim */ $trim = 'trim';
$macs = array_map($trim, $macs);
// Remove invalid entries. $macs = array_filter($macs, function (string $address) { return $address !== '00:00:00:00:00:00' && preg_match(self::SYSFS_PATTERN, $address); });
/** @var string|bool $mac */ $mac = reset($macs); }
return (string) $mac; } }
|