[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Class to validate and to work with IPv6 addresses 4 * 5 * @package Requests 6 * @subpackage Utilities 7 */ 8 9 /** 10 * Class to validate and to work with IPv6 addresses 11 * 12 * This was originally based on the PEAR class of the same name, but has been 13 * entirely rewritten. 14 * 15 * @package Requests 16 * @subpackage Utilities 17 */ 18 class Requests_IPv6 { 19 /** 20 * Uncompresses an IPv6 address 21 * 22 * RFC 4291 allows you to compress consecutive zero pieces in an address to 23 * '::'. This method expects a valid IPv6 address and expands the '::' to 24 * the required number of zero pieces. 25 * 26 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101 27 * ::1 -> 0:0:0:0:0:0:0:1 28 * 29 * @author Alexander Merz <alexander.merz@web.de> 30 * @author elfrink at introweb dot nl 31 * @author Josh Peck <jmp at joshpeck dot org> 32 * @copyright 2003-2005 The PHP Group 33 * @license http://www.opensource.org/licenses/bsd-license.php 34 * @param string $ip An IPv6 address 35 * @return string The uncompressed IPv6 address 36 */ 37 public static function uncompress($ip) { 38 if (substr_count($ip, '::') !== 1) { 39 return $ip; 40 } 41 42 list($ip1, $ip2) = explode('::', $ip); 43 $c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':'); 44 $c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':'); 45 46 if (strpos($ip2, '.') !== false) { 47 $c2++; 48 } 49 // :: 50 if ($c1 === -1 && $c2 === -1) { 51 $ip = '0:0:0:0:0:0:0:0'; 52 } 53 // ::xxx 54 elseif ($c1 === -1) { 55 $fill = str_repeat('0:', 7 - $c2); 56 $ip = str_replace('::', $fill, $ip); 57 } 58 // xxx:: 59 elseif ($c2 === -1) { 60 $fill = str_repeat(':0', 7 - $c1); 61 $ip = str_replace('::', $fill, $ip); 62 } 63 // xxx::xxx 64 else { 65 $fill = ':' . str_repeat('0:', 6 - $c2 - $c1); 66 $ip = str_replace('::', $fill, $ip); 67 } 68 return $ip; 69 } 70 71 /** 72 * Compresses an IPv6 address 73 * 74 * RFC 4291 allows you to compress consecutive zero pieces in an address to 75 * '::'. This method expects a valid IPv6 address and compresses consecutive 76 * zero pieces to '::'. 77 * 78 * Example: FF01:0:0:0:0:0:0:101 -> FF01::101 79 * 0:0:0:0:0:0:0:1 -> ::1 80 * 81 * @see uncompress() 82 * @param string $ip An IPv6 address 83 * @return string The compressed IPv6 address 84 */ 85 public static function compress($ip) { 86 // Prepare the IP to be compressed 87 $ip = self::uncompress($ip); 88 $ip_parts = self::split_v6_v4($ip); 89 90 // Replace all leading zeros 91 $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]); 92 93 // Find bunches of zeros 94 if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) { 95 $max = 0; 96 $pos = null; 97 foreach ($matches[0] as $match) { 98 if (strlen($match[0]) > $max) { 99 $max = strlen($match[0]); 100 $pos = $match[1]; 101 } 102 } 103 104 $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max); 105 } 106 107 if ($ip_parts[1] !== '') { 108 return implode(':', $ip_parts); 109 } 110 else { 111 return $ip_parts[0]; 112 } 113 } 114 115 /** 116 * Splits an IPv6 address into the IPv6 and IPv4 representation parts 117 * 118 * RFC 4291 allows you to represent the last two parts of an IPv6 address 119 * using the standard IPv4 representation 120 * 121 * Example: 0:0:0:0:0:0:13.1.68.3 122 * 0:0:0:0:0:FFFF:129.144.52.38 123 * 124 * @param string $ip An IPv6 address 125 * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part 126 */ 127 protected static function split_v6_v4($ip) { 128 if (strpos($ip, '.') !== false) { 129 $pos = strrpos($ip, ':'); 130 $ipv6_part = substr($ip, 0, $pos); 131 $ipv4_part = substr($ip, $pos + 1); 132 return array($ipv6_part, $ipv4_part); 133 } 134 else { 135 return array($ip, ''); 136 } 137 } 138 139 /** 140 * Checks an IPv6 address 141 * 142 * Checks if the given IP is a valid IPv6 address 143 * 144 * @param string $ip An IPv6 address 145 * @return bool true if $ip is a valid IPv6 address 146 */ 147 public static function check_ipv6($ip) { 148 $ip = self::uncompress($ip); 149 list($ipv6, $ipv4) = self::split_v6_v4($ip); 150 $ipv6 = explode(':', $ipv6); 151 $ipv4 = explode('.', $ipv4); 152 if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) { 153 foreach ($ipv6 as $ipv6_part) { 154 // The section can't be empty 155 if ($ipv6_part === '') { 156 return false; 157 } 158 159 // Nor can it be over four characters 160 if (strlen($ipv6_part) > 4) { 161 return false; 162 } 163 164 // Remove leading zeros (this is safe because of the above) 165 $ipv6_part = ltrim($ipv6_part, '0'); 166 if ($ipv6_part === '') { 167 $ipv6_part = '0'; 168 } 169 170 // Check the value is valid 171 $value = hexdec($ipv6_part); 172 if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) { 173 return false; 174 } 175 } 176 if (count($ipv4) === 4) { 177 foreach ($ipv4 as $ipv4_part) { 178 $value = (int) $ipv4_part; 179 if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) { 180 return false; 181 } 182 } 183 } 184 return true; 185 } 186 else { 187 return false; 188 } 189 } 190 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Dec 15 01:00:02 2022 | Cross-referenced by PHPXref 0.7.1 |