コード例 #1
0
ファイル: CIDR.php プロジェクト: 0151n/vichan
 /**
  * Return a contiguous list of true CIDR blocks that span the range given.
  *
  * Note: It's not a good idea to call this with IPv6 addresses. While it may
  * work for certain ranges this can be very slow. Also an IPv6 list won't be
  * as accurate as an IPv4 list.
  *
  * @example
  *  range_to_cidrlist(192.168.0.0, 192.168.0.15) ==
  *    192.168.0.0/28
  *  range_to_cidrlist(192.168.0.0, 192.168.0.20) ==
  *    192.168.0.0/28
  *    192.168.0.16/30
  *    192.168.0.20/32
  */
 public static function range_to_cidrlist($start, $end)
 {
     $ver = false === filter_var($start, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 6 : 4;
     $start = IP::inet_ptod($start);
     $end = IP::inet_ptod($end);
     $len = $ver == 4 ? 32 : 128;
     $log2 = $ver == 4 ? log(2) : BC::bclog(2);
     $list = array();
     while (BC::cmp($end, $start) >= 0) {
         // $end >= $start
         $prefix = self::max_prefix(IP::inet_dtop($start), $len);
         if ($ver == 4) {
             $diff = $len - floor(log($end - $start + 1) / $log2);
         } else {
             // this is not as accurate due to the bclog function
             $diff = bcsub($len, BC::bcfloor(bcdiv(BC::bclog(bcadd(bcsub($end, $start), '1')), $log2)));
         }
         if ($prefix < $diff) {
             $prefix = $diff;
         }
         $list[] = IP::inet_dtop($start) . "/" . $prefix;
         if ($ver == 4) {
             $start += pow(2, $len - $prefix);
         } else {
             $start = bcadd($start, bcpow(2, $len - $prefix));
         }
     }
     return $list;
 }
コード例 #2
0
ファイル: IP.php プロジェクト: 0151n/vichan
 /**
  * Convert an IPv4 address into an IPv6 address.
  *
  * One use-case for this is IP 6to4 tunnels used in networking.
  *
  * @example
  *      to_ipv4("10.10.10.10") == a0a:a0a
  *
  * @param string $ip IPv4 address.
  * @param boolean $mapped If true a Full IPv6 address is returned within the
  *                        official ipv4to6 mapped space "0:0:0:0:0:ffff:x:x"
  */
 public static function to_ipv6($ip, $mapped = false)
 {
     if (!self::isIPv4($ip)) {
         throw new \InvalidArgumentException("Invalid IPv4 address \"{$ip}\"");
     }
     $num = IP::inet_ptod($ip);
     $o1 = dechex($num >> 16);
     $o2 = dechex($num & 0xffff);
     return $mapped ? "0:0:0:0:0:ffff:{$o1}:{$o2}" : "{$o1}:{$o2}";
 }