01 <?php 02 # Function(1) - Bad Example - 03 04 function ip2cidr($ip_start, $ip_end) { 05 $cidr = $ip_start . "/" . (int)(32 - log((ip2long($ip_end) + 1 - ip2long($ip_start)), 2)); 06 07 return $cidr; 08 } 09 10 # Function(2) - Bad Example - 11 12 function ip2cidr($ip_start, $ip_end) { 13 if(long2ip(ip2long($ip_start)) != $ip_start || long2ip(ip2long($ip_end)) != $ip_end) { 14 return NULL; 15 } 16 17 $ipl_start = (int)ip2long($ip_start); 18 $ipl_end = (int)ip2long($ip_end); 19 20 if($ipl_start > 0 && $ipl_end < 0) { 21 $delta = ($ipl_end + 4294967296) - $ipl_start; 22 } else { 23 $delta = $ipl_end - $ipl_start; 24 } 25 26 $netmask = str_pad(decbin($delta), 32, "0", "STR_PAD_LEFT"); 27 28 if(ip2long($ip_start) == 0 && substr_count($netmask, "1") == 32) { 29 return "0.0.0.0/0"; 30 } 31 if($delta < 0 || ($delta > 0 && $delta % 2 == 0)) { 32 return NULL; 33 } 34 35 for($mask = 0; $mask < 32; $mask++) { 36 if($netmask[$mask] == 1) { 37 break; 38 } 39 } 40 41 if(substr_count($netmask, "0") != $mask) { 42 return NULL; 43 } 44 45 return "$ip_start/$mask"; 46 } 47 48 # Function(3) - Good Example (Bug Fixed) - 49 50 function imask($this) { 51 // use base_convert not dechex because dechex is broken and returns 0x80000000 instead of 0xffffffff 52 return base_convert((pow(2, 32) - pow(2, (32 - $this))), 10, 16); 53 } 54 55 function imaxblock($ibase, $tbit) { 56 while($tbit > 0) { 57 $im = hexdec(imask($tbit - 1)); 58 $imand = $ibase & $im; 59 if ($imand != $ibase) { 60 break; 61 } 62 $tbit--; 63 } 64 return $tbit; 65 } 66 67 function range2cidrlist($istart, $iend) { 68 // this function returns an array of cidr lists that map the range given 69 $s = explode(".", $istart); 70 // PHP ip2long does not handle leading zeros on IP addresses! 172.016 comes back as 172.14, seems to be treated as octal! 71 $start = ""; 72 $dot = ""; 73 while(list($key, $val) = each($s)) { 74 $start = sprintf("%s%s%d", $start, $dot, $val); 75 $dot = "."; 76 } 77 $end = ""; 78 $dot = ""; 79 $e = explode(".", $iend); 80 while(list($key, $val) = each($e)) { 81 $end = sprintf("%s%s%d", $end, $dot, $val); 82 $dot = "."; 83 } 84 $start = ip2long($start); 85 $end = ip2long($end); 86 $result = array(); 87 while($end >= $start) { 88 $maxsize = imaxblock($start, 32); 89 $x = log($end - $start + 1) / log(2); 90 $maxdiff = floor(32 - floor($x)); 91 $ip = long2ip($start); 92 if($maxsize < $maxdiff) { 93 $maxsize = $maxdiff; 94 } 95 array_push($result, "$ip/$maxsize"); 96 $start += pow(2, (32 - $maxsize)); 97 } 98 return $result; 99 } 100 ?>