Network   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 12
c 1
b 1
f 0
lcom 1
cbo 0
dl 0
loc 79
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getRange() 0 18 4
A getIPv4Range() 0 19 3
B getIPv6Range() 0 29 4
A convertBinaryToPrintable() 0 4 1
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2015 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace SpomkyLabs\IpFilterBundle\Tool;
13
14
class Network
15
{
16
    public static function getRange($network)
17
    {
18
        try {
19
            list($ip, $cidr) = explode('/', $network);
20
        } catch (\Exception $e) {
21
            throw new \Exception('Invalid IP/CIDR combination supplied');
22
        }
23
24
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
25
            return self::getIPv4Range($ip, $cidr);
26
        }
27
28
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
29
            return self::getIPv6Range($ip, $cidr);
30
        }
31
32
        throw new \Exception('Invalid IP/CIDR combination supplied');
33
    }
34
35
    protected static function getIPv4Range($ip, $cidr)
36
    {
37
        if ($cidr < 0 || $cidr > 32) {
38
            throw new \Exception('Invalid network, IPv4 CIDR must be between 0 and 32.');
39
        }
40
41
        $ipLong = ip2long($ip);
42
        $ipMaskLong = bindec(str_repeat('1', $cidr).str_repeat('0', 32 - $cidr));
43
        $network = $ipLong & $ipMaskLong;
44
        $broadcast = $ipLong | ~$ipMaskLong;
45
46
        return [
47
            'start'     => long2ip($network + 1),
48
            'end'       => long2ip($broadcast - 1),
49
            'network'   => long2ip($network),
50
            'mask'      => long2ip($ipMaskLong),
51
            'broadcast' => long2ip($broadcast),
52
        ];
53
    }
54
55
    protected static function getIPv6Range($ip, $cidr)
56
    {
57
        if ($cidr < 0 || $cidr > 128) {
58
            throw new \Exception('Invalid network, IPv6 CIDR must be between 0 and 128.');
59
        }
60
61
        $hosts = 128 - $cidr;
62
        $networks = 128 - $hosts;
63
64
        $_m = str_repeat('1', $networks).str_repeat('0', $hosts);
65
66
        $_hexMask = '';
67
        foreach (str_split($_m, 4) as $segment) {
68
            $_hexMask .= base_convert($segment, 2, 16);
69
        }
70
71
        $mask = substr(preg_replace('/([A-f0-9]{4})/', '$1:', $_hexMask), 0, -1);
72
73
        $ip_bin = inet_pton($ip);
74
        $mask_bin = inet_pton($mask);
75
76
        $network = $ip_bin & $mask_bin;
77
        $broadcast = $ip_bin | ~$mask_bin;
78
79
        return [
80
            'start' => self::convertBinaryToPrintable($network),
81
            'end'   => self::convertBinaryToPrintable($broadcast),
82
        ];
83
    }
84
85
    /**
86
     * @param string $str
87
     */
88
    protected static function convertBinaryToPrintable($str)
89
    {
90
        return inet_ntop(pack('A'.strlen($str), $str));
91
    }
92
}
93