{
$ipv4 = ereg('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', $ip);
$ipv6 = ereg("^[0-9a-fA-F:]+$", $ip);
-
+
error_log("ipversion, $ip, $ipv4, $ipv6");
if($ipv4 == 1) return 4;
if($ipv6 == 1) return 6;
function ip6ToLongStr($ip)
{
if(ipversion($ip)!=6) return false;
-
+
$pss = explode(":", $ip);
$ns = count($pss);
-
+
$nstr = "";
foreach($pss as $ele) {
+ echo "ele: $ele\n";
if($nstr != "") {
$nstr .= ":";
+ echo "add colon\n";
}
- if(strlen($ele < 1)) {
+ if(strlen($ele)<1) {
// this is where we pad 8-count of 0000:
+ echo "add pad count\n";
$pds = 8-$ns+1;
for($i=0; $i < $pds; $i++) {
- $nstr .= "0000";
+ $nstr .= "0000:";
}
+ $nstr = rtrim($nstr, ":");
} else if(strlen($ele) < 4) {
$nstr .= str_pad($ele, 4, "0", STR_PAD_LEFT);
} else {
// this function converts an ip address to a comparable integer
// so we can bounds-check.
// it returns an array of [firstnum][lastnum]
-function ip6ToComp($ip, $mask)
+// this is without a doubt one of the ugliest things i've ever done.
+function ip6ToGmp($ip, $mask)
{
- if($ipversion($ip)!=6) return false;
+ if(ipversion($ip)!=6) return false;
+
+ $ipone = ip::truncateNetwork($ip, $mask);
+ $iponeap = $ipone."::0";
+ $rip = ip6ToLongStr($iponeap);
- $rip = ip6ToLongStr($ip);
+ $riphex = "0x".str_replace(":", "", $rip);
+ // f**king ugly
+ $sns = 8-($mask / 16);
+
+ $slt = $ipone;
+ for($i = 0; $i < $sns; $i++) {
+ $slt .= ":FFFF";
+ }
+
+ $endhex = "0x".str_replace(":", "", ip6ToLongStr($slt));
+
+ echo "$rip, $ipone, $iponeap, $riphex, $slt, $endhex\n";
+
+ // now we gmp_init
+ $gmpone = gmp_init($riphex);
+ $gmptwo = gmp_init($endhex);
+
+ $array["start"] = $gmpone;
+ $array["end"] = $gmptwo;
+
+ return $array;
}
function ip4ToComp($ip, $mask)
{
-
+
}
class ip {
-
+
static function isValid($ip, $mask = 0)
{
-
+
$ver = ipversion($ip);
-
+
if($ver == 0) return 0;
if($ver == 6) {
return false;
} else {
$sns = $mask / 16;
-
+
// now check that we have $sns number of subnets specified
$pss = explode(":", $ip);
$ns = count($pss);
-
+
// we need to specify an error we can throw back at the user
if($ns < $sns) {
error_log("no 2, $ns, $sns, $ip");
return false;
}
}
-
+
// we are still a valid ipv6 ip address/mask
error_log("Valid");
return true;
}
}
}
-
+
if($ver == 4) {
if($mask != 0) {
return $ip;
}
}
}
-
+
static function truncateNetwork($ip, $mask)
{
$ver = ipversion($ip);
-
+
if($ver == 0) return false;
-
+
if($ver == 6) {
if($mask != 0) {
if($mask%16 != 0) {
return false;
} else {
$sns = $mask / 16;
-
+
// now check that we have $sns number of subnets specified
$pss = explode(":", $ip);
$ns = count($pss);
-
+
// we need to specify an error we can throw back at the user
if($ns < $sns) {
error_log("no 2, $ns, $sns, $ip");
print_r($pss);
return false;
}
-
+
$slt = "";
for($i = 0; $i < $sns; $i++) {
if($i!=0) $slt .= ":";
}
$slt .= "".$pss[$i];
}
-
+
// we are still a valid ipv6 ip address/mask
error_log("Valid");
return $slt;
}
}
}
-
+
if($ver == 4) {
if($mask != 0) {
return $ip;
}
}
}
-
+
function addSupernet($name, $sn, $mask, $desc)
{
global $db;
-
+
if(ip::isValid($sn, $mask)) {
$sn = ip::truncateNetwork($sn, $mask);
$sql = "insert into supernet values (NULL, '$name', '$sn', '$mask', '$desc')";
}
return false;
}
-
+
function addSubnet($name, $subnet, $mask, $desc, $super)
{
global $db;
if(ip::isValid($subnet, $mask)) {
- $sn = ip::truncateNetwork($sn, $mask);
+ $subnet = ip::truncateNetwork($subnet, $mask);
// ("sn_id" INTEGER PRIMARY KEY AUTOINCREMENT,"snid_id" INTEGER,"sn_ip" TEXT,"sn_mask" TEXT,"sn_name" TEXT, "sn_desc" TEXT);';
- //if(!isSubnet($subnet, $mask, $super)) return "Is not a valid subnet";
-
+ if(!$this->isSubnet($subnet, $mask, $super)) return "Is not a valid subnet of the super range";
+ if(!$this->isConflicting($subnet, $mask, $super)) return "Is conflicting with an existing allocation";
+
$sql = "insert into subnet values (NULL, '$super', '$subnet', '$mask', '$name', '$desc')";
error_log("sql: $sql");
$db->dbobject->query($sql);
return true;
}
}
-
+
function isSubnet($subnet, $mask, $superid)
{
- return true;
+ global $db, $wwwConnector;
+
+ $res = $db->dbobject->query("select * from supernet where sn_id=='$superid'");
+
+ foreach($res as $row) {
+ $sn = $row["sn_ip"];
+ $sm = $row["sn_mask"];
+ }
+
+ if(ipversion($sn) == 6) {
+ // we ip6 to gmp the main subnet...
+ $aone = ip6ToGmp($sn, $sm);
+
+ // we ip6togmp the sub sub...
+ $atwo = ip6ToGmp($subnet, $mask);
+
+ // then we gmp compare the two... subnet[start] must be higher then (or equal) $supernet[start] and subnet[end] must be lower then or equal too $supernt[end];
+ $cmp1 = gmp_cmp($aone["start"], $atwo["start"]);
+ $cmp2 = gmp_cmp($aone["end"], $atwo["end"]);
+
+ error_log("cmp1, $cmp1, cmp2, $cmp2");
+ // in order to be a subnet, $cmp1 should be 0 or negative, $cmp2 should be 0 or positive
+ if($cmp1 <= 0&&$cmp2 >= 0) return true;
+ return false;
+ }
+ if(ipversion($sn) == 4) {
+ // ERR, TODO
+ }
+ return true;
}
-
+
// this function returns true if it is NOT conflicting
function isConflicting($subnet, $mask, $superid)
{
+ global $db, $wwwConnector;
+
+ if(ipversion($subnet) == 6) {
+ $res = $db->dbobject->query("select * from subnet where snid_id=='$superid'");
+
+ // we ip6togmp the sub sub...
+ $atwo = ip6ToGmp($subnet, $mask);
+
+ foreach($res as $row) {
+ $sn = $row["sn_ip"];
+ $sm = $row["sn_mask"];
+
+ // we ip6 to gmp the main subnet...
+ $aone = ip6ToGmp($sn, $sm);
+
+ // in order to be not a collision, must be either $aone["end"] is lower then atwo["start"] or aone["start"] is higher then atwo["end"]
+ $cmp1 = gmp_cmp($aone["end"], $atwo["start"]);
+ $cmp2 = gmp_cmp($aone["start"], $atwo["end"]);
+
+ error_log("conflighting cmp1, $cmp1, cmp2, $cmp2 ".gmp_strval($aone["end"])." - ".gmp_strval($aone["start"])." - ".gmp_strval($atwo["end"])." - ".gmp_strval($atwo["start"])." - ");
+
+ if($cmp1 < 0) return true;
+ if($cmp2 > 0) return true;
+
+ return false;
+
+ }
+ }
return true;
}
-
+
public $supers = "";
public $subs = "";
}