http://modulesgarden.com * CONTACT -> contact@modulesgarden.com * * * This software is furnished under a license and may be used and copied * only in accordance with the terms of such license and with the * inclusion of the above copyright notice. This software or any other * copies thereof may not be provided or otherwise made available to any * other person. No title to and ownership of the software is hereby * transferred. * * * ******************************************************************** */ namespace ModulesGarden\ProxmoxAddon\App\UI\IpManagement\Providers; use ModulesGarden\ProxmoxAddon as main; use ModulesGarden\ProxmoxAddon\App\Libs\BigInteger; use ModulesGarden\ProxmoxAddon\Core\UI\Interfaces\AdminArea; use ModulesGarden\ProxmoxAddon\Core\UI\ResponseTemplates\HtmlDataJsonResponse; use ModulesGarden\ProxmoxAddon\Core\UI\Widget\Forms\DataProviders\BaseModelDataProvider; use function ModulesGarden\ProxmoxAddon\App\Libs\inet_itop; use function ModulesGarden\ProxmoxAddon\App\Libs\inet_ptoi; use function ModulesGarden\ProxmoxAddon\App\Libs\ipv6_range; use function ModulesGarden\ProxmoxAddon\Core\Helper\sl; /** * * Description of RangeVmProvider * * @author Pawel Kopec */ class IpAddressProvider extends BaseModelDataProvider implements AdminArea { public function __construct() { parent::__construct(main\App\Models\IpAddress::class); } public function read() { if (!$this->actionElementId) { return false; } $dbData = $this->model->where('id', $this->actionElementId)->first(); if ($dbData === null) { return; } $data = $dbData->toArray(); //Node $this->data['node'] = []; $this->data['node']['value'] = $data['node']; unset($data['node']); //sid $this->data['sid'] = []; $this->data['sid']['value'] = $data['sid']; unset($data['sid']); //visualization $this->data['visualization'] = []; $this->data['visualization']['value'] = $data['visualization']; unset($data['visualization']); //private $this->data['private'] = $data['private'] == "1" ? "on" : "off"; unset($data['private']); $this->data = array_merge($this->data, $data); sl('lang')->addReplacementConstant('ip', $this->data['ip']); } public function create() { try { $form = $this->getFormDataValues(); if (preg_match('/\:/', $this->formData['ipPool'])) { $pool = $this->createIpv6Pool($this->formData['ipPool'], $this->formData['cidr']); $type = 'IPv6'; } else { $pool = $this->createIpv4Pool($this->formData['ipPool'], $this->formData['cidr']); $type = 'IPv4'; } foreach ($pool as $ip) { if (main\App\Models\IpAddress::where("ip", $ip)->count()) { continue; } $attributes = $this->formData; $attributes['ip'] = $ip; $attributes['private'] = $this->formData['private'] == "on" ? "1" : "0"; $attributes['trunks'] = (int)$this->formData['trunks'] > 0 ? $this->formData['trunks'] : null; $attributes['tag'] = (int)$this->formData['tag'] > 0 ? $this->formData['tag'] : null; $attributes['type'] = $type; $attributes['hostingId'] = 0; $ipAddress = new main\App\Models\IpAddress(); $ipAddress->fill($attributes)->save(); unset($ipAddress); } main\Core\ServiceLocator::call('lang')->addReplacementConstant("ipPool", $this->formData['ipPool']) ->addReplacementConstant("cidr", $this->formData['cidr']); return (new HtmlDataJsonResponse())->setMessageAndTranslate('Pool address :ipPool:/:cidr: has been added'); } catch (\Exception $ex) { return (new HtmlDataJsonResponse())->setStatusError()->setMessageAndTranslate($ex->getMessage()); } } private function createIpv6Pool($ipPool, $mask) { $prefix = implode('/', [$ipPool, $mask]); $range = ipv6_range($prefix); $start = inet_ptoi($range[1]); $end = inet_ptoi($range[2]); $a = new BigInteger($start); $b = new BigInteger($end); $diff = $b->subtract($a)->toString(); $pool = []; for ($i = 0; $i < ($diff + 1); $i++) { $c = new BigInteger($i); $iptoint = $a->add($c)->toString(); $pool[] = inet_itop($iptoint); } return $pool; } private function createIpv4Pool($ipPool, $mask) { $pool = []; $ip_enc = ip2long($ipPool); //convert last (32-$mask) bits to zeroes $curr_ip = $ip_enc | pow(2, (32 - $mask)) - pow(2, (32 - $mask)); $ips = []; $ip_nmask = self::translateBitmaskToNetmask((int)$mask); $ip_address_long = $ip_enc; $ip_nmask_long = ip2long($ip_nmask); //caculate network address $ip_net = $ip_address_long & $ip_nmask_long; //caculate first usable address $ip_host_first = ((~$ip_nmask_long) & $ip_address_long); $ip_first = ($ip_address_long ^ $ip_host_first) + 1; //caculate last usable address $ip_broadcast_invert = ~$ip_nmask_long; $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1; //caculate broadcast address $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1; $ip_last_short = long2ip($ip_last); $totalHost = (float)pow(2, (32 - $mask)); if ($totalHost > 10000) { throw new \Exception(sprintf("Subnet %s/%s is too large. You are tring to add %s addresses.", $ipPool, $mask, $totalHost)); } for ($pos = 0; $pos < pow(2, (32 - $mask)); ++$pos) { $ip = long2ip((float)$curr_ip + $pos); $pool[] = $ip; if ($ip == $ip_last_short) { break; } } return $pool; } public static function translateBitmaskToNetmask($bitmask) { $maskMap = [ 0 => "0.0.0.0", 1 => "128.0.0.0", 2 => "192.0.0.0", 3 => "224.0.0.0", 4 => "240.0.0.0", 5 => "248.0.0.0", 6 => "252.0.0.0", 7 => "254.0.0.0", 8 => "255.0.0.0", 9 => "255.128.0.0", 10 => "255.192.0.0", 11 => "255.224.0.0", 12 => "255.240.0.0", 13 => "255.248.0.0", 14 => "255.252.0.0", 15 => "255.254.0.0", 16 => "255.255.0.0", 17 => "255.255.128.0", 18 => "255.255.192.0", 19 => "255.255.224.0", 20 => "255.255.240.0", 21 => "255.255.248.0", 22 => "255.255.252.0", 23 => "255.255.254.0", 24 => "255.255.255.0", 25 => "255.255.255.128", 26 => "255.255.255.192", 27 => "255.255.255.224", 28 => "255.255.255.240", 29 => "255.255.255.248", 30 => "255.255.255.252", 31 => "255.255.255.254", 32 => "255.255.255.255" ]; return isset($maskMap[$bitmask]) ? $maskMap[$bitmask] : $bitmask; } public function update() { $form = $this->getFormDataValues(); $this->formData['private'] = $form['private'] == "on" ? "1" : "0"; $this->formData['trunks'] = (int)$form['trunks'] > 0 ? $form['trunks'] : null; $this->formData['tag'] = (int)$form['tag'] > 0 ? $form['tag'] : null; parent::update(); main\Core\ServiceLocator::call('lang')->addReplacementConstant('ip', $this->formData['ip']); return (new HtmlDataJsonResponse())->setMessageAndTranslate('IP Address :ip: has been updated successfully'); } public function delete() { parent::delete(); main\Core\ServiceLocator::call('lang')->addReplacementConstant('ip', $this->formData['ip']); return (new HtmlDataJsonResponse())->setMessageAndTranslate('IP Address :ip: has been deleted successfully'); } public function deleteMass() { if (!$this->getRequestValue('massActions')) { return; } $this->model->destroy((array)$this->getRequestValue('massActions')); return (new HtmlDataJsonResponse())->setMessageAndTranslate('The selected IP Addresses have been deleted successfully'); } }