AbstractRange.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. namespace IPLib\Range;
  3. use IPLib\Address\AddressInterface;
  4. use IPLib\Address\IPv4;
  5. use IPLib\Address\IPv6;
  6. use IPLib\Address\Type as AddressType;
  7. use IPLib\Factory;
  8. /**
  9. * Base class for range classes.
  10. */
  11. abstract class AbstractRange implements RangeInterface
  12. {
  13. /**
  14. * {@inheritdoc}
  15. *
  16. * @see \IPLib\Range\RangeInterface::getRangeType()
  17. */
  18. public function getRangeType()
  19. {
  20. if ($this->rangeType === null) {
  21. $addressType = $this->getAddressType();
  22. if ($addressType === AddressType::T_IPv6 && Subnet::get6to4()->containsRange($this)) {
  23. $this->rangeType = Factory::getRangeFromBoundaries($this->fromAddress->toIPv4(), $this->toAddress->toIPv4())->getRangeType();
  24. } else {
  25. switch ($addressType) {
  26. case AddressType::T_IPv4:
  27. $defaultType = IPv4::getDefaultReservedRangeType();
  28. $reservedRanges = IPv4::getReservedRanges();
  29. break;
  30. case AddressType::T_IPv6:
  31. $defaultType = IPv6::getDefaultReservedRangeType();
  32. $reservedRanges = IPv6::getReservedRanges();
  33. break;
  34. default:
  35. throw new \Exception('@todo'); // @codeCoverageIgnore
  36. }
  37. $rangeType = null;
  38. foreach ($reservedRanges as $reservedRange) {
  39. $rangeType = $reservedRange->getRangeType($this);
  40. if ($rangeType !== null) {
  41. break;
  42. }
  43. }
  44. $this->rangeType = $rangeType === null ? $defaultType : $rangeType;
  45. }
  46. }
  47. return $this->rangeType === false ? null : $this->rangeType;
  48. }
  49. /**
  50. * {@inheritdoc}
  51. *
  52. * @see \IPLib\Range\RangeInterface::getAddressAtOffset()
  53. */
  54. public function getAddressAtOffset($n)
  55. {
  56. if (!is_int($n)) {
  57. return null;
  58. }
  59. $address = null;
  60. if ($n >= 0) {
  61. $start = Factory::parseAddressString($this->getComparableStartString());
  62. $address = $start->getAddressAtOffset($n);
  63. } else {
  64. $end = Factory::parseAddressString($this->getComparableEndString());
  65. $address = $end->getAddressAtOffset($n + 1);
  66. }
  67. if ($address === null) {
  68. return null;
  69. }
  70. return $this->contains($address) ? $address : null;
  71. }
  72. /**
  73. * {@inheritdoc}
  74. *
  75. * @see \IPLib\Range\RangeInterface::contains()
  76. */
  77. public function contains(AddressInterface $address)
  78. {
  79. $result = false;
  80. if ($address->getAddressType() === $this->getAddressType()) {
  81. $cmp = $address->getComparableString();
  82. $from = $this->getComparableStartString();
  83. if ($cmp >= $from) {
  84. $to = $this->getComparableEndString();
  85. if ($cmp <= $to) {
  86. $result = true;
  87. }
  88. }
  89. }
  90. return $result;
  91. }
  92. /**
  93. * {@inheritdoc}
  94. *
  95. * @see \IPLib\Range\RangeInterface::containsRange()
  96. */
  97. public function containsRange(RangeInterface $range)
  98. {
  99. $result = false;
  100. if ($range->getAddressType() === $this->getAddressType()) {
  101. $myStart = $this->getComparableStartString();
  102. $itsStart = $range->getComparableStartString();
  103. if ($itsStart >= $myStart) {
  104. $myEnd = $this->getComparableEndString();
  105. $itsEnd = $range->getComparableEndString();
  106. if ($itsEnd <= $myEnd) {
  107. $result = true;
  108. }
  109. }
  110. }
  111. return $result;
  112. }
  113. }