GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 0f5b77...f26127 )
by François
05:01
created

IP::getAddress()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Copyright 2016 François Kooman <[email protected]>.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace fkooman\VPN\Server;
19
20
use InvalidArgumentException;
21
22
class IP
23
{
24
    /** @var string */
25
    private $ipAddress;
26
27
    /** @var int */
28
    private $ipPrefix;
29
30
    /** @var int */
31
    private $ipFamily;
32
33
    public function __construct($ipAddressPrefix)
34
    {
35
        // detect if there is a prefix
36
        $hasPrefix = false !== strpos($ipAddressPrefix, '/');
37
        if ($hasPrefix) {
38
            list($ipAddress, $ipPrefix) = explode('/', $ipAddressPrefix);
39
        } else {
40
            $ipAddress = $ipAddressPrefix;
41
            $ipPrefix = null;
42
        }
43
44
        // validate the IP address
45
        if (false === filter_var($ipAddress, FILTER_VALIDATE_IP)) {
46
            throw new IPException('invalid IP address');
47
        }
48
49
        $is6 = false !== strpos($ipAddress, ':');
50
        if ($is6) {
51
            if (is_null($ipPrefix)) {
52
                $ipPrefix = 128;
53
            }
54
55 View Code Duplication
            if (!is_numeric($ipPrefix) || 0 > $ipPrefix || 128 < $ipPrefix) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56
                throw new IPException('IP prefix must be a number between 0 and 128');
57
            }
58
            // normalize the IPv6 address
59
            $ipAddress = inet_ntop(inet_pton($ipAddress));
60
        } else {
61
            if (is_null($ipPrefix)) {
62
                $ipPrefix = 32;
63
            }
64 View Code Duplication
            if (!is_numeric($ipPrefix) || 0 > $ipPrefix || 32 < $ipPrefix) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
                throw new IPException('IP prefix must be a number between 0 and 32');
66
            }
67
        }
68
69
        $this->ipAddress = $ipAddress;
70
        $this->ipPrefix = (int) $ipPrefix;
71
        $this->ipFamily = $is6 ? 6 : 4;
72
    }
73
74
    public function getAddress()
75
    {
76
        return $this->ipAddress;
77
    }
78
79
    public function getPrefix()
80
    {
81
        return $this->ipPrefix;
82
    }
83
84
    public function getAddressPrefix()
85
    {
86
        return sprintf('%s/%d', $this->getAddress(), $this->getPrefix());
87
    }
88
89
    public function getFamily()
90
    {
91
        return $this->ipFamily;
92
    }
93
94
    /**
95
     * IPv4 only.
96
     */
97 View Code Duplication
    public function getNetmask()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
    {
99
        if (4 !== $this->getFamily()) {
100
            throw new IPException('method only for IPv4');
101
        }
102
103
        return long2ip(-1 << (32 - $this->getPrefix()));
104
    }
105
106
    /**
107
     * IPv4 only.
108
     */
109
    public function getNetwork()
110
    {
111
        if (4 !== $this->getFamily()) {
112
            throw new IPException('method only for IPv4');
113
        }
114
115
        return long2ip(ip2long($this->getAddress()) & ip2long($this->getNetmask()));
116
    }
117
118
    /**
119
     * IPv4 only.
120
     */
121 View Code Duplication
    public function getNumberOfHosts()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
    {
123
        if (4 !== $this->getFamily()) {
124
            throw new IPException('method only for IPv4');
125
        }
126
127
        return pow(2, 32 - $this->getPrefix()) - 2;
128
    }
129
130
    public function split($networkCount)
131
    {
132
        if (!is_int($networkCount)) {
133
            throw new InvalidArgumentException('parameter must be integer');
134
        }
135
136
        if (0 !== ($networkCount & ($networkCount - 1))) {
137
            throw new InvalidArgumentException('parameter must be power of 2');
138
        }
139
140
        if (4 === $this->getFamily()) {
141
            return $this->split4($networkCount);
142
        }
143
144
        return $this->split6($networkCount);
145
    }
146
147
    private function split4($networkCount)
148
    {
149
        if (30 <= $this->getPrefix()) {
150
            throw new IPException('network too small to split up, must be bigger than /30');
151
        }
152
153
        if (pow(2, 32 - $this->getPrefix() - 2) < $networkCount) {
154
            throw new IPException('network too small to split in this many networks');
155
        }
156
157
        $prefix = $this->getPrefix() + log($networkCount, 2);
158
        $splitRanges = [];
159
        for ($i = 0; $i < $networkCount; ++$i) {
160
            $noHosts = pow(2, 32 - $prefix);
161
            $networkAddress = long2ip($i * $noHosts + ip2long($this->getAddress()));
162
            $splitRanges[] = new self($networkAddress.'/'.$prefix);
163
        }
164
165
        return $splitRanges;
166
    }
167
168
    private function split6($networkCount)
169
    {
170
        if (64 <= $this->getPrefix()) {
171
            throw new IPException('network too small to split up, must be bigger than /64');
172
        }
173
174
        if (0 !== $this->getPrefix() % 4) {
175
            throw new IPException('network prefix length must be divisible by 4');
176
        }
177
178
        if (pow(2, 64 - $this->getPrefix()) < $networkCount) {
179
            throw new IPException('network too small to split in this many networks');
180
        }
181
182
        $hexAddress = bin2hex(inet_pton($this->getAddress()));
183
        // strip the last digits based on prefix size
184
        $hexAddress = substr($hexAddress, 0, 16 - ((64 - $this->getPrefix()) / 4));
185
186
        $splitRanges = [];
187
        for ($i = 0; $i < $networkCount; ++$i) {
188
            // pad with zeros until there is enough space for or network number
189
            $paddedHexAddress = str_pad($hexAddress, 16 - strlen(dechex($i)), '0');
190
            // append the network number
191
            $hexAddressWithNetwork = $paddedHexAddress.dechex($i);
192
            // pad it to the end and convert back to IPv6 address
193
            $splitRanges[] = new self(sprintf('%s/64', inet_ntop(hex2bin(str_pad($hexAddressWithNetwork, 32, '0')))));
194
        }
195
196
        return $splitRanges;
197
    }
198
199
    public function __toString()
200
    {
201
        return $this->getAddressPrefix();
202
    }
203
}
204