calc CIDR for wireguard
This commit is contained in:
+62
@@ -135,6 +135,9 @@ class Bot
|
||||
case preg_match('~^/changeAllowedIps (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->changeAllowedIps(...explode('_', $m['arg']));
|
||||
break;
|
||||
case preg_match('~^/calc (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->calc(...explode('_', $m['arg']));
|
||||
break;
|
||||
case preg_match('~^/changeIps (?P<arg>\w+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->changeIps(...explode('_', $m['arg']));
|
||||
break;
|
||||
@@ -1497,9 +1500,68 @@ DNS-over-HTTPS with IP:
|
||||
$this->subnet($page);
|
||||
}
|
||||
|
||||
public function calc($page)
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
"@{$this->input['username']} enter like '10.0.0.0/24, -10.0.0.5/32'",
|
||||
$this->input['message_id'],
|
||||
reply: 'enter like \'10.0.0.0/24, -10.0.0.5/32\'',
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'start_callback' => $this->input['callback_id'],
|
||||
'callback' => 'calcSubnet',
|
||||
'args' => [$page],
|
||||
];
|
||||
}
|
||||
|
||||
public function calcSubnet($text)
|
||||
{
|
||||
$text = explode(',', $text);
|
||||
$text = array_map(fn ($e) => trim($e), $text);
|
||||
if (!empty($text)) {
|
||||
foreach ($text as $k => $v) {
|
||||
if (preg_match('~^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}~', $v)) {
|
||||
$include[] = $v;
|
||||
}
|
||||
if (preg_match('~^-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2})~', $v, $m)) {
|
||||
$exclude[] = $m[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($include)) {
|
||||
foreach ($include as $k => $v) {
|
||||
$t = explode('/', $v);
|
||||
$include[$k] = [ip2long($t[0]), ip2long($t[0]) + (1 << (32 - $t[1])) - 1];
|
||||
}
|
||||
if (!empty($exclude)) {
|
||||
foreach ($exclude as $k => $v) {
|
||||
$t = explode('/', $v);
|
||||
$exclude[$k] = [ip2long($t[0]), ip2long($t[0]) + (1 << (32 - $t[1])) - 1];
|
||||
}
|
||||
}
|
||||
$c = new Calc();
|
||||
$r = $c->prepare($include, $exclude ?: []);
|
||||
if (!empty($r)) {
|
||||
$t = [];
|
||||
foreach ($r as $k => $v) {
|
||||
$t = array_merge($t, $c->toCIDR($v[0], $v[1]));
|
||||
}
|
||||
$this->send($this->input['chat'], '<pre>' . implode(', ', $t) . '</pre>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function subnet($page = 0, $count = 5)
|
||||
{
|
||||
$text = "Menu -> Wireguard -> " . $this->i18n('listSubnet') . "\n";
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('calc'),
|
||||
'callback_data' => "/calc $page",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add'),
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
class Calc
|
||||
{
|
||||
public function merge(array $a, array $b): array
|
||||
{
|
||||
if ($b[0] > $a[1] + 1) {
|
||||
$tmp = [$a, $b];
|
||||
} elseif ($b[1] <= $a[1]) {
|
||||
$tmp = [$a];
|
||||
} else {
|
||||
$tmp = [[$a[0], $b[1]]];
|
||||
}
|
||||
return array_filter($tmp);
|
||||
}
|
||||
|
||||
public function substract(array $a, array $b): array
|
||||
{
|
||||
if ($b[0] > $a[1] || $b[1] < $a[0]) {
|
||||
return [$a];
|
||||
} elseif ($b[0] <= $a[0] && $b[1] >= $a[1]) {
|
||||
return [];
|
||||
} elseif ($b[0] > $a[0] && $b[1] < $a[1]) {
|
||||
return [[$a[0], $b[0] - 1], [$b[1] + 1, $a[1]]];
|
||||
} elseif ($b[0] <= $a[0]) {
|
||||
return [$b[1] + 1, $a[1]];
|
||||
} else {
|
||||
return [$a[0], $b[1] - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public function alignment(array $arr): array
|
||||
{
|
||||
usort($arr, fn ($a, $b) => $a[0] <=> $b[0]);
|
||||
$tmp = [[]];
|
||||
foreach ($arr as $k => $v) {
|
||||
$t = array_pop($tmp);
|
||||
$tmp = array_merge($tmp, $this->merge($t, $v));
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
public function prepare(array $include, array $exclude): array
|
||||
{
|
||||
$include = $this->alignment($include);
|
||||
if (!empty($exclude)) {
|
||||
$tmp = [];
|
||||
$exclude = $this->alignment($exclude);
|
||||
foreach ($exclude as $k => $v) {
|
||||
foreach ($include as $i => $j) {
|
||||
$tmp = array_merge($tmp, $this->substract($j, $v));
|
||||
}
|
||||
$d = array_filter($tmp);
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
return $include;
|
||||
}
|
||||
|
||||
public function toCIDR(int $a, int $b)
|
||||
{
|
||||
$diff = $b - $a + 1;
|
||||
if ($diff > 1) {
|
||||
for ($i = 0; $i <= 32; $i++) {
|
||||
if ($diff / (1 << $i) < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tmp[] = long2ip($a) . "/" . (32 - $i + 1);
|
||||
$new = $a + (1 << ($i - 1));
|
||||
if ($new <= $b) {
|
||||
$tmp = array_merge($tmp, $this->toCIDR($new, $b));
|
||||
}
|
||||
} else {
|
||||
$tmp[] = long2ip($a) . "/32";
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
}
|
||||
@@ -217,4 +217,8 @@ $i = [
|
||||
'en' => 'AllowedIPs',
|
||||
'ru' => 'AllowedIPs',
|
||||
],
|
||||
'calc' => [
|
||||
'en' => 'calc CIDR',
|
||||
'ru' => 'calc CIDR',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ require __DIR__ . '/timezone.php';
|
||||
require __DIR__ . '/config.php';
|
||||
if ('POST' == $_SERVER['REQUEST_METHOD'] && $_GET['k'] == $c['key']) {
|
||||
// require __DIR__ . '/debug.php';
|
||||
require __DIR__ . '/calc.php';
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
|
||||
Reference in New Issue
Block a user