From 1cd712b22c48840bf343c5aecc060124e6e31347 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 29 Aug 2021 11:56:03 +0800 Subject: [PATCH] update: more special IPv6 range --- backend/getInfo.php | 4 +- backend/specialIP.php | 175 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 166 insertions(+), 13 deletions(-) diff --git a/backend/getInfo.php b/backend/getInfo.php index cdca586..a934c1f 100644 --- a/backend/getInfo.php +++ b/backend/getInfo.php @@ -8,7 +8,9 @@ include("cityCN.php"); include("specialIP.php"); function getIPInfo($ip) { - // TODO: format ipv6 + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $ip = long2ip6(ip2long6($ip)); // 压缩IPv6地址 + } $specialInfo = checkSpecial($ip); // 检查是否为特殊IP段 if ($specialInfo !== null) { $info['ip'] = $ip; diff --git a/backend/specialIP.php b/backend/specialIP.php index 6e6baaa..3b072bd 100644 --- a/backend/specialIP.php +++ b/backend/specialIP.php @@ -105,6 +105,131 @@ $specialIPv4 = array( ] ); +// data from: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + +$specialIPv6 = array( + [ + 'scope' => '::1/128', + 'range' => '::1 - ::1', + 'descEn' => 'Loopback Address', + 'descCn' => '环回地址' + ], + [ + 'scope' => '::/128', + 'range' => ':: - ::', + 'descEn' => 'Unspecified Address', + 'descCn' => '未指定地址' + ], + [ + 'scope' => '::ffff:0:0/96', + 'range' => '::ffff:0:0 - ::ffff:ffff:ffff', + 'descEn' => 'IPv4-mapped Address', + 'descCn' => 'IPv4映射地址' + ], + [ + 'scope' => '64:ff9b::/96', + 'range' => '64:ff9b:: - 64:ff9b::ffff:ffff', + 'descEn' => 'IPv4-IPv6 Translat', + 'descCn' => 'IPv4转IPv6地址' + ], + [ + 'scope' => '64:ff9b:1::/48', + 'range' => '64:ff9b:1:: - 64:ff9b:1:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'IPv4-IPv6 Translat', + 'descCn' => 'IPv4转IPv6地址' + ], + [ + 'scope' => '100::/64', + 'range' => '100:: - 100::ffff:ffff:ffff:ffff', + 'descEn' => 'Discard-Only Address Block', + 'descCn' => '仅丢弃块地址' + ], + [ + 'scope' => '2001:1::1/128', + 'range' => '2001:1::1 - 2001:1::1', + 'descEn' => 'Port Control Protocol Anycast', + 'descCn' => '端口控制协议任播地址' + ], + [ + 'scope' => '2001:1::2/128', + 'range' => '2001:1::2 - 2001:1::2', + 'descEn' => 'Traversal Using Relays around NAT Anycast', + 'descCn' => '中继遍历NAT任播地址' + ], + [ + 'scope' => '2001:2::/48', + 'range' => '2001:2:: - 2001:2::ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'Benchmarking', + 'descCn' => '基准测试地址' + ], + [ + 'scope' => '2001:3::/32', + 'range' => '2001:3:: - 2001:3:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'AMT', + 'descCn' => 'AMT地址' + ], + // [ + // 'scope' => '2001:4:112::/48', + // 'range' => '2001:4:112:: - 2001:4:112:ffff:ffff:ffff:ffff:ffff', + // 'descEn' => 'AS112-v6', + // 'descCn' => '' + // ], + [ + 'scope' => '2001:10::/28', + 'range' => '2001:10:: - 2001:1f:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'Deprecated (previously ORCHID)', + 'descCn' => 'ORCHID地址(已弃用)' + ], + [ + 'scope' => '2001:20::/28', + 'range' => '2001:20:: - 2001:2f:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'ORCHIDv2', + 'descCn' => 'ORCHIDv2地址' + ], + [ + 'scope' => '2001::/23', + 'range' => '2001:: - 2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'IETF Protocol Assignments', + 'descCn' => 'IETF协议分配地址' + ], + [ + 'scope' => '2001:db8::/32', + 'range' => '2001:db8:: - 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'Documentation', + 'descCn' => '文档地址' + ], + [ + 'scope' => '2001::/32', + 'range' => '2001:: - 2001::ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'TEREDO', + 'descCn' => 'TEREDO地址' + ], + [ + 'scope' => '2002::/16', + 'range' => '2002:: - 2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'IPv6 to IPv4', + 'descCn' => 'IPv6转IPv4地址' + ], + // [ + // 'scope' => '2620:4f:8000::/48', + // 'range' => '2620:4f:8000:: - 2620:4f:8000:ffff:ffff:ffff:ffff:ffff', + // 'descEn' => 'Direct Delegation AS112 Service', + // 'descCn' => '' + // ], + [ + 'scope' => 'fc00::/7', + 'range' => 'fc00:: - fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'Unique-Local', + 'descCn' => '唯一本地地址' + ], + [ + 'scope' => 'fe80::/10', + 'range' => 'fe80:: - febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'descEn' => 'Link-Local Unicast', + 'descCn' => '链路本地地址' + ], +); + function cidrToRange($cidr) { // CIDR转IP段 $cidr = explode('/', $cidr); $range['start'] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1])))); @@ -112,6 +237,34 @@ function cidrToRange($cidr) { // CIDR转IP段 return $range; } +function ip2long6($ipv6) { // 压缩IPv6地址为long + $ip_n = inet_pton($ipv6); + $bits = 15; + while ($bits >= 0) { + $bin = sprintf("%08b", (ord($ip_n[$bits]))); + $ipv6long = $bin.$ipv6long; + $bits--; + } + return gmp_strval(gmp_init($ipv6long, 2), 10); +} + +function long2ip6($ipv6long) { // 解压long为IPv6地址 + $bin = gmp_strval(gmp_init($ipv6long, 10), 2); + if (strlen($bin) < 128) { + $pad = 128 - strlen($bin); + for ($i = 1; $i <= $pad; $i++) { + $bin = '0' . $bin; + } + } + $bits = 0; + while ($bits <= 7) { + $bin_part = substr($bin, ($bits * 16), 16); + $ipv6 .= dechex(bindec($bin_part)) . ':'; + $bits++; + } + return inet_ntop(inet_pton(substr($ipv6, 0, -1))); +} + function checkSpecialIPv4($ip) { // 检查特殊IPv4地址 global $specialIPv4; $ipv4 = ip2long($ip); @@ -130,22 +283,20 @@ function checkSpecialIPv4($ip) { // 检查特殊IPv4地址 } function checkSpecialIPv6($ip) { // 检查特殊IPv6地址 - // TODO: More IPv6 range - if ('::1' === $ip) { - $info['scope'] = '::1/128'; - $info['en'] = 'localhost IPv6 access'; - $info['cn'] = '本地IPv6地址'; - } - if (stripos($ip, 'fe80:') === 0) { - $info['scope'] = 'fe80::/16'; - $info['en'] = 'link-local IPv6 access'; - $info['cn'] = '链路本地IPv6地址'; + global $specialIPv6; + $ipv6 = ip2long6($ip); + foreach ($specialIPv6 as $special) { + $range = explode(' - ', $special['range']); + if ($ipv6 >= ip2long6($range[0]) && $ipv6 <= ip2long6($range[1])) { + unset($special['range']); + return $special; + } } - return isset($info) ? $info : null; + return null; // 非特殊地址 } function checkSpecial($ip) { // 检查特殊IP地址并返回说明 - if (filter_var($ip, \FILTER_VALIDATE_IP,\FILTER_FLAG_IPV4)) { // IPv4 + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { // IPv4 return checkSpecialIPv4($ip); } else { return checkSpecialIPv6($ip);