Index: trunk/phase3/includes/IP.php |
— | — | @@ -124,16 +124,12 @@ |
125 | 125 | * See http://www.answers.com/topic/ipv4-compatible-address |
126 | 126 | * IPs with the first 92 bits as zeros are reserved from IPv6 |
127 | 127 | * @param string $ip quad-dotted IP address. |
128 | | - * @return string |
| 128 | + * @return string IPv4 address |
129 | 129 | */ |
130 | 130 | public static function IPv4toIPv6( $ip ) { |
131 | | - if ( !$ip ) { |
132 | | - return null; |
| 131 | + if ( !self::isIPv4( $ip ) ) { |
| 132 | + throw new MWException( "IPv4toIPv6() called on a non-IPv4 address." ); |
133 | 133 | } |
134 | | - // Convert only if needed |
135 | | - if ( self::isIPv6( $ip ) ) { |
136 | | - return $ip; |
137 | | - } |
138 | 134 | // IPv4 address with CIDR |
139 | 135 | if ( strpos( $ip, '/' ) !== false ) { |
140 | 136 | $parts = explode( '/', $ip, 2 ); |
— | — | @@ -397,10 +393,13 @@ |
398 | 394 | /** |
399 | 395 | * Convert a network specification in CIDR notation |
400 | 396 | * to an integer network and a number of bits |
401 | | - * @param string $range (CIDR IP) |
| 397 | + * @param string $range IP with CIDR prefix |
402 | 398 | * @return array(int, int) |
403 | 399 | */ |
404 | 400 | public static function parseCIDR( $range ) { |
| 401 | + if ( self::isIPv6( $range ) ) { |
| 402 | + return self::parseCIDR6( $range ); |
| 403 | + } |
405 | 404 | $parts = explode( '/', $range, 2 ); |
406 | 405 | if ( count( $parts ) != 2 ) { |
407 | 406 | return array( false, false ); |
— | — | @@ -425,8 +424,8 @@ |
426 | 425 | } |
427 | 426 | |
428 | 427 | /** |
429 | | - * Given a string range in a number of formats, return the start and end of |
430 | | - * the range in hexadecimal. |
| 428 | + * Given a string range in a number of formats, |
| 429 | + * return the start and end of the range in hexadecimal. |
431 | 430 | * |
432 | 431 | * Formats are: |
433 | 432 | * 1.2.3.4/24 CIDR |
— | — | @@ -437,15 +436,14 @@ |
438 | 437 | * 2001:0db8:85a3::7344 - 2001:0db8:85a3::7344 Explicit range |
439 | 438 | * 2001:0db8:85a3::7344 Single IP |
440 | 439 | * @param string $range IP range |
441 | | - * @return array(string, int) |
| 440 | + * @return array(string, string) |
442 | 441 | */ |
443 | 442 | public static function parseRange( $range ) { |
444 | | - // Use IPv6 functions if needed |
445 | | - if ( self::isIPv6( $range ) ) { |
446 | | - return self::parseRange6( $range ); |
447 | | - } |
| 443 | + // CIDR notation |
448 | 444 | if ( strpos( $range, '/' ) !== false ) { |
449 | | - # CIDR |
| 445 | + if ( self::isIPv6( $range ) ) { |
| 446 | + return self::parseRange6( $range ); |
| 447 | + } |
450 | 448 | list( $network, $bits ) = self::parseCIDR( $range ); |
451 | 449 | if ( $network === false ) { |
452 | 450 | $start = $end = false; |
— | — | @@ -453,10 +451,13 @@ |
454 | 452 | $start = sprintf( '%08X', $network ); |
455 | 453 | $end = sprintf( '%08X', $network + pow( 2, ( 32 - $bits ) ) - 1 ); |
456 | 454 | } |
| 455 | + // Explicit range |
457 | 456 | } elseif ( strpos( $range, '-' ) !== false ) { |
458 | | - # Explicit range |
459 | 457 | list( $start, $end ) = array_map( 'trim', explode( '-', $range, 2 ) ); |
460 | | - if( self::isIPAddress( $start ) && self::isIPAddress( $end ) ) { |
| 458 | + if ( self::isIPv6( $start ) && self::isIPv6( $end ) ) { |
| 459 | + return self::parseRange6( $range ); |
| 460 | + } |
| 461 | + if ( self::isIPv4( $start ) && self::isIPv4( $end ) ) { |
461 | 462 | $start = self::toUnsigned( $start ); |
462 | 463 | $end = self::toUnsigned( $end ); |
463 | 464 | if ( $start > $end ) { |
— | — | @@ -593,26 +594,25 @@ |
594 | 595 | if ( self::isValid( $addr ) ) { |
595 | 596 | return $addr; |
596 | 597 | } |
597 | | - |
598 | 598 | // Turn mapped addresses from ::ce:ffff:1.2.3.4 to 1.2.3.4 |
599 | 599 | if ( strpos( $addr, ':' ) !== false && strpos( $addr, '.' ) !== false ) { |
600 | 600 | $addr = substr( $addr, strrpos( $addr, ':' ) + 1 ); |
601 | | - if( self::isIPv4( $addr ) ) { |
| 601 | + if ( self::isIPv4( $addr ) ) { |
602 | 602 | return $addr; |
603 | 603 | } |
604 | 604 | } |
605 | | - |
606 | 605 | // IPv6 loopback address |
607 | 606 | $m = array(); |
608 | 607 | if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) { |
609 | 608 | return '127.0.0.1'; |
610 | 609 | } |
611 | | - |
612 | 610 | // IPv4-mapped and IPv4-compatible IPv6 addresses |
613 | 611 | if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) { |
614 | 612 | return $m[1]; |
615 | 613 | } |
616 | | - if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) { |
| 614 | + if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . |
| 615 | + ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) |
| 616 | + { |
617 | 617 | return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) ); |
618 | 618 | } |
619 | 619 | |