<?php
/*******************************************************************
 * 版权协议：2009-2019
 * 版权所有: PHP-北京金南曦网络技术有限公司旗下PHPWMS，PHP商城系统技术支持中心http://www.php188.net，并保留所有权利。 
* PHP商城系统网址: http://www.php188.com
 * PHPWMS系统网址：http://www.phpwms.com
 * 销售电话：010-87875088
 * 销售电话：010-87875188 
*------------------------------------------------------------------
 * 这不是一个完全免费软件！您只能在不用于商业目的的前提下对程序代码进
 * 行修改和使用；不允许对程序代码以任何形式任何目的的再发布。
 *------------------------------------------------------------------
 * 文件名称：cls_ip_search.php
 * 摘    要：IP归属地查询类
 * 适用范围：PHPWMS 1.0
 * 版    本：1.0
 *------------------------------------------------------------------
 * Script Written By phpwms项目组
 * 最后更新： 2009-09-24 phpwms 由PHP金南曦网络技术有限公司整理发布
 *******************************************************************/

	!defined('IN_SYS') and die('Hacking attempt');

	class IpSearch {
		var $fp;
		var $firstip;
		var $lastip;
		var $totalip;

		function __construct() {
			global $sys_dir;
			$filename = $sys_dir.CLASS_PATH.'ipdata.dat';
			if (($this -> fp = @fopen($filename,'rb')) !== false) {
				$this -> firstip = $this -> getLong();
				$this -> lastip  = $this -> getLong();
				$this -> totalip = ($this -> lastip - $this -> firstip) / 7;
				register_shutdown_function(array(&$this,'_IpLocation'));
			}
		}

		function getLong() {
			$result = unpack('Vlong',fread($this -> fp,4));

			return $result['long'];
		}

		function getLong3() {
			$result = unpack('Vlong',fread($this -> fp,3).chr(0));

			return $result['long'];
		}

		function packIp($ip) {
			return pack('N',intval(ip2long($ip)));
		}

		function getString($data = '') {
			$char = fread($this -> fp,1);
			while (ord($char) > 0)
			{
				$data .= $char;
				$char = fread($this -> fp,1);
			}

			return $data;
		}

		function getArea() {
			$byte = fread($this -> fp,1);

			switch (ord($byte)) {
				case 0:
					$area = '';
					break;
				case 1:
				case 2:
					fseek($this -> fp,$this -> getLong3());
					$area = $this -> getString();
					break;
				default:
					$area = $this -> getString($byte);
					break;
			}

			return $area;
		}

		function getLocation($ip) {
			if (!$this -> fp) {
				return NULL;
			}

			$location['ip'] = gethostbyname($ip);
			$ip = $this -> packIp($location['ip']);

			$ipone = ord($ip[0]);
			if ($ipone == 10 || $ipone == 127 || ($ipone == 192 && ord($ip[1]) == 168) || ($ipone == 172 && (ord($ip[1]) >= 16 && ord($ip[1]) <= 31))) {
				$location['country'] = '本地局域网';
				$location['area']    = '';

				return $location;
			}

			$l = 0;
			$u = $this -> totalip;
			$findip = $this -> lastip;
			while ($l <= $u) {
				$i = floor(($l + $u) / 2);
				fseek($this -> fp,$this -> firstip + $i * 7);
				$beginip = strrev(fread($this -> fp,4));

				if ($ip < $beginip) {
					$u = $i - 1;
				} else {
					fseek($this -> fp,$this -> getLong3());
					$endip = strrev(fread($this -> fp,4));
					if ($ip > $endip) {
						$l = $i + 1;
					} else {
						$findip = $this -> firstip + $i * 7;
						break;
					}
				}
			}

			fseek($this -> fp,$findip);
			$location['beginip'] = long2ip($this -> getLong());
			$offset = $this -> getLong3();
			fseek($this -> fp,$offset);
			$location['endip'] = long2ip($this -> getLong());
			$byte = fread($this -> fp,1);
			switch (ord($byte))	{
				case 1:
					$countryOffset = $this -> getLong3();
					fseek($this -> fp,$countryOffset);
					$byte = fread($this -> fp,1);
					switch (ord($byte)) {
						case 2:
							fseek($this -> fp,$this -> getLong3());
							$location['country'] = $this -> getString();
							fseek($this -> fp,$countryOffset + 4);
							$location['area'] = $this -> getArea();
							break;
						default:
							$location['country'] = $this -> getString($byte);
							$location['area'] = $this -> getArea();
							break;
					}
					break;
				case 2:
					fseek($this -> fp,$this -> getLong3());
					$location['country'] = $this -> getString();
					fseek($this -> fp,$offset + 8);
					$location['area'] = $this -> getArea();
					break;
				default:
					$location['country'] = $this -> getString($byte);
					$location['area'] = $this -> getArea();
					break;
			}
			if ($location['country'] == 'CZ88.NET') {
				$location['country'] = '';
			}
			if ($location['area'] == 'CZ88.NET') {
				$location['area'] = '';
			}

			return $location;
		}

		function _IpLocation() {
			fclose($this -> fp);
		}
	}
?>