PTR::expandIpv6()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.074

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 5
cts 6
cp 0.8333
rs 9.6666
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.074
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS\Rdata;
15
16
use Badcow\DNS\Validator;
17
use PhpIP\IPv6;
18
19
/**
20
 * @see https://tools.ietf.org/html/rfc1035#section-3.3.12
21
 */
22
class PTR extends CNAME
23
{
24
    const TYPE = 'PTR';
25
    const TYPE_CODE = 12;
26
27
    /**
28
     * Expands an IPv6 address to its full, non-shorthand representation.
29
     *
30
     * E.g. 2001:db8:9a::42 -> 2001:0db8:009a:0000:0000:0000:0000:0042
31
     *
32
     * @param string $ip IPv6 address
33
     *
34
     * @throws \InvalidArgumentException
35 10
     */
36
    public static function expandIpv6(string $ip): string
37 10
    {
38 2
        $_ip = new IPv6($ip);
0 ignored issues
show
Unused Code introduced by
$_ip is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
39
40
        if (!Validator::ipv6($ip)) {
41 9
            throw new \InvalidArgumentException(sprintf('"%s" is not a valid IPv6 address.', $ip));
42
        }
43
44
        if (false === $packed = inet_pton($ip)) {
45 9
            throw new \InvalidArgumentException(sprintf('"%s" is not a valid IPv6 address.', $ip));
46
        }
47 9
48
        if (false === $hex = unpack('H*hex', $packed)) {
49
            throw new \InvalidArgumentException(sprintf('Could not unpack IP "%s"', $ip));
50
        }
51
52
        return implode(':', str_split($hex['hex'], 4));
53
    }
54
55
    /**
56
     * This function will expand in incomplete IPv6 address.
57
     * An incomplete IPv6 address is of the form `2001:db8:ff:abcd`
58
     * i.e. one where there is less than eight hextets.
59 2
     *
60
     * @param string $ip IPv6 address
61 2
     *
62 2
     * @return string Expanded incomplete IPv6 address
63 2
     */
64
    public static function expandIncompleteIpv6(string $ip): string
65 2
    {
66
        $hextets = array_map(function ($hextet) {
67
            return str_pad($hextet, 4, '0', STR_PAD_LEFT);
68
        }, explode(':', $ip));
69
70
        return implode(':', $hextets);
71
    }
72
73
    /**
74
     * Takes a valid IPv6 address and contracts it
75
     * to its shorter version.
76
     *
77
     * E.g.: 2001:0000:0000:acad:0000:0000:0000:0001 -> 2001:0:0:acad::1
78
     *
79
     * Note: If there is more than one set of consecutive hextets, the function
80
     * will favour the larger of the sets. If both sets of zeroes are the same
81
     * the first will be favoured in the omission of zeroes.
82
     *
83
     * E.g.: 2001:0000:0000:ab80:2390:0000:0000:000a -> 2001:0:0:ab80:2390::a
84
     *
85
     * @param string $ip IPv6 address
86 11
     *
87
     * @throws \InvalidArgumentException
88 11
     *
89
     * @return string Contracted IPv6 address
90 11
     */
91 1
    public static function contractIpv6(string $ip): string
92
    {
93
        $packed = inet_pton($ip);
94 10
95
        if (!Validator::ipv6($ip) || false === $packed) {
96 10
            throw new \InvalidArgumentException(sprintf('"%s" is not a valid IPv6 address.', $ip));
97
        }
98
99
        $unpacked = inet_ntop($packed);
100 10
101
        if (false === $unpacked) {
102
            throw new \InvalidArgumentException(sprintf('"%s" could not be contracted.', $ip));
103
        }
104
105
        return $unpacked;
106
    }
107
108
    /**
109
     * Creates a reverse IPv4 address.
110
     *
111
     * E.g. 192.168.1.213 -> 213.1.168.192.in-addr.arpa.
112 2
     *
113
     * @param string $ip Valid IPv4 address
114 2
     *
115
     * @return string Reversed IP address appended with ".in-addr.arpa."
116 2
     */
117
    public static function reverseIpv4(string $ip): string
118
    {
119
        $octets = array_reverse(explode('.', $ip));
120
121
        return implode('.', $octets).'.in-addr.arpa.';
122
    }
123
124
    /**
125
     * Creates a reverse IPv6 address.
126
     *
127
     * E.g. 2001:db8::567:89ab -> b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
128
     *
129 2
     * @param string $ip           A full or partial IPv6 address
130
     * @param bool   $appendSuffix Whether or not to append ".ip6.arpa.' suffix.
131
     *
132 2
     * @return string The reversed address appended with ".ip6.arpa."
133 2
     */
134 2
    public static function reverseIpv6(string $ip, bool $appendSuffix = true): string
135
    {
136
        try {
137 2
            $ip = self::expandIpv6($ip);
138 2
        } catch (\InvalidArgumentException $e) {
139 2
            $ip = self::expandIncompleteIpv6($ip);
140 2
        }
141
142 2
        $ip = str_replace(':', '', $ip);
143
        $ip = strrev($ip);
144
        $ip = implode('.', str_split($ip));
145
        $ip .= $appendSuffix ? '.ip6.arpa.' : '';
146
147
        return $ip;
148
    }
149
}
150