Projet

Général

Profil

Paste
Télécharger (7,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / simplepie / library / SimplePie / Net / IPv6.php @ 41cc1b08

1
<?php
2
/**
3
 * SimplePie
4
 *
5
 * A PHP-Based RSS and Atom Feed Framework.
6
 * Takes the hard work out of managing a complete RSS/Atom solution.
7
 *
8
 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without modification, are
12
 * permitted provided that the following conditions are met:
13
 *
14
 *         * Redistributions of source code must retain the above copyright notice, this list of
15
 *           conditions and the following disclaimer.
16
 *
17
 *         * Redistributions in binary form must reproduce the above copyright notice, this list
18
 *           of conditions and the following disclaimer in the documentation and/or other materials
19
 *           provided with the distribution.
20
 *
21
 *         * Neither the name of the SimplePie Team nor the names of its contributors may be used
22
 *           to endorse or promote products derived from this software without specific prior
23
 *           written permission.
24
 *
25
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28
 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
 * POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 * @package SimplePie
36
 * @version 1.3.1
37
 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
38
 * @author Ryan Parman
39
 * @author Geoffrey Sneddon
40
 * @author Ryan McCue
41
 * @link http://simplepie.org/ SimplePie
42
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43
 */
44

    
45

    
46
/**
47
 * Class to validate and to work with IPv6 addresses.
48
 *
49
 * @package SimplePie
50
 * @subpackage HTTP
51
 * @copyright 2003-2005 The PHP Group
52
 * @license http://www.opensource.org/licenses/bsd-license.php
53
 * @link http://pear.php.net/package/Net_IPv6
54
 * @author Alexander Merz <alexander.merz@web.de>
55
 * @author elfrink at introweb dot nl
56
 * @author Josh Peck <jmp at joshpeck dot org>
57
 * @author Geoffrey Sneddon <geoffers@gmail.com>
58
 */
59
class SimplePie_Net_IPv6
60
{
61
        /**
62
         * Uncompresses an IPv6 address
63
         *
64
         * RFC 4291 allows you to compress concecutive zero pieces in an address to
65
         * '::'. This method expects a valid IPv6 address and expands the '::' to
66
         * the required number of zero pieces.
67
         *
68
         * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
69
         *           ::1         ->  0:0:0:0:0:0:0:1
70
         *
71
         * @author Alexander Merz <alexander.merz@web.de>
72
         * @author elfrink at introweb dot nl
73
         * @author Josh Peck <jmp at joshpeck dot org>
74
         * @copyright 2003-2005 The PHP Group
75
         * @license http://www.opensource.org/licenses/bsd-license.php
76
         * @param string $ip An IPv6 address
77
         * @return string The uncompressed IPv6 address
78
         */
79
        public static function uncompress($ip)
80
        {
81
                $c1 = -1;
82
                $c2 = -1;
83
                if (substr_count($ip, '::') === 1)
84
                {
85
                        list($ip1, $ip2) = explode('::', $ip);
86
                        if ($ip1 === '')
87
                        {
88
                                $c1 = -1;
89
                        }
90
                        else
91
                        {
92
                                $c1 = substr_count($ip1, ':');
93
                        }
94
                        if ($ip2 === '')
95
                        {
96
                                $c2 = -1;
97
                        }
98
                        else
99
                        {
100
                                $c2 = substr_count($ip2, ':');
101
                        }
102
                        if (strpos($ip2, '.') !== false)
103
                        {
104
                                $c2++;
105
                        }
106
                        // ::
107
                        if ($c1 === -1 && $c2 === -1)
108
                        {
109
                                $ip = '0:0:0:0:0:0:0:0';
110
                        }
111
                        // ::xxx
112
                        else if ($c1 === -1)
113
                        {
114
                                $fill = str_repeat('0:', 7 - $c2);
115
                                $ip = str_replace('::', $fill, $ip);
116
                        }
117
                        // xxx::
118
                        else if ($c2 === -1)
119
                        {
120
                                $fill = str_repeat(':0', 7 - $c1);
121
                                $ip = str_replace('::', $fill, $ip);
122
                        }
123
                        // xxx::xxx
124
                        else
125
                        {
126
                                $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
127
                                $ip = str_replace('::', $fill, $ip);
128
                        }
129
                }
130
                return $ip;
131
        }
132

    
133
        /**
134
         * Compresses an IPv6 address
135
         *
136
         * RFC 4291 allows you to compress concecutive zero pieces in an address to
137
         * '::'. This method expects a valid IPv6 address and compresses consecutive
138
         * zero pieces to '::'.
139
         *
140
         * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
141
         *           0:0:0:0:0:0:0:1        ->  ::1
142
         *
143
         * @see uncompress()
144
         * @param string $ip An IPv6 address
145
         * @return string The compressed IPv6 address
146
         */
147
        public static function compress($ip)
148
        {
149
                // Prepare the IP to be compressed
150
                $ip = self::uncompress($ip);
151
                $ip_parts = self::split_v6_v4($ip);
152

    
153
                // Replace all leading zeros
154
                $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
155

    
156
                // Find bunches of zeros
157
                if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
158
                {
159
                        $max = 0;
160
                        $pos = null;
161
                        foreach ($matches[0] as $match)
162
                        {
163
                                if (strlen($match[0]) > $max)
164
                                {
165
                                        $max = strlen($match[0]);
166
                                        $pos = $match[1];
167
                                }
168
                        }
169

    
170
                        $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
171
                }
172

    
173
                if ($ip_parts[1] !== '')
174
                {
175
                        return implode(':', $ip_parts);
176
                }
177
                else
178
                {
179
                        return $ip_parts[0];
180
                }
181
        }
182

    
183
        /**
184
         * Splits an IPv6 address into the IPv6 and IPv4 representation parts
185
         *
186
         * RFC 4291 allows you to represent the last two parts of an IPv6 address
187
         * using the standard IPv4 representation
188
         *
189
         * Example:  0:0:0:0:0:0:13.1.68.3
190
         *           0:0:0:0:0:FFFF:129.144.52.38
191
         *
192
         * @param string $ip An IPv6 address
193
         * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
194
         */
195
        private static function split_v6_v4($ip)
196
        {
197
                if (strpos($ip, '.') !== false)
198
                {
199
                        $pos = strrpos($ip, ':');
200
                        $ipv6_part = substr($ip, 0, $pos);
201
                        $ipv4_part = substr($ip, $pos + 1);
202
                        return array($ipv6_part, $ipv4_part);
203
                }
204
                else
205
                {
206
                        return array($ip, '');
207
                }
208
        }
209

    
210
        /**
211
         * Checks an IPv6 address
212
         *
213
         * Checks if the given IP is a valid IPv6 address
214
         *
215
         * @param string $ip An IPv6 address
216
         * @return bool true if $ip is a valid IPv6 address
217
         */
218
        public static function check_ipv6($ip)
219
        {
220
                $ip = self::uncompress($ip);
221
                list($ipv6, $ipv4) = self::split_v6_v4($ip);
222
                $ipv6 = explode(':', $ipv6);
223
                $ipv4 = explode('.', $ipv4);
224
                if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
225
                {
226
                        foreach ($ipv6 as $ipv6_part)
227
                        {
228
                                // The section can't be empty
229
                                if ($ipv6_part === '')
230
                                        return false;
231

    
232
                                // Nor can it be over four characters
233
                                if (strlen($ipv6_part) > 4)
234
                                        return false;
235

    
236
                                // Remove leading zeros (this is safe because of the above)
237
                                $ipv6_part = ltrim($ipv6_part, '0');
238
                                if ($ipv6_part === '')
239
                                        $ipv6_part = '0';
240

    
241
                                // Check the value is valid
242
                                $value = hexdec($ipv6_part);
243
                                if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
244
                                        return false;
245
                        }
246
                        if (count($ipv4) === 4)
247
                        {
248
                                foreach ($ipv4 as $ipv4_part)
249
                                {
250
                                        $value = (int) $ipv4_part;
251
                                        if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
252
                                                return false;
253
                                }
254
                        }
255
                        return true;
256
                }
257
                else
258
                {
259
                        return false;
260
                }
261
        }
262

    
263
        /**
264
         * Checks if the given IP is a valid IPv6 address
265
         *
266
         * @codeCoverageIgnore
267
         * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
268
         * @see check_ipv6
269
         * @param string $ip An IPv6 address
270
         * @return bool true if $ip is a valid IPv6 address
271
         */
272
        public static function checkIPv6($ip)
273
        {
274
                return self::check_ipv6($ip);
275
        }
276
}