IpAddressProvider.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /* * ********************************************************************
  3. * ProxmoxAddon product developed. (Aug 23, 2018)
  4. * *
  5. *
  6. * CREATED BY MODULESGARDEN -> http://modulesgarden.com
  7. * CONTACT -> contact@modulesgarden.com
  8. *
  9. *
  10. * This software is furnished under a license and may be used and copied
  11. * only in accordance with the terms of such license and with the
  12. * inclusion of the above copyright notice. This software or any other
  13. * copies thereof may not be provided or otherwise made available to any
  14. * other person. No title to and ownership of the software is hereby
  15. * transferred.
  16. *
  17. *
  18. * ******************************************************************** */
  19. namespace ModulesGarden\ProxmoxAddon\App\UI\IpManagement\Providers;
  20. use ModulesGarden\ProxmoxAddon as main;
  21. use ModulesGarden\ProxmoxAddon\App\Libs\BigInteger;
  22. use ModulesGarden\ProxmoxAddon\Core\UI\Interfaces\AdminArea;
  23. use ModulesGarden\ProxmoxAddon\Core\UI\ResponseTemplates\HtmlDataJsonResponse;
  24. use ModulesGarden\ProxmoxAddon\Core\UI\Widget\Forms\DataProviders\BaseModelDataProvider;
  25. use function ModulesGarden\ProxmoxAddon\App\Libs\inet_itop;
  26. use function ModulesGarden\ProxmoxAddon\App\Libs\inet_ptoi;
  27. use function ModulesGarden\ProxmoxAddon\App\Libs\ipv6_range;
  28. use function ModulesGarden\ProxmoxAddon\Core\Helper\sl;
  29. /**
  30. *
  31. * Description of RangeVmProvider
  32. *
  33. * @author Pawel Kopec <pawelk@modulesgardne.com>
  34. */
  35. class IpAddressProvider extends BaseModelDataProvider implements AdminArea
  36. {
  37. public function __construct()
  38. {
  39. parent::__construct(main\App\Models\IpAddress::class);
  40. }
  41. public function read()
  42. {
  43. if (!$this->actionElementId)
  44. {
  45. return false;
  46. }
  47. $dbData = $this->model->where('id', $this->actionElementId)->first();
  48. if ($dbData === null)
  49. {
  50. return;
  51. }
  52. $data = $dbData->toArray();
  53. //Node
  54. $this->data['node'] = [];
  55. $this->data['node']['value'] = $data['node'];
  56. unset($data['node']);
  57. //sid
  58. $this->data['sid'] = [];
  59. $this->data['sid']['value'] = $data['sid'];
  60. unset($data['sid']);
  61. //visualization
  62. $this->data['visualization'] = [];
  63. $this->data['visualization']['value'] = $data['visualization'];
  64. unset($data['visualization']);
  65. //private
  66. $this->data['private'] = $data['private'] == "1" ? "on" : "off";
  67. unset($data['private']);
  68. $this->data = array_merge($this->data, $data);
  69. sl('lang')->addReplacementConstant('ip', $this->data['ip']);
  70. }
  71. public function create()
  72. {
  73. try
  74. {
  75. $form = $this->getFormDataValues();
  76. if (preg_match('/\:/', $this->formData['ipPool']))
  77. {
  78. $pool = $this->createIpv6Pool($this->formData['ipPool'], $this->formData['cidr']);
  79. $type = 'IPv6';
  80. }
  81. else
  82. {
  83. $pool = $this->createIpv4Pool($this->formData['ipPool'], $this->formData['cidr']);
  84. $type = 'IPv4';
  85. }
  86. foreach ($pool as $ip)
  87. {
  88. if (main\App\Models\IpAddress::where("ip", $ip)->count())
  89. {
  90. continue;
  91. }
  92. $attributes = $this->formData;
  93. $attributes['ip'] = $ip;
  94. $attributes['private'] = $this->formData['private'] == "on" ? "1" : "0";
  95. $attributes['trunks'] = (int)$this->formData['trunks'] > 0 ? $this->formData['trunks'] : null;
  96. $attributes['tag'] = (int)$this->formData['tag'] > 0 ? $this->formData['tag'] : null;
  97. $attributes['type'] = $type;
  98. $attributes['hostingId'] = 0;
  99. $ipAddress = new main\App\Models\IpAddress();
  100. $ipAddress->fill($attributes)->save();
  101. unset($ipAddress);
  102. }
  103. main\Core\ServiceLocator::call('lang')->addReplacementConstant("ipPool", $this->formData['ipPool'])
  104. ->addReplacementConstant("cidr", $this->formData['cidr']);
  105. return (new HtmlDataJsonResponse())->setMessageAndTranslate('Pool address :ipPool:/:cidr: has been added');
  106. }
  107. catch (\Exception $ex)
  108. {
  109. return (new HtmlDataJsonResponse())->setStatusError()->setMessageAndTranslate($ex->getMessage());
  110. }
  111. }
  112. private function createIpv6Pool($ipPool, $mask)
  113. {
  114. $prefix = implode('/', [$ipPool, $mask]);
  115. $range = ipv6_range($prefix);
  116. $start = inet_ptoi($range[1]);
  117. $end = inet_ptoi($range[2]);
  118. $a = new BigInteger($start);
  119. $b = new BigInteger($end);
  120. $diff = $b->subtract($a)->toString();
  121. $pool = [];
  122. for ($i = 0; $i < ($diff + 1); $i++)
  123. {
  124. $c = new BigInteger($i);
  125. $iptoint = $a->add($c)->toString();
  126. $pool[] = inet_itop($iptoint);
  127. }
  128. return $pool;
  129. }
  130. private function createIpv4Pool($ipPool, $mask)
  131. {
  132. $pool = [];
  133. $ip_enc = ip2long($ipPool);
  134. //convert last (32-$mask) bits to zeroes
  135. $curr_ip = $ip_enc | pow(2, (32 - $mask)) - pow(2, (32 - $mask));
  136. $ips = [];
  137. $ip_nmask = self::translateBitmaskToNetmask((int)$mask);
  138. $ip_address_long = $ip_enc;
  139. $ip_nmask_long = ip2long($ip_nmask);
  140. //caculate network address
  141. $ip_net = $ip_address_long & $ip_nmask_long;
  142. //caculate first usable address
  143. $ip_host_first = ((~$ip_nmask_long) & $ip_address_long);
  144. $ip_first = ($ip_address_long ^ $ip_host_first) + 1;
  145. //caculate last usable address
  146. $ip_broadcast_invert = ~$ip_nmask_long;
  147. $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1;
  148. //caculate broadcast address
  149. $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1;
  150. $ip_last_short = long2ip($ip_last);
  151. $totalHost = (float)pow(2, (32 - $mask));
  152. if ($totalHost > 10000)
  153. {
  154. throw new \Exception(sprintf("Subnet %s/%s is too large. You are tring to add %s addresses.", $ipPool, $mask, $totalHost));
  155. }
  156. for ($pos = 0; $pos < pow(2, (32 - $mask)); ++$pos)
  157. {
  158. $ip = long2ip((float)$curr_ip + $pos);
  159. $pool[] = $ip;
  160. if ($ip == $ip_last_short)
  161. {
  162. break;
  163. }
  164. }
  165. return $pool;
  166. }
  167. public static function translateBitmaskToNetmask($bitmask)
  168. {
  169. $maskMap = [
  170. 0 => "0.0.0.0",
  171. 1 => "128.0.0.0",
  172. 2 => "192.0.0.0",
  173. 3 => "224.0.0.0",
  174. 4 => "240.0.0.0",
  175. 5 => "248.0.0.0",
  176. 6 => "252.0.0.0",
  177. 7 => "254.0.0.0",
  178. 8 => "255.0.0.0",
  179. 9 => "255.128.0.0",
  180. 10 => "255.192.0.0",
  181. 11 => "255.224.0.0",
  182. 12 => "255.240.0.0",
  183. 13 => "255.248.0.0",
  184. 14 => "255.252.0.0",
  185. 15 => "255.254.0.0",
  186. 16 => "255.255.0.0",
  187. 17 => "255.255.128.0",
  188. 18 => "255.255.192.0",
  189. 19 => "255.255.224.0",
  190. 20 => "255.255.240.0",
  191. 21 => "255.255.248.0",
  192. 22 => "255.255.252.0",
  193. 23 => "255.255.254.0",
  194. 24 => "255.255.255.0",
  195. 25 => "255.255.255.128",
  196. 26 => "255.255.255.192",
  197. 27 => "255.255.255.224",
  198. 28 => "255.255.255.240",
  199. 29 => "255.255.255.248",
  200. 30 => "255.255.255.252",
  201. 31 => "255.255.255.254",
  202. 32 => "255.255.255.255"
  203. ];
  204. return isset($maskMap[$bitmask]) ? $maskMap[$bitmask] : $bitmask;
  205. }
  206. public function update()
  207. {
  208. $form = $this->getFormDataValues();
  209. $this->formData['private'] = $form['private'] == "on" ? "1" : "0";
  210. $this->formData['trunks'] = (int)$form['trunks'] > 0 ? $form['trunks'] : null;
  211. $this->formData['tag'] = (int)$form['tag'] > 0 ? $form['tag'] : null;
  212. parent::update();
  213. main\Core\ServiceLocator::call('lang')->addReplacementConstant('ip', $this->formData['ip']);
  214. return (new HtmlDataJsonResponse())->setMessageAndTranslate('IP Address :ip: has been updated successfully');
  215. }
  216. public function delete()
  217. {
  218. parent::delete();
  219. main\Core\ServiceLocator::call('lang')->addReplacementConstant('ip', $this->formData['ip']);
  220. return (new HtmlDataJsonResponse())->setMessageAndTranslate('IP Address :ip: has been deleted successfully');
  221. }
  222. public function deleteMass()
  223. {
  224. if (!$this->getRequestValue('massActions'))
  225. {
  226. return;
  227. }
  228. $this->model->destroy((array)$this->getRequestValue('massActions'));
  229. return (new HtmlDataJsonResponse())->setMessageAndTranslate('The selected IP Addresses have been deleted successfully');
  230. }
  231. }