MediaWiki
REL1_24
|
00001 <?php 00012 class IPTest extends MediaWikiTestCase { 00017 public function testisIPAddress() { 00018 $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' ); 00019 $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' ); 00020 $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' ); 00021 $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' ); 00022 $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' ); 00023 $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' ); 00024 $this->assertFalse( 00025 IP::isIPAddress( '2001:0DB8::A:1::' ), 00026 'IPv6 with a double :: occurrence, last at end' 00027 ); 00028 $this->assertFalse( 00029 IP::isIPAddress( '::2001:0DB8::5:1' ), 00030 'IPv6 with a double :: occurrence, firt at beginning' 00031 ); 00032 $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' ); 00033 $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' ); 00034 $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' ); 00035 $this->assertFalse( IP::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' ); 00036 00037 $this->assertTrue( IP::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' ); 00038 $this->assertTrue( IP::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' ); 00039 $this->assertTrue( IP::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) ); 00040 $this->assertTrue( IP::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' ); 00041 $this->assertTrue( IP::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' ); 00042 00043 $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac', 00044 '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' ); 00045 foreach ( $validIPs as $ip ) { 00046 $this->assertTrue( IP::isIPAddress( $ip ), "$ip is a valid IP address" ); 00047 } 00048 } 00049 00053 public function testisIPv6() { 00054 $this->assertFalse( IP::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' ); 00055 $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); 00056 $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' ); 00057 $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' ); 00058 00059 $this->assertTrue( IP::isIPv6( 'fc:100::' ) ); 00060 $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) ); 00061 $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) ); 00062 $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) ); 00063 $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) ); 00064 $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) ); 00065 00066 $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); 00067 $this->assertFalse( 00068 IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 00069 'IPv6 with 9 words ending with "::"' 00070 ); 00071 00072 $this->assertFalse( IP::isIPv6( ':::' ) ); 00073 $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' ); 00074 00075 $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' ); 00076 $this->assertTrue( IP::isIPv6( '::0' ) ); 00077 $this->assertTrue( IP::isIPv6( '::fc' ) ); 00078 $this->assertTrue( IP::isIPv6( '::fc:100' ) ); 00079 $this->assertTrue( IP::isIPv6( '::fc:100:a' ) ); 00080 $this->assertTrue( IP::isIPv6( '::fc:100:a:d' ) ); 00081 $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) ); 00082 $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) ); 00083 $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) ); 00084 00085 $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); 00086 $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); 00087 00088 $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' ); 00089 $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' ); 00090 $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' ); 00091 00092 $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' ); 00093 $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); 00094 $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) ); 00095 $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); 00096 $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' ); 00097 $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); 00098 $this->assertTrue( IP::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' ); 00099 $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); 00100 $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); 00101 00102 $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); 00103 $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); 00104 00105 $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac:0' ) ); 00106 } 00107 00111 public function testisIPv4() { 00112 $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' ); 00113 $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' ); 00114 $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' ); 00115 $this->assertFalse( IP::isIPv4( 'abc' ) ); 00116 $this->assertFalse( IP::isIPv4( ':' ) ); 00117 $this->assertFalse( IP::isIPv4( '124.24.52' ), 'IPv4 not enough quads' ); 00118 $this->assertFalse( IP::isIPv4( '24.324.52.13' ), 'IPv4 out of range' ); 00119 $this->assertFalse( IP::isIPv4( '.24.52.13' ), 'IPv4 starts with period' ); 00120 00121 $this->assertTrue( IP::isIPv4( '124.24.52.13' ) ); 00122 $this->assertTrue( IP::isIPv4( '1.24.52.13' ) ); 00123 $this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) ); 00124 } 00125 00129 public function testValidIPs() { 00130 foreach ( range( 0, 255 ) as $i ) { 00131 $a = sprintf( "%03d", $i ); 00132 $b = sprintf( "%02d", $i ); 00133 $c = sprintf( "%01d", $i ); 00134 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { 00135 $ip = "$f.$f.$f.$f"; 00136 $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv4 address" ); 00137 } 00138 } 00139 foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) { 00140 $a = sprintf( "%04x", $i ); 00141 $b = sprintf( "%03x", $i ); 00142 $c = sprintf( "%02x", $i ); 00143 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { 00144 $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; 00145 $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv6 address" ); 00146 } 00147 } 00148 // test with some abbreviations 00149 $this->assertFalse( IP::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' ); 00150 $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); 00151 $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' ); 00152 $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' ); 00153 00154 $this->assertTrue( IP::isValid( 'fc:100::' ) ); 00155 $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) ); 00156 $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) ); 00157 00158 $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' ); 00159 $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); 00160 $this->assertTrue( IP::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' ); 00161 $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); 00162 $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); 00163 $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); 00164 $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); 00165 00166 $this->assertFalse( 00167 IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 00168 'IPv6 with 8 words ending with "::"' 00169 ); 00170 $this->assertFalse( 00171 IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 00172 'IPv6 with 9 words ending with "::"' 00173 ); 00174 } 00175 00179 public function testInvalidIPs() { 00180 // Out of range... 00181 foreach ( range( 256, 999 ) as $i ) { 00182 $a = sprintf( "%03d", $i ); 00183 $b = sprintf( "%02d", $i ); 00184 $c = sprintf( "%01d", $i ); 00185 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { 00186 $ip = "$f.$f.$f.$f"; 00187 $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); 00188 } 00189 } 00190 foreach ( range( 'g', 'z' ) as $i ) { 00191 $a = sprintf( "%04s", $i ); 00192 $b = sprintf( "%03s", $i ); 00193 $c = sprintf( "%02s", $i ); 00194 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { 00195 $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; 00196 $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv6 address" ); 00197 } 00198 } 00199 // Have CIDR 00200 $ipCIDRs = array( 00201 '212.35.31.121/32', 00202 '212.35.31.121/18', 00203 '212.35.31.121/24', 00204 '::ff:d:321:5/96', 00205 'ff::d3:321:5/116', 00206 'c:ff:12:1:ea:d:321:5/120', 00207 ); 00208 foreach ( $ipCIDRs as $i ) { 00209 $this->assertFalse( IP::isValid( $i ), 00210 "$i is an invalid IP address because it is a block" ); 00211 } 00212 // Incomplete/garbage 00213 $invalid = array( 00214 'www.xn--var-xla.net', 00215 '216.17.184.G', 00216 '216.17.184.1.', 00217 '216.17.184', 00218 '216.17.184.', 00219 '256.17.184.1' 00220 ); 00221 foreach ( $invalid as $i ) { 00222 $this->assertFalse( IP::isValid( $i ), "$i is an invalid IP address" ); 00223 } 00224 } 00225 00229 public function testValidBlocks() { 00230 $valid = array( 00231 '116.17.184.5/32', 00232 '0.17.184.5/30', 00233 '16.17.184.1/24', 00234 '30.242.52.14/1', 00235 '10.232.52.13/8', 00236 '30.242.52.14/0', 00237 '::e:f:2001/96', 00238 '::c:f:2001/128', 00239 '::10:f:2001/70', 00240 '::fe:f:2001/1', 00241 '::6d:f:2001/8', 00242 '::fe:f:2001/0', 00243 ); 00244 foreach ( $valid as $i ) { 00245 $this->assertTrue( IP::isValidBlock( $i ), "$i is a valid IP block" ); 00246 } 00247 } 00248 00252 public function testInvalidBlocks() { 00253 $invalid = array( 00254 '116.17.184.5/33', 00255 '0.17.184.5/130', 00256 '16.17.184.1/-1', 00257 '10.232.52.13/*', 00258 '7.232.52.13/ab', 00259 '11.232.52.13/', 00260 '::e:f:2001/129', 00261 '::c:f:2001/228', 00262 '::10:f:2001/-1', 00263 '::6d:f:2001/*', 00264 '::86:f:2001/ab', 00265 '::23:f:2001/', 00266 ); 00267 foreach ( $invalid as $i ) { 00268 $this->assertFalse( IP::isValidBlock( $i ), "$i is not a valid IP block" ); 00269 } 00270 } 00271 00276 public function testSanitizeIP() { 00277 $this->assertNull( IP::sanitizeIP( '' ) ); 00278 $this->assertNull( IP::sanitizeIP( ' ' ) ); 00279 } 00280 00285 public function testToHex( $expected, $input ) { 00286 $result = IP::toHex( $input ); 00287 $this->assertTrue( $result === false || is_string( $result ) ); 00288 $this->assertEquals( $expected, $result ); 00289 } 00290 00294 public static function provideToHex() { 00295 return array( 00296 array( '00000001', '0.0.0.1' ), 00297 array( '01020304', '1.2.3.4' ), 00298 array( '7F000001', '127.0.0.1' ), 00299 array( '80000000', '128.0.0.0' ), 00300 array( 'DEADCAFE', '222.173.202.254' ), 00301 array( 'FFFFFFFF', '255.255.255.255' ), 00302 array( false, 'IN.VA.LI.D' ), 00303 array( 'v6-00000000000000000000000000000001', '::1' ), 00304 array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), 00305 array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ), 00306 array( false, 'IN:VA::LI:D' ), 00307 array( false, ':::1' ) 00308 ); 00309 } 00310 00314 public function testPrivateIPs() { 00315 $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); 00316 foreach ( $private as $p ) { 00317 $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); 00318 } 00319 $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' ); 00320 foreach ( $public as $p ) { 00321 $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" ); 00322 } 00323 } 00324 00325 // Private wrapper used to test CIDR Parsing. 00326 private function assertFalseCIDR( $CIDR, $msg = '' ) { 00327 $ff = array( false, false ); 00328 $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg ); 00329 } 00330 00331 // Private wrapper to test network shifting using only dot notation 00332 private function assertNet( $expected, $CIDR ) { 00333 $parse = IP::parseCIDR( $CIDR ); 00334 $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" ); 00335 } 00336 00340 public function testHexToQuad() { 00341 $this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) ); 00342 $this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) ); 00343 $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) ); 00344 $this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) ); 00345 // hex not left-padded... 00346 $this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) ); 00347 $this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) ); 00348 $this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) ); 00349 $this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) ); 00350 } 00351 00355 public function testHexToOctet() { 00356 $this->assertEquals( '0:0:0:0:0:0:0:1', 00357 IP::hexToOctet( '00000000000000000000000000000001' ) ); 00358 $this->assertEquals( '0:0:0:0:0:0:FF:3', 00359 IP::hexToOctet( '00000000000000000000000000FF0003' ) ); 00360 $this->assertEquals( '0:0:0:0:0:0:FF00:6', 00361 IP::hexToOctet( '000000000000000000000000FF000006' ) ); 00362 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', 00363 IP::hexToOctet( '000000000000000000000000FCCFFAFF' ) ); 00364 $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 00365 IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) ); 00366 // hex not left-padded... 00367 $this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) ); 00368 $this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) ); 00369 $this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) ); 00370 $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) ); 00371 $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) ); 00372 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) ); 00373 } 00374 00380 public function testCIDRParsing() { 00381 $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); 00382 $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); 00383 00384 // Verify if statement 00385 $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" ); 00386 $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" ); 00387 $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" ); 00388 $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" ); 00389 00390 // Check internal logic 00391 # 0 mask always result in array(0,0) 00392 $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '192.0.0.2/0' ) ); 00393 $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '0.0.0.0/0' ) ); 00394 $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '255.255.255.255/0' ) ); 00395 00396 // @todo FIXME: Add more tests. 00397 00398 # This part test network shifting 00399 $this->assertNet( '192.0.0.0', '192.0.0.2/24' ); 00400 $this->assertNet( '192.168.5.0', '192.168.5.13/24' ); 00401 $this->assertNet( '10.0.0.160', '10.0.0.161/28' ); 00402 $this->assertNet( '10.0.0.0', '10.0.0.3/28' ); 00403 $this->assertNet( '10.0.0.0', '10.0.0.3/30' ); 00404 $this->assertNet( '10.0.0.4', '10.0.0.4/30' ); 00405 $this->assertNet( '172.17.32.0', '172.17.35.48/21' ); 00406 $this->assertNet( '10.128.0.0', '10.135.0.0/9' ); 00407 $this->assertNet( '134.0.0.0', '134.0.5.1/8' ); 00408 } 00409 00413 public function testIPCanonicalizeOnValidIp() { 00414 $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ), 00415 'Canonicalization of a valid IP returns it unchanged' ); 00416 } 00417 00421 public function testIPCanonicalizeMappedAddress() { 00422 $this->assertEquals( 00423 '192.0.2.152', 00424 IP::canonicalize( '::ffff:192.0.2.152' ) 00425 ); 00426 $this->assertEquals( 00427 '192.0.2.152', 00428 IP::canonicalize( '::192.0.2.152' ) 00429 ); 00430 } 00431 00437 public function testIPIsInRange( $expected, $addr, $range, $message = '' ) { 00438 $this->assertEquals( 00439 $expected, 00440 IP::isInRange( $addr, $range ), 00441 $message 00442 ); 00443 } 00444 00446 public static function provideIPsAndRanges() { 00447 # Format: (expected boolean, address, range, optional message) 00448 return array( 00449 # IPv4 00450 array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ), 00451 array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ), 00452 array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ), 00453 00454 array( false, '0.0.0.0', '192.0.2.0/24' ), 00455 array( false, '255.255.255', '192.0.2.0/24' ), 00456 00457 # IPv6 00458 array( false, '::1', '2001:DB8::/32' ), 00459 array( false, '::', '2001:DB8::/32' ), 00460 array( false, 'FE80::1', '2001:DB8::/32' ), 00461 00462 array( true, '2001:DB8::', '2001:DB8::/32' ), 00463 array( true, '2001:0DB8::', '2001:DB8::/32' ), 00464 array( true, '2001:DB8::1', '2001:DB8::/32' ), 00465 array( true, '2001:0DB8::1', '2001:DB8::/32' ), 00466 array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 00467 '2001:DB8::/32' ), 00468 00469 array( false, '2001:0DB8:F::', '2001:DB8::/96' ), 00470 ); 00471 } 00472 00477 public function testSplitHostAndPort( $expected, $input, $description ) { 00478 $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); 00479 } 00480 00484 public static function provideSplitHostAndPort() { 00485 return array( 00486 array( false, '[', 'Unclosed square bracket' ), 00487 array( false, '[::', 'Unclosed square bracket 2' ), 00488 array( array( '::', false ), '::', 'Bare IPv6 0' ), 00489 array( array( '::1', false ), '::1', 'Bare IPv6 1' ), 00490 array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ), 00491 array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ), 00492 array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ), 00493 array( false, '::x', 'Double colon but no IPv6' ), 00494 array( array( 'x', 80 ), 'x:80', 'Hostname and port' ), 00495 array( false, 'x:x', 'Hostname and invalid port' ), 00496 array( array( 'x', false ), 'x', 'Plain hostname' ) 00497 ); 00498 } 00499 00504 public function testCombineHostAndPort( $expected, $input, $description ) { 00505 list( $host, $port, $defaultPort ) = $input; 00506 $this->assertEquals( 00507 $expected, 00508 IP::combineHostAndPort( $host, $port, $defaultPort ), 00509 $description ); 00510 } 00511 00515 public static function provideCombineHostAndPort() { 00516 return array( 00517 array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ), 00518 array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ), 00519 array( 'x', array( 'x', 2, 2 ), 'Normal default port' ), 00520 array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ), 00521 ); 00522 } 00523 00528 public function testSanitizeRange( $input, $expected, $description ) { 00529 $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); 00530 } 00531 00535 public static function provideIPCIDRs() { 00536 return array( 00537 array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ), 00538 array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ), 00539 array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ), 00540 array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ), 00541 array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ), 00542 array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ), 00543 array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ), 00544 array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ), 00545 ); 00546 } 00547 00552 public function testPrettifyIP( $ip, $prettified ) { 00553 $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); 00554 } 00555 00559 public static function provideIPsToPrettify() { 00560 return array( 00561 array( '0:0:0:0:0:0:0:0', '::' ), 00562 array( '0:0:0::0:0:0', '::' ), 00563 array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ), 00564 array( '0:0::f', '::f' ), 00565 array( '0::0:0:0:33:fef:b', '::33:fef:b' ), 00566 array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ), 00567 array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ), 00568 array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ), 00569 array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ), 00570 array( '0:0:0:0:0:0:0:0/16', '::/16' ), 00571 array( '0:0:0::0:0:0/64', '::/64' ), 00572 array( '0:0::f/52', '::f/52' ), 00573 array( '::0:0:33:fef:b/52', '::33:fef:b/52' ), 00574 array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ), 00575 array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ), 00576 array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ), 00577 array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ), 00578 ); 00579 } 00580 }