Ipv4Range.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. namespace ModulesGarden\ProxmoxAddon\App\Services\Ip;
  3. class Ipv4Range
  4. {
  5. protected $pool;
  6. protected $cidr;
  7. protected $limit;
  8. protected $disableIpAddresses=[];
  9. const NET_MASK = [
  10. 0 => "0.0.0.0",
  11. 1 => "128.0.0.0",
  12. 2 => "192.0.0.0",
  13. 3 => "224.0.0.0",
  14. 4 => "240.0.0.0",
  15. 5 => "248.0.0.0",
  16. 6 => "252.0.0.0",
  17. 7 => "254.0.0.0",
  18. 8 => "255.0.0.0",
  19. 9 => "255.128.0.0",
  20. 10 => "255.192.0.0",
  21. 11 => "255.224.0.0",
  22. 12 => "255.240.0.0",
  23. 13 => "255.248.0.0",
  24. 14 => "255.252.0.0",
  25. 15 => "255.254.0.0",
  26. 16 => "255.255.0.0",
  27. 17 => "255.255.128.0",
  28. 18 => "255.255.192.0",
  29. 19 => "255.255.224.0",
  30. 20 => "255.255.240.0",
  31. 21 => "255.255.248.0",
  32. 22 => "255.255.252.0",
  33. 23 => "255.255.254.0",
  34. 24 => "255.255.255.0",
  35. 25 => "255.255.255.128",
  36. 26 => "255.255.255.192",
  37. 27 => "255.255.255.224",
  38. 28 => "255.255.255.240",
  39. 29 => "255.255.255.248",
  40. 30 => "255.255.255.252",
  41. 31 => "255.255.255.254",
  42. 32 => "255.255.255.255"
  43. ];
  44. protected $firstIp = false;
  45. /**
  46. * Ipv4Range constructor.
  47. * @param $pool
  48. * @param $cidr
  49. */
  50. public function __construct($pool, $cidr)
  51. {
  52. $this->pool = $pool;
  53. $this->cidr = $cidr;
  54. }
  55. public function get(){
  56. $pool = [];
  57. $ip_enc = ip2long($this->pool);
  58. //convert last (32-$mask) bits to zeroes
  59. $curr_ip = $ip_enc | pow(2, (32 - $this->cidr)) - pow(2, (32 - $this->cidr));
  60. $ips = [];
  61. $ip_nmask = self::NET_MASK[$this->cidr];
  62. $ip_address_long = $ip_enc;
  63. $ip_nmask_long = ip2long($ip_nmask);
  64. //caculate network address
  65. $ip_net = $ip_address_long & $ip_nmask_long;
  66. //caculate first usable address
  67. $ip_host_first = ((~$ip_nmask_long) & $ip_address_long);
  68. $ip_first = ($ip_address_long ^ $ip_host_first) + 1;
  69. //caculate last usable address
  70. $ip_broadcast_invert = ~$ip_nmask_long;
  71. $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1;
  72. //caculate broadcast address
  73. $ip_last = ($ip_address_long | $ip_broadcast_invert) - 1;
  74. $ip_last_short = long2ip($ip_last);
  75. $totalHost = (float)pow(2, (32 - $this->cidr));
  76. if ($totalHost > 10000)
  77. {
  78. throw new \Exception(sprintf("Subnet %s/%s is too large. You are tring to add %s addresses.", $this->pool, $this->cidr, $totalHost));
  79. }
  80. for ($pos = 0; $pos < pow(2, (32 - $this->cidr)); ++$pos)
  81. {
  82. $ip = long2ip((float)$curr_ip + $pos);
  83. if(!$this->firstIp && preg_match("/\.0$/", $ip)){
  84. continue;
  85. }
  86. if(in_array($ip, $this->disableIpAddresses)){
  87. continue;
  88. }
  89. $pool[] = $ip;
  90. if ($ip == $ip_last_short)
  91. {
  92. break;
  93. }
  94. if($this->limit && count($pool) == $this->limit){
  95. return $pool;
  96. }
  97. }
  98. return $pool;
  99. }
  100. /**
  101. * @return mixed
  102. */
  103. public function getLimit()
  104. {
  105. return $this->limit;
  106. }
  107. /**
  108. * @param mixed $limit
  109. * @return Ipv4Range
  110. */
  111. public function setLimit($limit)
  112. {
  113. $this->limit = $limit;
  114. return $this;
  115. }
  116. /**
  117. * @param array $disableIpAddresses
  118. * @return Ipv4Range
  119. */
  120. public function disableIpAddresses($disableIpAddresses)
  121. {
  122. $this->disableIpAddresses = $disableIpAddresses;
  123. return $this;
  124. }
  125. public function firstIp($enable=false){
  126. $this->firstIp = $enable;
  127. return $this;
  128. }
  129. }