Using a better method to get the English language file.
[lhc/web/wiklou.git] / includes / IP.php
1 <?php
2 /*
3 * Collection of public static functions to play with IP address
4 * and IP blocks.
5 *
6 * @Author "Ashar Voultoiz" <hashar@altern.org>
7 * @License GPL v2 or later
8 */
9
10 // Some regex definition to "play" with IP address and IP address blocks
11
12 // An IP is made of 4 bytes from x00 to xFF which is d0 to d255
13 define( 'RE_IP_BYTE', '(25[0-5]|2[0-4]\d|1?\d{1,2})');
14 define( 'RE_IP_ADD' , RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
15 // An IP block is an IP address and a prefix (d1 to d32)
16 define( 'RE_IP_PREFIX' , '(3[0-2]|[12]?\d)');
17 define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX);
18
19 class IP {
20
21 /**
22 * Validate an IP address.
23 * @return boolean True if it is valid.
24 */
25 public static function isValid( $ip ) {
26 return preg_match( '/^' . RE_IP_ADD . '$/', $ip, $matches) ;
27 }
28
29 /**
30 * Validate an IP Block.
31 * @return boolean True if it is valid.
32 */
33 public static function isValidBlock( $ipblock ) {
34 return ( count(self::toArray($ipblock)) == 1 + 5 );
35 }
36
37 /**
38 * Determine if an IP address really is an IP address, and if it is public,
39 * i.e. not RFC 1918 or similar
40 * Comes from ProxyTools.php
41 */
42 public static function isPublic( $ip ) {
43 $n = IP::toUnsigned( $ip );
44 if ( !$n ) {
45 return false;
46 }
47
48 // ip2long accepts incomplete addresses, as well as some addresses
49 // followed by garbage characters. Check that it's really valid.
50 if( $ip != long2ip( $n ) ) {
51 return false;
52 }
53
54 static $privateRanges = false;
55 if ( !$privateRanges ) {
56 $privateRanges = array(
57 array( '10.0.0.0', '10.255.255.255' ), # RFC 1918 (private)
58 array( '172.16.0.0', '172.31.255.255' ), # "
59 array( '192.168.0.0', '192.168.255.255' ), # "
60 array( '0.0.0.0', '0.255.255.255' ), # this network
61 array( '127.0.0.0', '127.255.255.255' ), # loopback
62 );
63 }
64
65 foreach ( $privateRanges as $r ) {
66 $start = IP::toUnsigned( $r[0] );
67 $end = IP::toUnsigned( $r[1] );
68 if ( $n >= $start && $n <= $end ) {
69 return false;
70 }
71 }
72 return true;
73 }
74
75 /**
76 * Split out an IP block as an array of 4 bytes and a mask,
77 * return false if it cant be determined
78 *
79 * @parameter $ip string A quad dotted IP address
80 * @return array
81 */
82 public static function toArray( $ipblock ) {
83 if(! preg_match( '/^' . RE_IP_ADD . '(?:\/(?:'.RE_IP_PREFIX.'))?' . '$/', $ipblock, $matches ) ) {
84 return false;
85 } else {
86 return $matches;
87 }
88 }
89
90 /**
91 * Return a zero-padded hexadecimal representation of an IP address
92 * Comes from ProxyTools.php
93 * @param $ip Quad dotted IP address.
94 */
95 public static function toHex( $ip ) {
96 $n = self::toUnsigned( $ip );
97 if ( $n !== false ) {
98 $n = sprintf( '%08X', $n );
99 }
100 return $n;
101 }
102
103 /**
104 * Given an IP address in dotted-quad notation, returns an unsigned integer.
105 * Like ip2long() except that it actually works and has a consistent error return value.
106 * Comes from ProxyTools.php
107 * @param $ip Quad dotted IP address.
108 */
109 public static function toUnsigned( $ip ) {
110 $n = ip2long( $ip );
111 if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
112 $n = false;
113 } elseif ( $n < 0 ) {
114 $n += pow( 2, 32 );
115 }
116 return $n;
117 }
118 }
119 ?>