Migrate IP related tools from ProxyTools.php to IP.php
authorAntoine Musso <hashar@users.mediawiki.org>
Wed, 12 Jul 2006 18:33:21 +0000 (18:33 +0000)
committerAntoine Musso <hashar@users.mediawiki.org>
Wed, 12 Jul 2006 18:33:21 +0000 (18:33 +0000)
and its own class of static functions

includes/AutoLoader.php
includes/Block.php
includes/IP.php [new file with mode: 0644]
includes/ProxyTools.php
includes/Setup.php
includes/SpecialIpblocklist.php

index ddbc8a8..783570f 100644 (file)
@@ -89,6 +89,7 @@ function __autoload($className) {
                'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php',
                'Http' => 'includes/HttpFunctions.php',
                'Image' => 'includes/Image.php',
+               'IP' => 'includes/IP.php',
                'ThumbnailImage' => 'includes/Image.php',
                'ImageGallery' => 'includes/ImageGallery.php',
                'ImagePage' => 'includes/ImagePage.php',
index 563b14f..95b5901 100644 (file)
@@ -214,7 +214,7 @@ class Block
         */
        function loadRange( $address, $killExpired = true )
        {
-               $iaddr = wfIP2Hex( $address );
+               $iaddr = IP::ToHex( $address );
                if ( $iaddr === false ) {
                        # Invalid address
                        return false;
@@ -507,7 +507,7 @@ class Block
                $parts = explode( '/', $range );
                if ( count( $parts ) == 2 ) {
                        $shift = 32 - $parts[1];
-                       $ipint = wfIP2Unsigned( $parts[0] );
+                       $ipint = IP::ToUnsigned( $parts[0] );
                        $ipint = $ipint >> $shift << $shift;
                        $newip = long2ip( $ipint );
                        $range = "$newip/{$parts[1]}";
diff --git a/includes/IP.php b/includes/IP.php
new file mode 100644 (file)
index 0000000..9218676
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/*
+ * Collection of public static functions to play with IP address
+ * and IP blocks.
+ *
+ * @Author "Ashar Voultoiz" <hashar@altern.org>
+ * @License GPL v2 or later
+ */
+
+// Some regex definition to "play" with IP address and IP address blocks
+
+// An IP is made of 4 bytes from x00 to xFF which is d0 to d255
+define( 'RE_IP_BYTE', '(25[0-5]|2[0-4]\d|1?\d{1,2})');
+define( 'RE_IP_ADD' , RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
+// An IP block is an IP address and a prefix (d1 to d32)
+define( 'RE_IP_PREFIX' , '(3[0-2]|[12]?\d)');
+define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX);
+
+class IP {
+
+       /**
+        * Validate an IP address.
+        * @return boolean True if it is valid.
+        */
+       public static function IsValid( $ip ) {
+               return preg_match( '/^' . RE_IP_ADD . '$/', $ip, $matches) ;
+       }
+
+       /**
+        * Validate an IP Block.
+        * @return boolean True if it is valid.
+        */
+       public static function IsValidBlock( $ipblock ) {
+               return ( count(self::ToArray($ipblock)) == 1 + 5 );
+       }
+
+       /**
+        * Determine if an IP address really is an IP address, and if it is public,
+        * i.e. not RFC 1918 or similar
+        * Comes from ProxyTools.php
+        */
+       function IsPublic( $ip ) {
+               $n = IP::ToUnsigned( $ip );
+               if ( !$n ) {
+                       return false;
+               }
+
+               // ip2long accepts incomplete addresses, as well as some addresses
+               // followed by garbage characters. Check that it's really valid.
+               if( $ip != long2ip( $n ) ) {
+                       return false;
+               }
+
+               static $privateRanges = false;
+               if ( !$privateRanges ) {
+                       $privateRanges = array(
+                               array( '10.0.0.0',    '10.255.255.255' ),   # RFC 1918 (private)
+                               array( '172.16.0.0',  '172.31.255.255' ),   #     "
+                               array( '192.168.0.0', '192.168.255.255' ),  #     "
+                               array( '0.0.0.0',     '0.255.255.255' ),    # this network
+                               array( '127.0.0.0',   '127.255.255.255' ),  # loopback
+                       );
+               }
+
+               foreach ( $privateRanges as $r ) {
+                       $start = IP::ToUnsigned( $r[0] );
+                       $end = IP::ToUnsigned( $r[1] );
+                       if ( $n >= $start && $n <= $end ) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Split out an IP block as an array of 4 bytes and a mask,
+        * return false if it cant be determined
+        *
+        * @parameter $ip string A quad dotted IP address
+        * @return array
+        */
+       public static function ToArray( $ipblock ) {
+               if(! preg_match( '/^' . RE_IP_ADD . '(?:\/(?:'.RE_IP_PREFIX.'))?' . '$/', $ipblock, $matches ) ) {
+                       return false;
+               } else {
+                       return $matches;
+               }
+       }
+
+       /**
+        * Return a zero-padded hexadecimal representation of an IP address
+        * Comes from ProxyTools.php
+        * @param $ip Quad dotted IP address.
+        */
+       public static function ToHex( $ip ) {
+               $n = self::ToUnsigned( $ip );
+               if ( $n !== false ) {
+                       $n = sprintf( '%08X', $n );
+               }
+               return $n;
+       }
+
+       /**
+        * Given an IP address in dotted-quad notation, returns an unsigned integer.
+        * Like ip2long() except that it actually works and has a consistent error return value.
+        * Comes from ProxyTools.php
+        * @param $ip Quad dotted IP address.
+        */
+       public static function ToUnsigned( $ip ) {
+               $n = ip2long( $ip );
+               if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
+                       $n = false;
+               } elseif ( $n < 0 ) {
+                       $n += pow( 2, 32 );
+               }
+               return $n;
+       }
+}
+?>
index bed79c1..a2157d5 100644 (file)
@@ -55,7 +55,7 @@ function wfGetIP() {
                # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private)
                foreach ( $ipchain as $i => $curIP ) {
                        if ( array_key_exists( $curIP, $trustedProxies ) ) {
-                               if ( isset( $ipchain[$i + 1] ) && wfIsIPPublic( $ipchain[$i + 1] ) ) {
+                               if ( isset( $ipchain[$i + 1] ) && IP::IsPublic( $ipchain[$i + 1] ) ) {
                                        $ip = $ipchain[$i + 1];
                                }
                        } else {
@@ -69,68 +69,6 @@ function wfGetIP() {
        return $ip;
 }
 
-/**
- * Given an IP address in dotted-quad notation, returns an unsigned integer.
- * Like ip2long() except that it actually works and has a consistent error return value.
- */
-function wfIP2Unsigned( $ip ) {
-       $n = ip2long( $ip );
-       if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
-               $n = false;
-       } elseif ( $n < 0 ) {
-               $n += pow( 2, 32 );
-       }
-       return $n;
-}
-
-/**
- * Return a zero-padded hexadecimal representation of an IP address
- */
-function wfIP2Hex( $ip ) {
-       $n = wfIP2Unsigned( $ip );
-       if ( $n !== false ) {
-               $n = sprintf( '%08X', $n );
-       }
-       return $n;
-}
-
-/**
- * Determine if an IP address really is an IP address, and if it is public,
- * i.e. not RFC 1918 or similar
- */
-function wfIsIPPublic( $ip ) {
-       $n = wfIP2Unsigned( $ip );
-       if ( !$n ) {
-               return false;
-       }
-       
-       // ip2long accepts incomplete addresses, as well as some addresses
-       // followed by garbage characters. Check that it's really valid.
-       if( $ip != long2ip( $n ) ) {
-               return false;
-       }
-
-       static $privateRanges = false;
-       if ( !$privateRanges ) {
-               $privateRanges = array(
-                       array( '10.0.0.0',    '10.255.255.255' ),   # RFC 1918 (private)
-                       array( '172.16.0.0',  '172.31.255.255' ),   #     "
-                       array( '192.168.0.0', '192.168.255.255' ),  #     "
-                       array( '0.0.0.0',     '0.255.255.255' ),    # this network
-                       array( '127.0.0.0',   '127.255.255.255' ),  # loopback
-               );
-       }
-
-       foreach ( $privateRanges as $r ) {
-               $start = wfIP2Unsigned( $r[0] );
-               $end = wfIP2Unsigned( $r[1] );
-               if ( $n >= $start && $n <= $end ) {
-                       return false;
-               }
-       }
-       return true;
-}
-
 /**
  * Forks processes to scan the originating IP for an open proxy server
  * MemCached can be used to skip IPs that have already been scanned
@@ -186,7 +124,7 @@ function wfParseCIDR( $range ) {
        if ( count( $parts ) != 2 ) {
                return array( false, false );
        }
-       $network = wfIP2Unsigned( $parts[0] );
+       $network = IP::ToUnsigned( $parts[0] );
        if ( $network !== false && is_numeric( $parts[1] ) && $parts[1] >= 0 && $parts[1] <= 32 ) {
                $bits = $parts[1];
        } else {
index 022cf41..381ea1b 100644 (file)
@@ -61,6 +61,7 @@ require_once( "$IP/includes/MagicWord.php" );
 require_once( "$IP/includes/MessageCache.php" );
 require_once( "$IP/includes/Parser.php" );
 require_once( "$IP/includes/LoadBalancer.php" );
+require_once( "$IP/includes/IP.php" );
 require_once( "$IP/includes/ProxyTools.php" );
 require_once( "$IP/includes/ObjectCache.php" );
 require_once( "$IP/includes/ImageFunctions.php" );
index 16edc6c..4ad265c 100644 (file)
@@ -171,7 +171,7 @@ class IPUnblockForm {
                        // No extra conditions
                } elseif ( substr( $this->ip, 0, 1 ) == '#' ) {
                        $conds['ipb_id'] = substr( $this->ip, 1 );
-               } elseif ( wfIP2Unsigned( $this->ip ) !== false ) {
+               } elseif ( IP::ToUnsigned( $this->ip ) !== false ) {
                        $conds['ipb_address'] = $this->ip;
                        $conds['ipb_auto'] = 0;
                } elseif( preg_match( "/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\\/(\\d{1,2})$/", $this->ip, $matches ) ) {