mirror of https://github.com/tildeclub/site.git
				
				
				
			
		
			
	
	
		
			210 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
		
		
			
		
	
	
			210 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
|  | <?php | ||
|  | 	// CubicleSoft PHP IP Address functions.
 | ||
|  | 	// (C) 2013 CubicleSoft.  All Rights Reserved.
 | ||
|  | 
 | ||
|  | 	class IPAddr | ||
|  | 	{ | ||
|  | 		static function NormalizeIP($ipaddr) | ||
|  | 		{ | ||
|  | 			$ipv4addr = ""; | ||
|  | 			$ipv6addr = ""; | ||
|  | 
 | ||
|  | 			// Generate IPv6 address.
 | ||
|  | 			$ipaddr = strtolower(trim($ipaddr)); | ||
|  | 			if (strpos($ipaddr, ":") === false)  $ipaddr = "::ffff:" . $ipaddr; | ||
|  | 			$ipaddr = explode(":", $ipaddr); | ||
|  | 			if (count($ipaddr) < 3)  $ipaddr = array("", "", "0"); | ||
|  | 			$ipaddr2 = array(); | ||
|  | 			$foundpos = false; | ||
|  | 			foreach ($ipaddr as $num => $segment) | ||
|  | 			{ | ||
|  | 				$segment = trim($segment); | ||
|  | 				if ($segment != "")  $ipaddr2[] = $segment; | ||
|  | 				else if ($foundpos === false && count($ipaddr) > $num + 1 && $ipaddr[$num + 1] != "") | ||
|  | 				{ | ||
|  | 					$foundpos = count($ipaddr2); | ||
|  | 					$ipaddr2[] = "0000"; | ||
|  | 				} | ||
|  | 			} | ||
|  | 			// Convert ::ffff:123.123.123.123 format.
 | ||
|  | 			if (strpos($ipaddr2[count($ipaddr2) - 1], ".") !== false) | ||
|  | 			{ | ||
|  | 				$x = count($ipaddr2) - 1; | ||
|  | 				if ($ipaddr2[count($ipaddr2) - 2] != "ffff")  $ipaddr2[$x] = "0"; | ||
|  | 				else | ||
|  | 				{ | ||
|  | 					$ipaddr = explode(".", $ipaddr2[$x]); | ||
|  | 					if (count($ipaddr) != 4)  $ipaddr2[$x] = "0"; | ||
|  | 					else | ||
|  | 					{ | ||
|  | 						$ipaddr2[$x] = str_pad(strtolower(dechex($ipaddr[0])), 2, "0", STR_PAD_LEFT) . str_pad(strtolower(dechex($ipaddr[1])), 2, "0", STR_PAD_LEFT); | ||
|  | 						$ipaddr2[] = str_pad(strtolower(dechex($ipaddr[2])), 2, "0", STR_PAD_LEFT) . str_pad(strtolower(dechex($ipaddr[3])), 2, "0", STR_PAD_LEFT); | ||
|  | 					} | ||
|  | 				} | ||
|  | 			} | ||
|  | 			$ipaddr = array_slice($ipaddr2, 0, 8); | ||
|  | 			if ($foundpos !== false && count($ipaddr) < 8)  array_splice($ipaddr, $foundpos, 0, array_fill(0, 8 - count($ipaddr), "0000")); | ||
|  | 			foreach ($ipaddr as $num => $segment) | ||
|  | 			{ | ||
|  | 				$ipaddr[$num] = substr(str_pad(strtolower(dechex(hexdec($segment))), 4, "0", STR_PAD_LEFT), -4); | ||
|  | 			} | ||
|  | 			$ipv6addr = implode(":", $ipaddr); | ||
|  | 
 | ||
|  | 			// Extract IPv4 address.
 | ||
|  | 			if (substr($ipv6addr, 0, 30) == "0000:0000:0000:0000:0000:ffff:")  $ipv4addr = hexdec(substr($ipv6addr, 30, 2)) . "." . hexdec(substr($ipv6addr, 32, 2)) . "." . hexdec(substr($ipv6addr, 35, 2)) . "." . hexdec(substr($ipv6addr, 37, 2)); | ||
|  | 
 | ||
|  | 			// Make a short IPv6 address.
 | ||
|  | 			$shortipv6 = $ipv6addr; | ||
|  | 			$pattern = "0000:0000:0000:0000:0000:0000:0000"; | ||
|  | 			do | ||
|  | 			{ | ||
|  | 				$shortipv6 = str_replace($pattern, ":", $shortipv6); | ||
|  | 				$pattern = substr($pattern, 5); | ||
|  | 			} while (strlen($shortipv6) == 39 && $pattern != ""); | ||
|  | 			$shortipv6 = explode(":", $shortipv6); | ||
|  | 			foreach ($shortipv6 as $num => $segment) | ||
|  | 			{ | ||
|  | 				if ($segment != "")  $shortipv6[$num] = strtolower(dechex(hexdec($segment))); | ||
|  | 			} | ||
|  | 			$shortipv6 = implode(":", $shortipv6); | ||
|  | 
 | ||
|  | 			return array("ipv6" => $ipv6addr, "shortipv6" => $shortipv6, "ipv4" => $ipv4addr); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		static function GetRemoteIP($proxies = array()) | ||
|  | 		{ | ||
|  | 			$ipaddr = self::NormalizeIP(isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : "127.0.0.1"); | ||
|  | 
 | ||
|  | 			// Check for trusted proxies.  Stop at first untrusted IP in the chain.
 | ||
|  | 			if (isset($proxies[$ipaddr["ipv6"]]) || ($ipaddr["ipv4"] != "" && isset($proxies[$ipaddr["ipv4"]]))) | ||
|  | 			{ | ||
|  | 				$xforward = (isset($_SERVER["HTTP_X_FORWARDED_FOR"]) ? explode(",", $_SERVER["HTTP_X_FORWARDED_FOR"]) : array()); | ||
|  | 				$clientip = (isset($_SERVER["HTTP_CLIENT_IP"]) ? explode(",", $_SERVER["HTTP_CLIENT_IP"]) : array()); | ||
|  | 
 | ||
|  | 				do | ||
|  | 				{ | ||
|  | 					$found = false; | ||
|  | 
 | ||
|  | 					if (isset($proxies[$ipaddr["ipv6"]]))  $header = $proxies[$ipaddr["ipv6"]]; | ||
|  | 					else  $header = $proxies[$ipaddr["ipv4"]]; | ||
|  | 
 | ||
|  | 					$header = strtolower($header); | ||
|  | 					if ($header == "xforward" && count($xforward) > 0) | ||
|  | 					{ | ||
|  | 						$ipaddr = self::NormalizeIP(array_pop($xforward)); | ||
|  | 						$found = true; | ||
|  | 					} | ||
|  | 					else if ($header == "clientip" && count($clientip) > 0) | ||
|  | 					{ | ||
|  | 						$ipaddr = self::NormalizeIP(array_pop($clientip)); | ||
|  | 						$found = true; | ||
|  | 					} | ||
|  | 				} while ($found && (isset($proxies[$ipaddr["ipv6"]]) || ($ipaddr["ipv4"] != "" && isset($proxies[$ipaddr["ipv4"]])))); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return $ipaddr; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		static function IsMatch($pattern, $ipaddr) | ||
|  | 		{ | ||
|  | 			if (is_string($ipaddr))  $ipaddr = self::NormalizeIP($ipaddr); | ||
|  | 
 | ||
|  | 			if (strpos($pattern, ":") !== false) | ||
|  | 			{ | ||
|  | 				// Pattern is IPv6.
 | ||
|  | 				$pattern = explode(":", strtolower($pattern)); | ||
|  | 				$ipaddr = explode(":", $ipaddr["ipv6"]); | ||
|  | 				if (count($pattern) != 8 || count($ipaddr) != 8)  return false; | ||
|  | 				foreach ($pattern as $num => $segment) | ||
|  | 				{ | ||
|  | 					$found = false; | ||
|  | 					$pieces = explode(",", $segment); | ||
|  | 					foreach ($pieces as $piece) | ||
|  | 					{ | ||
|  | 						$piece = trim($piece); | ||
|  | 						$piece = explode(".", $piece); | ||
|  | 						if (count($piece) == 1) | ||
|  | 						{ | ||
|  | 							$piece = $piece[0]; | ||
|  | 
 | ||
|  | 							if ($piece == "*")  $found = true; | ||
|  | 							else if (strpos($piece, "-") !== false) | ||
|  | 							{ | ||
|  | 								$range = explode("-", $piece); | ||
|  | 								$range[0] = hexdec($range[0]); | ||
|  | 								$range[1] = hexdec($range[1]); | ||
|  | 								$val = hexdec($ipaddr[$num]); | ||
|  | 								if ($range[0] > $range[1])  $range[0] = $range[1]; | ||
|  | 								if ($val >= $range[0] && $val <= $range[1])  $found = true; | ||
|  | 							} | ||
|  | 							else if ($piece === $ipaddr[$num])  $found = true; | ||
|  | 						} | ||
|  | 						else if (count($piece) == 2) | ||
|  | 						{ | ||
|  | 							// Special IPv4-like notation.
 | ||
|  | 							$found2 = false; | ||
|  | 							$found3 = false; | ||
|  | 							$val = hexdec(substr($ipaddr[$num], 0, 2)); | ||
|  | 							$val2 = hexdec(substr($ipaddr[$num], 2, 2)); | ||
|  | 
 | ||
|  | 							if ($piece[0] == "*")  $found2 = true; | ||
|  | 							else if (strpos($piece[0], "-") !== false) | ||
|  | 							{ | ||
|  | 								$range = explode("-", $piece[0]); | ||
|  | 								if ($range[0] > $range[1])  $range[0] = $range[1]; | ||
|  | 								if ($val >= $range[0] && $val <= $range[1])  $found2 = true; | ||
|  | 							} | ||
|  | 							else if ($piece[0] == $val)  $found2 = true; | ||
|  | 
 | ||
|  | 							if ($piece[1] == "*")  $found3 = true; | ||
|  | 							else if (strpos($piece[1], "-") !== false) | ||
|  | 							{ | ||
|  | 								$range = explode("-", $piece[1]); | ||
|  | 								if ($range[0] > $range[1])  $range[0] = $range[1]; | ||
|  | 								if ($val >= $range[0] && $val <= $range[1])  $found3 = true; | ||
|  | 							} | ||
|  | 							else if ($piece[1] == $val2)  $found3 = true; | ||
|  | 
 | ||
|  | 							if ($found2 && $found3)  $found = true; | ||
|  | 						} | ||
|  | 
 | ||
|  | 						if ($found)  break; | ||
|  | 					} | ||
|  | 
 | ||
|  | 					if (!$found)  return false; | ||
|  | 				} | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				// Pattern is IPv4.
 | ||
|  | 				$pattern = explode(".", strtolower($pattern)); | ||
|  | 				$ipaddr = explode(".", $ipaddr["ipv4"]); | ||
|  | 				if (count($pattern) != 4 || count($ipaddr) != 4)  return false; | ||
|  | 				foreach ($pattern as $num => $segment) | ||
|  | 				{ | ||
|  | 					$found = false; | ||
|  | 					$pieces = explode(",", $segment); | ||
|  | 					foreach ($pieces as $piece) | ||
|  | 					{ | ||
|  | 						$piece = trim($piece); | ||
|  | 
 | ||
|  | 						if ($piece == "*")  $found = true; | ||
|  | 						else if (strpos($piece, "-") !== false) | ||
|  | 						{ | ||
|  | 							$range = explode("-", $piece); | ||
|  | 							if ($range[0] > $range[1])  $range[0] = $range[1]; | ||
|  | 							if ($ipaddr[$num] >= $range[0] && $ipaddr[$num] <= $range[1])  $found = true; | ||
|  | 						} | ||
|  | 						else if ($piece == $ipaddr[$num])  $found = true; | ||
|  | 
 | ||
|  | 						if ($found)  break; | ||
|  | 					} | ||
|  | 
 | ||
|  | 					if (!$found)  return false; | ||
|  | 				} | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return true; | ||
|  | 		} | ||
|  | 	} | ||
|  | ?>
 |