Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the ramsey/uuid library
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
10
 * @license http://opensource.org/licenses/MIT MIT
11
 */
12
 
13
declare(strict_types=1);
14
 
15
namespace Ramsey\Uuid\Provider\Node;
16
 
17
use Ramsey\Uuid\Exception\NodeException;
18
use Ramsey\Uuid\Provider\NodeProviderInterface;
19
use Ramsey\Uuid\Type\Hexadecimal;
20
 
21
use function array_filter;
22
use function array_map;
23
use function array_walk;
24
use function count;
25
use function ob_get_clean;
26
use function ob_start;
27
use function preg_match;
28
use function preg_match_all;
29
use function reset;
30
use function str_contains;
31
use function str_replace;
32
use function strtolower;
33
use function strtoupper;
34
use function substr;
35
 
36
use const GLOB_NOSORT;
37
use const PREG_PATTERN_ORDER;
38
 
39
/**
40
 * SystemNodeProvider retrieves the system node ID, if possible
41
 *
42
 * The system node ID, or host ID, is often the same as the MAC address for a
43
 * network interface on the host.
44
 */
45
class SystemNodeProvider implements NodeProviderInterface
46
{
47
    /**
48
     * Pattern to match nodes in ifconfig and ipconfig output.
49
     */
50
    private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i';
51
 
52
    /**
53
     * Pattern to match nodes in sysfs stream output.
54
     */
55
    private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i';
56
 
57
    public function getNode(): Hexadecimal
58
    {
59
        $node = $this->getNodeFromSystem();
60
 
61
        if ($node === '') {
62
            throw new NodeException(
63
                'Unable to fetch a node for this system'
64
            );
65
        }
66
 
67
        return new Hexadecimal($node);
68
    }
69
 
70
    /**
71
     * Returns the system node, if it can find it
72
     */
73
    protected function getNodeFromSystem(): string
74
    {
75
        static $node = null;
76
 
77
        if ($node !== null) {
78
            return (string) $node;
79
        }
80
 
81
        // First, try a Linux-specific approach.
82
        $node = $this->getSysfs();
83
 
84
        if ($node === '') {
85
            // Search ifconfig output for MAC addresses & return the first one.
86
            $node = $this->getIfconfig();
87
        }
88
 
89
        $node = str_replace([':', '-'], '', $node);
90
 
91
        return $node;
92
    }
93
 
94
    /**
95
     * Returns the network interface configuration for the system
96
     *
97
     * @codeCoverageIgnore
98
     */
99
    protected function getIfconfig(): string
100
    {
101
        $disabledFunctions = strtolower((string) ini_get('disable_functions'));
102
 
103
        if (str_contains($disabledFunctions, 'passthru')) {
104
            return '';
105
        }
106
 
107
        /**
108
         * @psalm-suppress UnnecessaryVarAnnotation
109
         * @var string $phpOs
110
         */
111
        $phpOs = constant('PHP_OS');
112
 
113
        ob_start();
114
        switch (strtoupper(substr($phpOs, 0, 3))) {
115
            case 'WIN':
116
                passthru('ipconfig /all 2>&1');
117
 
118
                break;
119
            case 'DAR':
120
                passthru('ifconfig 2>&1');
121
 
122
                break;
123
            case 'FRE':
124
                passthru('netstat -i -f link 2>&1');
125
 
126
                break;
127
            case 'LIN':
128
            default:
129
                passthru('netstat -ie 2>&1');
130
 
131
                break;
132
        }
133
 
134
        $ifconfig = (string) ob_get_clean();
135
 
136
        if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) {
137
            foreach ($matches[1] as $iface) {
138
                if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') {
139
                    return $iface;
140
                }
141
            }
142
        }
143
 
144
        return '';
145
    }
146
 
147
    /**
148
     * Returns MAC address from the first system interface via the sysfs interface
149
     */
150
    protected function getSysfs(): string
151
    {
152
        $mac = '';
153
 
154
        /**
155
         * @psalm-suppress UnnecessaryVarAnnotation
156
         * @var string $phpOs
157
         */
158
        $phpOs = constant('PHP_OS');
159
 
160
        if (strtoupper($phpOs) === 'LINUX') {
161
            $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT);
162
 
163
            if ($addressPaths === false || count($addressPaths) === 0) {
164
                return '';
165
            }
166
 
167
            /** @var array<array-key, string> $macs */
168
            $macs = [];
169
 
170
            array_walk($addressPaths, function (string $addressPath) use (&$macs): void {
171
                if (is_readable($addressPath)) {
172
                    $macs[] = file_get_contents($addressPath);
173
                }
174
            });
175
 
176
            /** @var callable $trim */
177
            $trim = 'trim';
178
 
179
            $macs = array_map($trim, $macs);
180
 
181
            // Remove invalid entries.
182
            $macs = array_filter($macs, function (string $address) {
183
                return $address !== '00:00:00:00:00:00'
184
                    && preg_match(self::SYSFS_PATTERN, $address);
185
            });
186
 
187
            /** @var string|bool $mac */
188
            $mac = reset($macs);
189
        }
190
 
191
        return (string) $mac;
192
    }
193
}