IP.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace MGModule\DNSManager2\mgLibs\custom\dns\utils;
  3. class IP {
  4. const LAST = 'last';
  5. const HALF = 'half';
  6. private $ip;
  7. private $block = null;
  8. private $delimeter = '.';
  9. private $ip_array;
  10. function __construct($ip) {
  11. if(strpos($ip, '/') !== false) {
  12. $this->block = explode('/',$ip)[1];
  13. $ip = explode('/',$ip)[0];
  14. }
  15. $this->ip = $ip;
  16. if($this->isIPv6()) {
  17. $this->expand();
  18. $this->delimeter = ':';
  19. }
  20. $this->explode();
  21. }
  22. /** Parses list of IPs and IPs with CIDR block into list of IPs
  23. * @param $availableIps array
  24. * @return array
  25. */
  26. public static function getAvailableIpList($availableIps)
  27. {
  28. $result = array();
  29. foreach ($availableIps as $ip)
  30. if(strpos($ip, '/') !== false)
  31. $result = array_merge($result, Cidr::cidrAsIpList($ip));
  32. else
  33. array_push($result, $ip);
  34. return array_unique($result);
  35. }
  36. public static function getOnlyIpv4($ipArray)
  37. {
  38. return array_values(array_filter($ipArray, function ($ip) {
  39. return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
  40. }));
  41. }
  42. public static function getOnlyIpv6($ipArray)
  43. {
  44. return array_values(array_filter($ipArray, function ($ip) {
  45. return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
  46. }));
  47. }
  48. private function expand() {
  49. $hex = unpack("H*hex", inet_pton($this->ip));
  50. $this->ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1);
  51. }
  52. public function explode() {
  53. $this->ip_array = explode($this->delimeter, $this->ip);
  54. return $this->ip_array;
  55. }
  56. public function isValid() {
  57. if($this->ip == null)
  58. return true;
  59. $cidrPart = true;
  60. if($this->block !== null) {
  61. $cidrPart = Cidr::validate($this->ip, $this->block);
  62. }
  63. return (filter_var($this->ip, FILTER_VALIDATE_IP) !== false) && $cidrPart;
  64. }
  65. public function isIPv4() {
  66. return filter_var($this->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
  67. }
  68. public function isIPv6() {
  69. return filter_var($this->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
  70. }
  71. public function isPrivateORReserved() {
  72. return filter_var($this->ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false;
  73. }
  74. public function reverse() {
  75. $this->ip_array = array_reverse($this->ip_array);
  76. }
  77. public function slice($offset, $length = null) {
  78. $slice = array_slice($this->ip_array, $this->constToNumber($offset), $this->constToNumber($length) );
  79. return implode($this->delimeter, $slice);
  80. }
  81. private function constToNumber($var) {
  82. if(is_null($var)) return null;
  83. switch((string)$var) {
  84. case self::LAST:
  85. return count($this->ip_array) - 2;
  86. case self::HALF:
  87. return (int) (count($this->ip_array)/2);
  88. default:
  89. return $var;
  90. }
  91. }
  92. public function __toString() {
  93. return $this->ip;
  94. }
  95. public function isInNetwork($net_addr, $net_mask) {
  96. // if($this->isIPv4()) {
  97. // $ip_binary_string = sprintf("%032b", ip2long($this->ip));
  98. // $net_binary_string = sprintf("%032b", ip2long($net_addr));
  99. // return (substr_compare($ip_binary_string, $net_binary_string, 0, $net_mask) === 0);
  100. // } else {
  101. $subnet = inet_pton($net_addr);
  102. $addr = inet_pton($this->ip);
  103. $binMask = $this->maskToByteArray($net_mask);
  104. return ($addr & $binMask) == $subnet;
  105. // }
  106. }
  107. private function maskToByteArray($subnetMask) {
  108. $addr = str_repeat("f", $subnetMask / 4);
  109. switch($subnetMask % 4) {
  110. case 0:
  111. break;
  112. case 1:
  113. $addr .= "8";
  114. break;
  115. case 2:
  116. $addr .= "c";
  117. break;
  118. case 3:
  119. $addr .= "e";
  120. break;
  121. }
  122. $addr = str_pad($addr, 32, '0');
  123. $addr = pack("H*", $addr);
  124. return $addr;
  125. }
  126. }