Changeset 497 for trunk/lib/Utilities.inc.php
- Timestamp:
- Sep 15, 2014 9:44:27 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Utilities.inc.php
r487 r497 1082 1082 } 1083 1083 1084 /** 1085 * Returns the remote IP address, taking into consideration proxy servers. 1086 * 1087 * @param bool $dolookup If true we resolve to IP to a host name, 1088 * if false we don't. 1089 * @return string IP address if $dolookup is false or no arg 1090 * Hostname if $dolookup is true 1091 */ 1092 function getRemoteAddr($dolookup=false) 1093 { 1094 $ip = getenv('HTTP_CLIENT_IP'); 1095 if (in_array($ip, array('', 'unknown', 'localhost', '127.0.0.1'))) { 1096 $ip = getenv('HTTP_X_FORWARDED_FOR'); 1097 if (mb_strpos($ip, ',') !== false) { 1098 // If HTTP_X_FORWARDED_FOR returns a comma-delimited list of IPs then return the first one (assuming the first is the original). 1099 $ips = explode(',', $ip, 2); 1100 $ip = $ips[0]; 1101 } 1102 if (in_array($ip, array('', 'unknown', 'localhost', '127.0.0.1'))) { 1103 $ip = getenv('REMOTE_ADDR'); 1104 } 1105 } 1106 return $dolookup && '' != $ip ? gethostbyaddr($ip) : $ip; 1084 /* 1085 * Returns the remote IP address, taking into consideration proxy servers. 1086 * 1087 * If strict checking is enabled, we will only trust REMOTE_ADDR or an HTTP header 1088 * value if REMOTE_ADDR is a trusted proxy (configured as an array in $cfg['trusted_proxies']). 1089 * 1090 * @access public 1091 * @param bool $dolookup Resolve to IP to a hostname? 1092 * @param bool $trust_all_proxies Should we trust any IP address set in HTTP_* variables? Set to FALSE for secure usage. 1093 * @return mixed Canonicalized IP address (or a corresponding hostname if $dolookup is true), or false if no IP was found. 1094 * @author Alix Axel <http://stackoverflow.com/a/2031935/277303> 1095 * @author Corey Ballou <http://blackbe.lt/advanced-method-to-obtain-the-client-ip-in-php/> 1096 * @author Quinn Comendant <quinn@strangecode.com> 1097 * @version 1.0 1098 * @since 12 Sep 2014 19:07:46 1099 */ 1100 function getRemoteAddr($dolookup=false, $trust_all_proxies=true) 1101 { 1102 global $cfg; 1103 1104 if (!isset($_SERVER['REMOTE_ADDR'])) { 1105 // Must be a CLI. 1106 return false; 1107 } 1108 1109 // Use an HTTP header value only if $trust_all_proxies is true or when REMOTE_ADDR is in our $cfg['trusted_proxies'] array. 1110 // $cfg['trusted_proxies'] is an array of proxy server addresses we expect to see in REMOTE_ADDR. 1111 if ($trust_all_proxies || isset($cfg['trusted_proxies']) && is_array($cfg['trusted_proxies']) && in_array($_SERVER['REMOTE_ADDR'], $cfg['trusted_proxies'], true)) { 1112 // Then it's probably safe to use an IP address value set in an HTTP header. 1113 // Loop through possible IP address headers. 1114 foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key) { 1115 // Loop through and if 1116 if (array_key_exists($key, $_SERVER)) { 1117 foreach (explode(',', $_SERVER[$key]) as $addr) { 1118 $addr = canonicalIPAddr(trim($addr)); 1119 if (false !== filter_var($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { 1120 return $dolookup && '' != $addr ? gethostbyaddr($addr) : $addr; 1121 } 1122 } 1123 } 1124 } 1125 } 1126 1127 $addr = canonicalIPAddr(trim($_SERVER['REMOTE_ADDR'])); 1128 return $dolookup && $addr ? gethostbyaddr($addr) : $addr; 1129 } 1130 1131 /* 1132 * Converts an ipv4 IP address in hexadecimal form into canonical form (i.e., it removes the prefix). 1133 * 1134 * @access public 1135 * @param string $addr IP address. 1136 * @return string Canonical IP address. 1137 * @author Sander Steffann <http://stackoverflow.com/a/12436099/277303> 1138 * @author Quinn Comendant <quinn@strangecode.com> 1139 * @version 1.0 1140 * @since 15 Sep 2012 1141 */ 1142 function canonicalIPAddr($addr) 1143 { 1144 // Known prefix 1145 $v4mapped_prefix_bin = pack('H*', '00000000000000000000ffff'); 1146 1147 // Parse 1148 $addr_bin = inet_pton($addr); 1149 1150 // Check prefix 1151 if (substr($addr_bin, 0, strlen($v4mapped_prefix_bin)) == $v4mapped_prefix_bin) { 1152 // Strip prefix 1153 echo 'prefix matches'; 1154 $addr_bin = substr($addr_bin, strlen($v4mapped_prefix_bin)); 1155 } 1156 1157 // Convert back to printable address in canonical form 1158 return inet_ntop($addr_bin); 1107 1159 } 1108 1160 … … 1117 1169 * @return mixed Returns the network that matched on success, false on failure. 1118 1170 */ 1119 function ipInRange($ ip, $networks)1171 function ipInRange($addr, $networks) 1120 1172 { 1121 1173 if (!is_array($networks)) { … … 1123 1175 } 1124 1176 1125 $ ip_binary = sprintf('%032b', ip2long($ip));1177 $addr_binary = sprintf('%032b', ip2long($addr)); 1126 1178 foreach ($networks as $network) { 1127 1179 if (preg_match('![\d\.]{7,15}/\d{1,2}!', $network)) { … … 1129 1181 list($cidr_ip, $cidr_bitmask) = explode('/', $network); 1130 1182 $cidr_ip_binary = sprintf('%032b', ip2long($cidr_ip)); 1131 if (mb_substr($ ip_binary, 0, $cidr_bitmask) === mb_substr($cidr_ip_binary, 0, $cidr_bitmask)) {1183 if (mb_substr($addr_binary, 0, $cidr_bitmask) === mb_substr($cidr_ip_binary, 0, $cidr_bitmask)) { 1132 1184 // IP address is within the specified IP range. 1133 1185 return $network; 1134 1186 } 1135 1187 } else { 1136 if ($ ip=== $network) {1188 if ($addr === $network) { 1137 1189 // IP address exactly matches. 1138 1190 return $network;
Note: See TracChangeset
for help on using the changeset viewer.