diff --git a/backend/country.php b/backend/country.php new file mode 100644 index 0000000..1b87572 --- /dev/null +++ b/backend/country.php @@ -0,0 +1,35 @@ +open('country.db'); // 国家地区缩写及代号数据库 + } +} + +function getCountry($code) { // 根据两位国家代码获取英文与中文全称 + if ($code == null) { + return null; + } + $db = new countryDB; + $raw = $db->query('SELECT * FROM main WHERE alpha_2="'.$code.'";')->fetchArray(SQLITE3_ASSOC); + $data['code'] = $code; + if ($raw) { + $data['en'] = $raw['name_en']; + $data['cn'] = $raw['name_cn']; + } else { + $data['en'] = "Unknow"; + $data['cn'] = null; + } + return $data; +} + +?> \ No newline at end of file diff --git a/backend/getCountry.php b/backend/getCountry.php deleted file mode 100644 index 6ba12aa..0000000 --- a/backend/getCountry.php +++ /dev/null @@ -1,23 +0,0 @@ -open('country.db'); // 国家地区缩写及代号数据库 - } -} - -function getCountry($code) { // 根据两位国家代码获取英文与中文全称 - $db = new countryDB; - if ($code == null) { - return null; - } - $dat = $db->query('SELECT * FROM main WHERE alpha_2="'.$code.'";')->fetchArray(SQLITE3_ASSOC); - if ($dat) { - $name_dat['en'] = $code." - ".$dat['name_en']; - $name_dat['cn'] = $dat['name_cn']; - } else { - $name_dat['en'] = $code." - Unknow"; - $name_dat['cn'] = null; - } - return $name_dat; -} diff --git a/backend/getInfo.php b/backend/getInfo.php deleted file mode 100644 index 9b9fbc1..0000000 --- a/backend/getInfo.php +++ /dev/null @@ -1,125 +0,0 @@ -getDetail($ip); - $specialInfo = getSpecialInfo($ip); - if (is_string($specialInfo)) { - $info['ip'] = $ip; - $info['as'] = null; - $info['city'] = null; - $info['region'] = null; - $info['country'] = null; - $info['timezone'] = null; - $info['loc'] = null; - $info['isp'] = $specialInfo; - } else { - $rawIspInfo = getInfo($ip); - $info['ip'] = $ip; - $info['as'] = getAS($rawIspInfo); - $info['city'] = $rawIspInfo['city']; - $info['region'] = $rawIspInfo['region']; - $info['country'] = getCountry($rawIspInfo['country'])['en']; - $info['country'] .= "(".getCountry($rawIspInfo['country'])['cn'].")"; - $info['timezone'] = $rawIspInfo['timezone']; - $info['loc'] = $rawIspInfo['loc']; - $info['isp'] = getIsp($rawIspInfo); - } - $info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']); - $info['detail'] = $detail['dataA'] . $detail['dataB']; - - if ($_GET['cli'] == "true") { // 使用命令行模式 - $cli = "IP: ".$info['ip'] . PHP_EOL; - $cli .= "AS: ".$info['as'] . PHP_EOL; - $cli .= "City: ".$info['city'] . PHP_EOL; - $cli .= "Region: ".$info['region'] . PHP_EOL; - $cli .= "Country: ".$info['country'] . PHP_EOL; - $cli .= "Timezone: ".$info['timezone'] . PHP_EOL; - $cli .= "Location: ".$info['loc'] . PHP_EOL; - $cli .= "ISP: ".$info['isp'] . PHP_EOL; - $cli .= "Scope: ".$info['scope'] . PHP_EOL; - $cli .= "Detail: ".$info['detail'] . PHP_EOL; - return $cli; - } - - header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送 - return json_encode($info); -} - -function getSpecialInfo($ip) { // 识别特殊IP地址 - if ('::1' === $ip) { - return 'localhost IPv6 access'; - } - if (stripos($ip, 'fe80:') === 0) { - return 'link-local IPv6 access'; - } - if (strpos($ip, '127.') === 0) { - return 'localhost IPv4 access'; - } - if (strpos($ip, '10.') === 0) { - return 'private IPv4 access'; - } - if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) { - return 'private IPv4 access'; - } - if (strpos($ip, '192.168.') === 0) { - return 'private IPv4 access'; - } - if (strpos($ip, '169.254.') === 0) { - return 'link-local IPv4 access'; - } - return null; -} - -function getInfo($ip) { // 获取IP详细信息 - $json = file_get_contents('https://ipinfo.io/' . $ip . '/json'); - if (!is_string($json)) { - return null; - } - $data = json_decode($json, true); - if (!is_array($data)) { - return null; - } - return $data; -} - -function getIsp($rawIspInfo) { // 提取ISP信息 - if ( - !is_array($rawIspInfo) - || !array_key_exists('org', $rawIspInfo) - || !is_string($rawIspInfo['org']) - || empty($rawIspInfo['org']) - ) { - return 'Unknown ISP'; - } - return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']); -} - -function getAS($rawIspInfo) { // 提取AS信息 - if ( - !is_array($rawIspInfo) - || !array_key_exists('org', $rawIspInfo) - || !is_string($rawIspInfo['org']) - || empty($rawIspInfo['org']) - ) { - return 'Unknown AS'; - } - if (preg_match('/AS\\d+\\s/', $rawIspInfo['org'], $as) !== 1) { - return 'Unknown AS'; - } - return trim($as['0']); -} - -function tryCIDR($beginIP, $endIP) { - $tmp = ip2long($endIP) - ip2long($beginIP) + 1; - if (pow(2, intval(log($tmp, 2))) == $tmp) { - return $beginIP . '/' . (32 - log($tmp, 2)); - } else { - return $beginIP . ' - ' . $endIP; - } -} - -?> diff --git a/backend/ipinfo.php b/backend/ipinfo.php new file mode 100644 index 0000000..5b15807 --- /dev/null +++ b/backend/ipinfo.php @@ -0,0 +1,71 @@ + \ No newline at end of file diff --git a/backend/qqwry.dat b/backend/qqwry.dat index de2efb9..05fa23b 100644 Binary files a/backend/qqwry.dat and b/backend/qqwry.dat differ diff --git a/backend/qqwry.php b/backend/qqwry.php index a6584cf..db9226c 100644 --- a/backend/qqwry.php +++ b/backend/qqwry.php @@ -1,25 +1,36 @@ fp = 0; - if (($this->fp = fopen(__DIR__ . '/qqwry.dat', 'rb')) !== false) { - $this->firstRecord = $this->read4byte(); - $this->lastRecord = $this->read4byte(); - $this->recordNum = ($this->lastRecord - $this->firstRecord) / 7; // 每条索引长度为7字节 - } + public function __construct($fileName) { // 构造函数 + $this->fp = fopen($fileName, 'rb'); + $this->firstRecord = $this->read4byte(); + $this->lastRecord = $this->read4byte(); + $this->recordNum = ($this->lastRecord - $this->firstRecord) / 7; // 每条索引长度为7字节 } public function __destruct() { // 析构函数 if ($this->fp) { fclose($this->fp); } - $this->fp = 0; } private function read4byte() { // 读取4字节并转为long @@ -151,3 +162,5 @@ class QQWry { } } } + +?> \ No newline at end of file diff --git a/backend/queryInfo.php b/backend/queryInfo.php index feeb80c..48df7f4 100644 --- a/backend/queryInfo.php +++ b/backend/queryInfo.php @@ -1,14 +1,100 @@ getDetail($ip); + $specialInfo = checkSpecial($ip); + if (is_string($specialInfo)) { + $info['ip'] = $ip; + $info['as'] = null; + $info['city'] = null; + $info['region'] = null; + $info['country'] = null; + $info['timezone'] = null; + $info['loc'] = null; + $info['isp'] = $specialInfo; + } else { + $data = IPinfo::getInfo($ip); + $country = getCountry($data['country']); + $info['ip'] = $data['ip']; + $info['as'] = $data['as']; + $info['city'] = $data['city']; + $info['region'] = $data['region']; + $info['country'] = $data['country'] . ' - ' . $country['en']; + $info['country'] .= "(" . $country['cn'] . ")"; + $info['timezone'] = $data['timezone']; + $info['loc'] = $data['loc']; + $info['isp'] = $data['isp']; + } + $info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']); + $info['detail'] = $detail['dataA'] . $detail['dataB']; -if (!filter_var($ip, \FILTER_VALIDATE_IP)) { - echo "Illegal IP format".PHP_EOL; - exit; + if ($_GET['cli'] == "true") { // 使用命令行模式 + $cli = "IP: ".$info['ip'] . PHP_EOL; + $cli .= "AS: ".$info['as'] . PHP_EOL; + $cli .= "City: ".$info['city'] . PHP_EOL; + $cli .= "Region: ".$info['region'] . PHP_EOL; + $cli .= "Country: ".$info['country'] . PHP_EOL; + $cli .= "Timezone: ".$info['timezone'] . PHP_EOL; + $cli .= "Location: ".$info['loc'] . PHP_EOL; + $cli .= "ISP: ".$info['isp'] . PHP_EOL; + $cli .= "Scope: ".$info['scope'] . PHP_EOL; + $cli .= "Detail: ".$info['detail'] . PHP_EOL; + return $cli; + } + + header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送 + return json_encode($info); +} + +function checkSpecial($ip) { // 检查特殊IP地址并返回说明 + if ('::1' === $ip) { + return 'localhost IPv6 access'; + } + if (stripos($ip, 'fe80:') === 0) { + return 'link-local IPv6 access'; + } + if (strpos($ip, '127.') === 0) { + return 'localhost IPv4 access'; + } + if (strpos($ip, '10.') === 0) { + return 'private IPv4 access'; + } + if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) { + return 'private IPv4 access'; + } + if (strpos($ip, '192.168.') === 0) { + return 'private IPv4 access'; + } + if (strpos($ip, '169.254.') === 0) { + return 'link-local IPv4 access'; + } + return null; +} + +function tryCIDR($beginIP, $endIP) { // 给定IP范围,尝试计算CIDR + $tmp = ip2long($endIP) - ip2long($beginIP) + 1; + if (pow(2, intval(log($tmp, 2))) == $tmp) { // 判断是否为2的整数次方 + return $beginIP . '/' . (32 - log($tmp, 2)); + } else { + return $beginIP . ' - ' . $endIP; + } +} + +function main() { + $ip = $_GET['ip']; + if (!filter_var($ip, \FILTER_VALIDATE_IP)) { + echo "Illegal IP format".PHP_EOL; + exit; + } + echo getIPInfo($ip); } -echo getIPInfo($ip); +main(); ?>