Created
May 20, 2017 23:29
-
-
Save roytam1/2b5d5439dd241ed24009d725bf235c12 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class _prepend_cf_ips { | |
var $cf_ipv4; | |
var $cf_ipv6; | |
function _IPv4_CIDRmatch($addr,$cidr) { | |
list($ip, $mask) = explode('/', $cidr); | |
return (ip2long($addr) >> (32 - $mask) == ip2long($ip.str_repeat('.0', 3 - substr_count($ip, '.'))) >> (32 - $mask)); | |
} | |
function _inet_pton($ip){ | |
//ipv4 | |
if (strpos($ip, '.') !== FALSE) { | |
$ip = trim($ip,':f'); | |
$ip = pack('N',ip2long($ip)); | |
} | |
//ipv6 | |
elseif (strpos($ip, ':') !== FALSE) { | |
//Short ipv6 fix by NewEraCracker | |
$_count = count(explode(':', $ip)); | |
while($_count<8) | |
{ | |
$ip = str_replace('::',':0::',$ip); | |
$_count++; | |
} | |
unset($_count); | |
//Newfags can't triforce! | |
$ip = explode(':', $ip); | |
$res = str_pad('', (4*(8-count($ip))), '0000', STR_PAD_LEFT); | |
foreach ($ip as $seg) { | |
$res .= str_pad($seg, 4, '0', STR_PAD_LEFT); | |
} | |
$ip = pack('H'.strlen($res), $res); | |
} | |
return $ip; | |
} | |
function _inet_ntop($ip){ | |
if (strlen($ip)==4){ | |
//ipv4 | |
list(,$ip)=unpack('N',$ip); | |
$ip=long2ip($ip); | |
} | |
elseif(strlen($ip)==16){ | |
//ipv6 | |
$ip=bin2hex($ip); | |
$ip=substr(chunk_split($ip,4,':'),0,-1); | |
$ip=explode(':',$ip); | |
$res=''; | |
foreach($ip as $seg) { | |
while($seg{0}=='0') $seg=substr($seg,1); | |
if ($seg!='') { | |
$res.=($res==''?'':':').$seg; | |
} else { | |
if (strpos($res,'::')===false) { | |
if (substr($res,-1)==':') continue; | |
$res.=':'; | |
continue; | |
} | |
$res.=($res==''?'':':').'0'; | |
} | |
} | |
$ip=$res; | |
} | |
return $ip; | |
} | |
function _IPv6_expand($ip){ | |
$hex = unpack("H*hex", $this->_inet_pton($ip)); | |
$ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1); | |
return $ip; | |
} | |
function _IPv6_compress($ip){ | |
// Shorten first group of zeros | |
if(substr($ip, 0, 4) === '0000') $ip = substr_replace($ip, ':0', 0, 4); | |
// Shorten full groups of zeros | |
$ip = str_replace(':0000', ':0', $ip); | |
// Remove leading zeros | |
$ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip); //return $ip; | |
// Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952) | |
$z = ':0:0:0:0:0:0:0:'; // Set chain | |
while(strpos($ip, '::') === false && strlen($z) >= 5){ // While no :: and chain still possible | |
$pos = strpos($ip, $z); | |
if($pos !== false){ $ip = substr_replace($ip, '::', $pos, strlen($z)); break; } // Replace chain and break | |
$z = substr($z, 0, strlen($z) - 2); // cut away one '0:' to shorten the chain | |
} | |
if(substr($ip, 1, 1) !== ':') return ltrim($ip, ':'); // Remove initial : if not a :: | |
return $ip; | |
} | |
function _IPv6_MaskToByteArray($subnetMask) { | |
$addr = str_repeat("f", $subnetMask / 4); | |
switch ($subnetMask % 4) { | |
case 0: | |
break; | |
case 1: | |
$addr .= "8"; | |
break; | |
case 2: | |
$addr .= "c"; | |
break; | |
case 3: | |
$addr .= "e"; | |
break; | |
} | |
$addr = str_pad($addr, 32, '0'); | |
$addr = pack("H*" , $addr); | |
return $addr; | |
} | |
function _IPv6_CidrMatch($address, $subnetAddress, $subnetMask) { | |
$binMask = $this->_IPv6_MaskToByteArray($subnetMask); | |
return ($address & $binMask) == $subnetAddress; | |
} | |
function _prepend_cf_ips() { | |
$targetip = strncmp($_SERVER['REMOTE_ADDR'],'::ffff:',7) === 0 ? substr($_SERVER['REMOTE_ADDR'], 7) : $_SERVER['REMOTE_ADDR']; | |
$this->cf_ipv4=explode("\n",'103.21.244.0/22 | |
103.22.200.0/22 | |
103.31.4.0/22 | |
104.16.0.0/12 | |
108.162.192.0/18 | |
131.0.72.0/22 | |
141.101.64.0/18 | |
162.158.0.0/15 | |
172.64.0.0/13 | |
173.245.48.0/20 | |
188.114.96.0/20 | |
190.93.240.0/20 | |
197.234.240.0/22 | |
198.41.128.0/17 | |
199.27.128.0/21'); | |
$this->cf_ipv6=explode("\n",'2400:cb00::/32 | |
2405:8100::/32 | |
2405:b500::/32 | |
2606:4700::/32 | |
2803:f800::/32 | |
2c0f:f248::/32 | |
2a06:98c0::/29'); | |
if(strpos($targetip,':') === false) { // IPv4 | |
foreach($this->cf_ipv4 as $i) { | |
if($this->_IPv4_CIDRmatch($targetip,$i)) { | |
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP']; | |
break; | |
} | |
} | |
} else { // IPv6 | |
foreach($this->cf_ipv6 as $i) { | |
list($net,$maskbits)=explode('/',$i); | |
if($this->_IPv6_CidrMatch($this->_inet_pton($targetip),$this->_inet_pton($this->_IPv6_expand($net)),$maskbits)) { | |
$_SERVER['REMOTE_ADDR'] = $this->_IPv6_compress($_SERVER['HTTP_CF_CONNECTING_IP']); | |
break; | |
} | |
} | |
} | |
} | |
} | |
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { | |
$_prep_cf_ip = new _prepend_cf_ips(); | |
unset($_prep_cf_ip); | |
unset($_SERVER['HTTP_CF_CONNECTING_IP']); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment