3 function ipversion($ip)
5 $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);
6 $ipv6 = ereg("^[0-9a-fA-F:]+$", $ip);
8 error_log("ipversion, $ip, $ipv4, $ipv6");
9 if($ipv4 == 1) return 4;
10 if($ipv6 == 1) return 6;
14 // this function tries to take a short representation of a ip6 address and converts it to a long one.
15 // this is not entirely going to work.. but we'll get back to this
16 function ip6ToLongStr($ip)
18 if(ipversion($ip)!=6) return false;
20 $pss = explode(":", $ip);
24 foreach($pss as $ele) {
31 // this is where we pad 8-count of 0000:
32 echo "add pad count\n";
34 for($i=0; $i < $pds; $i++) {
37 $nstr = rtrim($nstr, ":");
38 } else if(strlen($ele) < 4) {
39 $nstr .= str_pad($ele, 4, "0", STR_PAD_LEFT);
47 // this function converts an ip address to a comparable integer
48 // so we can bounds-check.
49 // it returns an array of [firstnum][lastnum]
50 // this is without a doubt one of the ugliest things i've ever done.
51 function ip6ToGmp($ip, $mask)
53 if(ipversion($ip)!=6) return false;
55 $ipone = ip::truncateNetwork($ip, $mask);
56 $iponeap = $ipone."::0";
57 $rip = ip6ToLongStr($iponeap);
59 $riphex = "0x".str_replace(":", "", $rip);
62 $sns = 8-($mask / 16);
65 for($i = 0; $i < $sns; $i++) {
69 $endhex = "0x".str_replace(":", "", ip6ToLongStr($slt));
71 echo "$rip, $ipone, $iponeap, $riphex, $slt, $endhex\n";
74 $gmpone = gmp_init($riphex);
75 $gmptwo = gmp_init($endhex);
77 $array["start"] = $gmpone;
78 $array["end"] = $gmptwo;
83 function ip4ToComp($ip, $mask)
90 static function isValid($ip, $mask = 0)
93 $ver = ipversion($ip);
95 if($ver == 0) return 0;
105 // now check that we have $sns number of subnets specified
106 $pss = explode(":", $ip);
109 // we need to specify an error we can throw back at the user
111 error_log("no 2, $ns, $sns, $ip");
115 for($i = 0; $i < $sns; $i++) {
116 if(strlen($pss[$i]) < 1) {
122 // we are still a valid ipv6 ip address/mask
136 static function truncateNetwork($ip, $mask)
138 $ver = ipversion($ip);
140 if($ver == 0) return false;
150 // now check that we have $sns number of subnets specified
151 $pss = explode(":", $ip);
154 // we need to specify an error we can throw back at the user
156 error_log("no 2, $ns, $sns, $ip");
162 for($i = 0; $i < $sns; $i++) {
163 if($i!=0) $slt .= ":";
164 if(strlen($pss[$i]) < 1) {
171 // we are still a valid ipv6 ip address/mask
185 function addSupernet($name, $sn, $mask, $desc)
189 if(ip::isValid($sn, $mask)) {
190 $sn = ip::truncateNetwork($sn, $mask);
191 $sql = "insert into supernet values (NULL, '$name', '$sn', '$mask', '$desc')";
192 $db->dbobject->query($sql);
198 function addSubnet($name, $subnet, $mask, $desc, $super)
201 if(ip::isValid($subnet, $mask)) {
202 $subnet = ip::truncateNetwork($subnet, $mask);
203 // ("sn_id" INTEGER PRIMARY KEY AUTOINCREMENT,"snid_id" INTEGER,"sn_ip" TEXT,"sn_mask" TEXT,"sn_name" TEXT, "sn_desc" TEXT);';
204 if(!$this->isSubnet($subnet, $mask, $super)) return "Is not a valid subnet of the super range";
205 if(!$this->isConflicting($subnet, $mask, $super)) return "Is conflicting with an existing allocation";
207 $sql = "insert into subnet values (NULL, '$super', '$subnet', '$mask', '$name', '$desc')";
208 error_log("sql: $sql");
209 $db->dbobject->query($sql);
214 function isSubnet($subnet, $mask, $superid)
216 global $db, $wwwConnector;
218 $res = $db->dbobject->query("select * from supernet where sn_id=='$superid'");
220 foreach($res as $row) {
222 $sm = $row["sn_mask"];
225 if(ipversion($sn) == 6) {
226 // we ip6 to gmp the main subnet...
227 $aone = ip6ToGmp($sn, $sm);
229 // we ip6togmp the sub sub...
230 $atwo = ip6ToGmp($subnet, $mask);
232 // 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];
233 $cmp1 = gmp_cmp($aone["start"], $atwo["start"]);
234 $cmp2 = gmp_cmp($aone["end"], $atwo["end"]);
236 error_log("cmp1, $cmp1, cmp2, $cmp2");
237 // in order to be a subnet, $cmp1 should be 0 or negative, $cmp2 should be 0 or positive
238 if($cmp1 <= 0&&$cmp2 >= 0) return true;
241 if(ipversion($sn) == 4) {
247 // this function returns true if it is NOT conflicting
248 function isConflicting($subnet, $mask, $superid)
250 global $db, $wwwConnector;
252 if(ipversion($subnet) == 6) {
253 $res = $db->dbobject->query("select * from subnet where snid_id=='$superid'");
255 // we ip6togmp the sub sub...
256 $atwo = ip6ToGmp($subnet, $mask);
258 foreach($res as $row) {
260 $sm = $row["sn_mask"];
262 // we ip6 to gmp the main subnet...
263 $aone = ip6ToGmp($sn, $sm);
265 // 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"]
266 $cmp1 = gmp_cmp($aone["end"], $atwo["start"]);
267 $cmp2 = gmp_cmp($aone["start"], $atwo["end"]);
269 error_log("conflighting cmp1, $cmp1, cmp2, $cmp2 ".gmp_strval($aone["end"])." - ".gmp_strval($aone["start"])." - ".gmp_strval($atwo["end"])." - ".gmp_strval($atwo["start"])." - ");
271 if($cmp1 < 0) return true;
272 if($cmp2 > 0) return true;