Example #1
0
 public function testIsInNetwork()
 {
     $ip = new Ip('2001:304:234a::1');
     $this->assertEquals(true, $ip->isInNetwork(new Ip('2001:304:234a::'), 48));
     $ip = new Ip('2001:304:234b::1');
     $this->assertEquals(false, $ip->isInNetwork(new Ip('2001:304:234a::'), 48));
     $ip = new Ip('127.2.4.5');
     $this->assertEquals(true, $ip->isInNetwork(new Ip('127.2.3.4'), 16));
     $ip = new Ip('127.2.127.9');
     $this->assertEquals(false, $ip->isInNetwork(new Ip('127.2.128.0'), 17));
 }
Example #2
0
 /**
  * Tests if an IP address belongs to a specific network
  *
  * Accepts a network base address and a prefix length.
  *
  * @param  Ip   $base      Base address for the network to test
  * @param  int  $prefixlen Prefix length to test
  * @return bool
  */
 public function isInNetwork(Ip $base, $prefixlen)
 {
     $baseVersion = $base->getVersion();
     $thisVersion = $this->getVersion();
     if ($prefixlen < 0) {
         throw new InvalidArgumentException('Prefix length cannot be negative');
     }
     if ($baseVersion !== $thisVersion) {
         throw new InvalidArgumentException('Address version does not match supplied network base version');
     }
     if ($thisVersion === 4 && $prefixlen > 32) {
         throw new InvalidArgumentException('Address version (4) was not supplied a correct prefix length');
     }
     if ($thisVersion === 6 && $prefixlen > 128) {
         throw new InvalidArgumentException('Address version (6) was not supplied a correct prefix length');
     }
     // First create a 128-bit long binary string regardless of IP version.
     // IPv4 addresses are left-padded with zeroes so that the algorithm
     // can be used generically.
     //
     // Next, split the 128-bit string into 32-bit chunks, and convert them
     // to unsigned integers. We can then use this to perform the bitwise
     // comparisons that we need later.
     $prefixIntegerArray = array_map('bindec', str_split(str_pad(str_pad(str_repeat('1', $prefixlen), $thisVersion === 4 ? 32 : 128, '0'), 128, '0', STR_PAD_LEFT), 32));
     $baseIntegerArray = $base->toIntegerArray();
     $thisIntegerArray = $this->toIntegerArray();
     // If it's version 4, we just want to compare final array position
     $start = $thisVersion === 4 ? 3 : 0;
     for ($i = $start; $i < 4; $i++) {
         $a = $thisIntegerArray[$i];
         $b = $baseIntegerArray[$i];
         $p = $prefixIntegerArray[$i];
         // If the address ANDed with the prefix mask is not equal to the
         // base address ANDed with the prefix mask, we can bail.
         if (($a & $p) !== ($b & $p)) {
             return false;
         }
     }
     return true;
 }