// 檢查連線 ip 是否在學校的 ip 範圍裡
//$test_mode=true;
$test_mode=false;
function ip_check(){
global $test_mode;
global $school_ip_net;
// ********************************************************************
// 學校校內網段設定 這三個網段一定要設定
$school_ip_net[0] = "172.20.2.1/24"; //內部虛擬網路
$school_ip_net[1] = "192.168.1.1/24"; //外部真實 IPv4
$school_ip_net[2] = "163.23.108.64/26"; //外部真實 IPv4
$school_ip_net[3] = "2001:288:56AB::/48"; //外部真實 IPv6
$school_ip_net[test] = "175.182.36.132/32"; //在校外測試時的 IPv4
// 連線的外部 ip
$out_ip=$_SERVER["REMOTE_ADDR"];
// ********************************************************************
// 判斷外部連線是 IPv4 還是 IPv6
function check_ipv4_or_6(){
$ip = $_SERVER['REMOTE_ADDR'];
$ipv6 = preg_match("/^[0-9a-f]{1,4}:([0-9a-f]{0,4}:){1,6}[0-9a-f]{1,4}$/", $ip);
$ipv4 = preg_match("/^([0-9]{1,3}\.){3}[0-9]{1,3}$/", $ip);
// 測試 開始
global $test_mode;
if ($test_mode){
echo "test mode...
";
echo $ip;
echo "
";
if ( $ipv4) echo "is IPv4";
if (! $ipv4) echo "not IPv4";
echo "
";
if ( $ipv6) echo "is IPv6";
if (! $ipv6) echo "not IPv6";
echo "
";
}
// 測試 結束
//$test_ipv6 = new ipv6();
//echo $test_ipv6;
// 測試
if ( $ipv6 != 0 ) return "IPv6";
elseif ( $ipv4 != 0 ) return "IPv4";
else return "unknown";
}
// ********************************************************************
// matchCIDR() - 判斷兩個地址是否在某個子網内
// @param $addr 地址IP ex.. 1.2.3.4
// @param $cidr 網段範圍 ex .. 1.2.3.5/24
// @return 同網段回傳 1 否則回傳 null
// 檢查 連線ip 是否在某範圍內 for IPV4
function check_ipv4_net($addr, $cidr) {
list($ip, $mask) = explode('/', $cidr);
return (ip2long($addr) >> (32 - $mask) == ip2long($ip) >> (32 - $mask));
};
class ipv6{
// 這個是 check_ipv6_net 所用到的函式
function ExpandIPv6Notation2Bin($ip6) {
if (strpos($ip6, '::') !== false)
$ip6 = str_replace('::', str_repeat(':0', 8 - substr_count($ip6, ':')).':', $ip6);
$ip6parts = explode(':', $ip6);
$res="";
foreach ($ip6parts as $part)
$res .= str_pad(base_convert( $part, 16, 2), 16, 0, STR_PAD_LEFT);
return $res;
}
// 檢查 連線ip 是否在某範圍內 for IPV6
Function check_ipv6_net( $cidr6, $chkipv6)
{ // 網段, 外部 IP
list($ip6, $prefixlen) = explode('/', $cidr6);
$cidrbin= substr( $this->ExpandIPv6Notation2Bin($ip6), 0, $prefixlen);
$chkip6bin= substr( $this->ExpandIPv6Notation2Bin($chkipv6), 0, $prefixlen);
if(! strcmp($cidrbin,$chkip6bin))return true;
return false;
}
}
// ********************************************************************
// 這是配合 ipv4,ipv6 兩種環境所寫
//
if (check_ipv4_or_6()=="IPv4")
{ //如果連線進來的ip是IPv4的話
if( check_ipv4_net($out_ip, $school_ip_net[2]))
{ // 檢測 172.20.2.1/24 網段
if ($test_mode) echo "連線 ip 是 172.20.2.1 網段...
";
return "school_inside";
}
elseif(check_ipv4_net($out_ip, $school_ip_net[0]))
{ // 檢測 192.168.1.1/24 網段
if ($test_mode) echo "連線 ip 是 192.168.1.1 網段...
";
return "school_inside";
}
elseif(check_ipv4_net($out_ip, $school_ip_net[1]))
{ // 檢測 163.23.108.65/26 網段
if ($test_mode) echo "連線 ip 是 163.23.108.65-126 網段...
";
return "school_inside";
}
elseif(check_ipv4_net($out_ip, $school_ip_net[test]))
{ // 檢測 163.23.108.65/26 網段
if ($test_mode){ echo "連線 ip 是 測試 網段...
";}
return "school_inside";
}
else
{
if ($test_mode) echo "連線 ip 雖屬於 ipv4,但不屬於 合法範圍網段...
";
return "school_outside";
}
}
//
elseif (check_ipv4_or_6()=="IPv6")
{ // 檢測 2001:288:56AB::/48 網段
$o_ipv6 = new ipv6();
if($o_ipv6->check_ipv6_net($school_ip_net[3],$out_ip))
{
if ($test_mode) echo "連線 ip 屬於 合法 ipv6 範圍網段...
";
echo "IPV6...";
return "school_inside";
}
}
else
{
if ($test_mode) echo "連線 ip 不屬於 ipv4,也不屬於 ipv6 之合法範圍網段...
";
return "school_outside";
}
//巢狀判斷式 結束
}
//echo ip_check();
?>