PageRenderTime 57ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/functions/functions-network.php

https://bitbucket.org/bertramtruong/phpipam
PHP | 1890 lines | 1036 code | 387 blank | 467 comment | 335 complexity | 6739ccaa24858604e0f6df032ef632b1 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Network functions
  4. *
  5. */
  6. /* @common functions ---------------- */
  7. /**
  8. * Resolve reverse DNS name if blank
  9. * Return class and name
  10. */
  11. function ResolveDnsName ( $ip )
  12. {
  13. // format to dotted representation
  14. $ip = Transform2long ( $ip );
  15. // resolve dns name if it is empty and configured
  16. if ( empty($dns_name) ) {
  17. $return['class'] = "resolved";
  18. $return['name'] = gethostbyaddr( $ip );
  19. }
  20. // if nothing resolves revert to blank
  21. if ($return['name'] == $ip) {
  22. $return['name'] = "";
  23. }
  24. /* return result */
  25. return($return);
  26. }
  27. /**
  28. * Present numbers in pow 10, only for IPv6
  29. */
  30. function reformatNumber ($number)
  31. {
  32. $length = strlen($number);
  33. $pos = $length - 3;
  34. if ($length > 8) {
  35. $number = "~". substr($number, 0, $length - $pos) . "&middot;10^<sup>". $pos ."</sup>";
  36. }
  37. return $number;
  38. }
  39. /**
  40. * Reformat IP address state
  41. */
  42. function reformatIPState ($state)
  43. {
  44. /*
  45. 0 = not active
  46. 1 = active
  47. 2 = reserved
  48. */
  49. switch ($state)
  50. {
  51. /*
  52. case "0": return "Offline"; break;
  53. case "1": return " "; break;
  54. case "2": return "Reserved";break;
  55. default: return $state;
  56. */
  57. case "0": return "<i class='icon-warning-sign icon-gray state' rel='tooltip' title='Not in use (Offline)'></i>"; break;
  58. case "1": return " "; break;
  59. case "2": return "<i class='icon-gray icon-tag state' rel='tooltip' title='Reserved'></i>"; break;
  60. default: return $state;
  61. }
  62. }
  63. /**
  64. * Verify that switch exists
  65. */
  66. function verifySwitchByName ($hostname)
  67. {
  68. global $db; # get variables from config file
  69. /* set check query and get result */
  70. $database = new database ($db['host'], $db['user'], $db['pass'], $db['name']);
  71. $query = 'select * from `switches` where `hostname` = "'. $hostname .'";';
  72. /* fetch role */
  73. $role = $database->getRow($query);
  74. /* close database connection */
  75. $database->close();
  76. /* return true if viewer, else false */
  77. if (!$role) {
  78. return false;
  79. }
  80. else {
  81. return true;
  82. }
  83. }
  84. /**
  85. * Verify that switch exists
  86. */
  87. function verifySwitchById ($id)
  88. {
  89. global $db; # get variables from config file
  90. /* set check query and get result */
  91. $database = new database ($db['host'], $db['user'], $db['pass'], $db['name']);
  92. $query = 'select * from `switches` where `id` = "'. $id .'";';
  93. /* fetch role */
  94. $role = $database->getRow($query);
  95. /* close database connection */
  96. $database->close();
  97. /* return true if viewer, else false */
  98. if (!$role) { return false; }
  99. else { return true; }
  100. }
  101. /**
  102. * Get Switch details by ID
  103. */
  104. function getSwitchById ($switchId)
  105. {
  106. global $db; # get variables from config file
  107. /* set check query and get result */
  108. $database = new database ($db['host'], $db['user'], $db['pass'], $db['name']);
  109. $query = 'select * from `switches` where `id` = "'. $switchId .' limit 1";';
  110. /* fetch role */
  111. $switch = $database->getArray($query);
  112. /* close database connection */
  113. $database->close();
  114. /* return true if viewer, else false */
  115. if (!$switch) { return false; }
  116. else { return $switch[0]; }
  117. }
  118. /* @VLAN functions ---------------- */
  119. /**
  120. * Validate VLAN number
  121. */
  122. function validateVlan ($vlan)
  123. {
  124. /* must be number:
  125. not 1
  126. reserved 1002-1005
  127. not higher that 4094
  128. */
  129. if(empty($vlan)) {
  130. return 'ok';
  131. }
  132. else if(!is_numeric($vlan)) {
  133. return 'VLAN must be numeric value!';
  134. }
  135. else if ($vlan > 4094) {
  136. return 'Vlan number can be max 4094';
  137. }
  138. else {
  139. return 'ok';
  140. }
  141. }
  142. /**
  143. * get VLAN details by ID
  144. */
  145. function getVLANbyNumber ($number)
  146. {
  147. global $db; # get variables from config file
  148. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  149. /* execute query */
  150. $query = 'select * from `vlans` where `number` = "'. $number .'";';
  151. /* update database */
  152. $vlan = $database->getArray($query);
  153. /* return false if none, else list */
  154. if(sizeof($vlan) == 0) {
  155. return false;
  156. }
  157. else {
  158. return $vlan;
  159. }
  160. }
  161. /* @VRF functions ---------------- */
  162. /**
  163. * get all VRFs
  164. */
  165. function getAllVRFs ()
  166. {
  167. global $db; # get variables from config file
  168. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  169. /* execute query */
  170. $query = "select * from `vrf`;";
  171. /* update database */
  172. $vrfs = $database->getArray($query);
  173. /* return false if none, else list */
  174. if(sizeof($vrfs) == 0) {
  175. return false;
  176. }
  177. else {
  178. return $vrfs;
  179. }
  180. }
  181. /**
  182. * get vrf details by id
  183. */
  184. function getVRFDetailsById ($vrfId)
  185. {
  186. global $db; # get variables from config file
  187. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  188. /* execute query */
  189. $query = 'select * from `vrf` where `vrfId` = "'. $vrfId .'";';
  190. /* update database */
  191. $vrf = $database->getArray($query);
  192. /* return false if none, else list */
  193. if(sizeof($vrf) == 0) {
  194. return false;
  195. }
  196. else {
  197. return $vrf[0];
  198. }
  199. }
  200. /* @section functions ---------------- */
  201. /**
  202. * Get all sections
  203. */
  204. function fetchSections ()
  205. {
  206. global $db; # get variables from config file
  207. /* set query */
  208. $query = 'select * from `sections` order by `id` asc;';
  209. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  210. /* fetch results */
  211. $sections = $database->getArray($query);
  212. /* close database connection */
  213. $database->close();
  214. /* return subnets array */
  215. return($sections);
  216. }
  217. /**
  218. * Get section details - provide section id
  219. */
  220. function getSectionDetailsById ($id)
  221. {
  222. global $db; # get variables from config file
  223. /* set query, open db connection and fetch results */
  224. $query = 'select * from sections where id = "'. $id .'";';
  225. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  226. $subnets = $database->getArray($query);
  227. $database->close();
  228. /* return section */
  229. if(sizeof($subnets) > 0) { return($subnets[0]); }
  230. }
  231. /**
  232. * Get section details - provide section name
  233. */
  234. function getSectionDetailsByName ($name)
  235. {
  236. global $db; # get variables from config file
  237. /* set query, open db connection and fetch results */
  238. $query = 'select * from sections where `name` = "'. $name .'";';
  239. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  240. $subnets = $database->getArray($query);
  241. $database->close();
  242. /* return subnets array */
  243. return($subnets[0]);
  244. }
  245. /* @subnet functions ---------------- */
  246. /**
  247. * Get all subnets
  248. */
  249. function fetchAllSubnets ()
  250. {
  251. global $db; # get variables from config file
  252. /* set query */
  253. $query = 'select * from subnets;';
  254. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  255. /* fetch results */
  256. $sections = $database->getArray($query);
  257. /* close database connection */
  258. $database->close();
  259. /* return subnets array */
  260. return($sections);
  261. }
  262. /**
  263. * Get all subnets in provided sectionId
  264. */
  265. function fetchSubnets ($sectionId)
  266. {
  267. global $db; # get variables from config file
  268. /* set query, open db connection and fetch results */
  269. $query = 'select * from subnets where sectionId = "'. $sectionId .'" ORDER BY masterSubnetId,subnet ASC;';
  270. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  271. $subnets = $database->getArray($query);
  272. $database->close();
  273. /* return subnets array */
  274. return($subnets);
  275. }
  276. /**
  277. * Get all master subnets in provided sectionId
  278. */
  279. function fetchMasterSubnets ($sectionId)
  280. {
  281. global $db; # get variables from config file
  282. # set query, open db connection and fetch results
  283. $query = 'select * from subnets where sectionId = "'. $sectionId .'" and (`masterSubnetId` = "0" or `masterSubnetId` IS NULL) ORDER BY subnet ASC;';
  284. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  285. $subnets = $database->getArray($query);
  286. $database->close();
  287. # return subnets array
  288. return($subnets);
  289. }
  290. /**
  291. * Get all slave subnets in provided subnetId
  292. */
  293. function getAllSlaveSubnetsBySubnetId ($subnetId)
  294. {
  295. global $db; # get variables from config file
  296. # set query, open db connection and fetch results
  297. $query = 'select * from subnets where `masterSubnetId` = "'. $subnetId .'" ORDER BY subnet ASC;';
  298. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  299. $subnets = $database->getArray($query);
  300. $database->close();
  301. # return subnets array
  302. return($subnets);
  303. }
  304. /**
  305. * Get all ip addresses in requested subnet bt provided Id
  306. */
  307. function getIpAddressesBySubnetId ($subnetId)
  308. {
  309. global $db; # get variables from config file
  310. /* set query, open db connection and fetch results */
  311. $query = 'select * from `ipaddresses` where subnetId = "'. $subnetId .'" order by `ip_addr` ASC;';
  312. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  313. $ipaddresses = $database->getArray($query);
  314. $database->close();
  315. /* return ip address array */
  316. return($ipaddresses);
  317. }
  318. /**
  319. * Get all ip addresses in requested subnet by provided Id, sort by fieldname and direction!
  320. */
  321. function getIpAddressesBySubnetIdSort ($subnetId, $fieldName, $direction)
  322. {
  323. global $db; # get variables from config file
  324. /* set query, open db connection and fetch results */
  325. $query = 'select * from `ipaddresses` where subnetId = "'. $subnetId .'" order by `'. $fieldName .'` '. $direction .';';
  326. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  327. $ipaddresses = $database->getArray($query);
  328. $database->close();
  329. /* return ip address array */
  330. return($ipaddresses);
  331. }
  332. /**
  333. * Get all ip addresses in requested subnet by provided Id, sort by fieldname and direction!
  334. */
  335. function getIpAddressesBySubnetIdslavesSort ($subnetId, $fieldName, $direction)
  336. {
  337. global $db; # get variables from config file
  338. /* get ALL slave subnets, then remove all subnets and IP addresses */
  339. global $removeSlaves;
  340. getAllSlaves ($subnetId);
  341. $removeSlaves = array_unique($removeSlaves);
  342. /* set query, open db connection and fetch results */
  343. $query = 'select * from `ipaddresses` where subnetId = "" ';
  344. foreach($removeSlaves as $subnetId2) {
  345. if($subnetId2 != $subnetId) { # ignore orphaned
  346. $query .= " or `subnetId` = '$subnetId2' ";
  347. }
  348. }
  349. $query .= 'order by `'. $fieldName .'` '. $direction .';';
  350. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  351. $ipaddresses = $database->getArray($query);
  352. $database->close();
  353. /* return ip address array */
  354. return($ipaddresses);
  355. }
  356. /**
  357. * Count number of ip addresses in provided subnet
  358. */
  359. function countIpAddressesBySubnetId ($subnetId)
  360. {
  361. global $db; # get variables from config file
  362. /* set query, open db connection and fetch results */
  363. $query = 'select count(*) from ipaddresses where subnetId = "'. $subnetId .'" order by subnetId ASC;';
  364. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  365. $count = $database->getArray($query);
  366. $database->close();
  367. /* we only need count field */
  368. $count = $count[0]['count(*)'];
  369. /* return ip address array */
  370. return($count);
  371. }
  372. /**
  373. * Get details for requested subnet by Id
  374. *
  375. * *** OLD *** - not used anymore!!!
  376. */
  377. function getSubnetDetails ($subnetId)
  378. {
  379. global $db; # get variables from config file
  380. /* set query, open db connection and fetch results */
  381. $query = 'select * from subnets where id = "'. $subnetId .'";';
  382. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  383. $SubnetDetails = $database->getArray($query);
  384. $database->close();
  385. /* return subnet details - only 1st field! We cannot do getRow because we need associative array */
  386. if(sizeof($SubnetDetails) > 0) { return($SubnetDetails[0]); }
  387. }
  388. /**
  389. * Get details for requested subnet by ID
  390. */
  391. function getSubnetDetailsById ($id)
  392. {
  393. global $db; # get variables from config file
  394. /* set query, open db connection and fetch results */
  395. $query = 'select * from `subnets` where `id` = "'. $id .'";';
  396. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  397. $SubnetDetails = $database->getArray($query);
  398. $database->close();
  399. /* return subnet details - only 1st field! We cannot do getRow because we need associative array */
  400. if(sizeof($SubnetDetails) > 0) { return($SubnetDetails[0]); }
  401. }
  402. /**
  403. * Calculate subnet details
  404. *
  405. * Calculate subnet details based on input!
  406. *
  407. * We must provide used hosts and subnet mask to calculate free hosts, and subnet to identify type
  408. */
  409. function calculateSubnetDetails ( $usedhosts, $bitmask, $subnet )
  410. {
  411. // number of used hosts
  412. $SubnetCalculateDetails['used'] = $usedhosts;
  413. // calculate max hosts
  414. if ( IdentifyAddress( $subnet ) == "IPv4") { $type = 0; }
  415. else { $type = 1; }
  416. $SubnetCalculateDetails['maxhosts'] = MaxHosts( $bitmask, $type );
  417. // calculate free hosts
  418. $SubnetCalculateDetails['freehosts'] = gmp_strval( gmp_sub ($SubnetCalculateDetails['maxhosts'] , $SubnetCalculateDetails['used']) );
  419. //reset maxhosts for /31 and /32 subnets
  420. if (gmp_cmp($SubnetCalculateDetails['maxhosts'],1) == -1) {
  421. $SubnetCalculateDetails['maxhosts'] = "1";
  422. }
  423. //if more than 100% fix it! (for /31 and /32)
  424. /*
  425. if($SubnetCalculateDetails['used'] > $SubnetCalculateDetails['maxhosts'] ) {
  426. $SubnetCalculateDetails['maxhosts'] = $SubnetCalculateDetails['used'];
  427. $SubnetCalculateDetails['freehosts'] = 0;
  428. }
  429. */
  430. // calculate use percentage
  431. $SubnetCalculateDetails['freehosts_percent'] = round( ( ($SubnetCalculateDetails['freehosts'] * 100) / $SubnetCalculateDetails['maxhosts']), 2 );
  432. return( $SubnetCalculateDetails );
  433. }
  434. /**
  435. * Check if subnet already exists in section!
  436. *
  437. * Subnet policy:
  438. * - inside section subnets cannot overlap!
  439. * - same subnet can be configured in different sections
  440. */
  441. function verifySubnetOverlapping ($sectionId, $subnetNew)
  442. {
  443. /* we need to get all subnets in section */
  444. global $db;
  445. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  446. /* first we must get all subnets in section (by sectionId) */
  447. $querySubnets = 'select subnet,mask from subnets where sectionId = "'. $sectionId .'";';
  448. $allSubnets = $database->getArray($querySubnets);
  449. /* set new Subnet array */
  450. $subnet['subnet'] = $subnetNew;
  451. /* IPv4 or ipv6? */
  452. $type = IdentifyAddress( $subnet['subnet'] );
  453. /* we need network and broadcast address and check for both if the exist in any network!*/
  454. if ($type == "IPv4")
  455. {
  456. /* verify new against each existing if they exist */
  457. if (!empty($allSubnets)) {
  458. foreach ($allSubnets as $existingSubnet) {
  459. /* we need cidr format! */
  460. $existingSubnet['subnet'] = Transform2long($existingSubnet['subnet']) .'/'. $existingSubnet['mask'];
  461. if ( verifyIPv4SubnetOverlapping ($subnetNew, $existingSubnet['subnet']) ) {
  462. return 'Subnet overlapps with '. $existingSubnet['subnet'];
  463. }
  464. }
  465. }
  466. }
  467. else
  468. {
  469. /* verify new against each existing */
  470. foreach ($allSubnets as $existingSubnet) {
  471. /* we need cidr format! */
  472. $existingSubnet['subnet'] = Transform2long($existingSubnet['subnet']) .'/'. $existingSubnet['mask'];
  473. if ( verifyIPv6SubnetOverlapping ($subnetNew, $existingSubnet['subnet']) ) {
  474. return 'Subnet overlapps with '. $existingSubnet['subnet'];
  475. }
  476. }
  477. }
  478. return false;
  479. }
  480. /**
  481. * Check if nested subnet already exists in section!
  482. *
  483. * Subnet policy:
  484. * - inside section subnets cannot overlap!
  485. * - same subnet can be configured in different sections
  486. */
  487. function verifyNestedSubnetOverlapping ($sectionId, $subnetNew)
  488. {
  489. /* we need to get all subnets in section */
  490. global $db;
  491. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  492. /* first we must get all subnets in section (by sectionId) */
  493. $querySubnets = 'select subnet,mask from subnets where sectionId = "'. $sectionId .'" and `masterSubnetId` != "0" and `masterSubnetId` IS NOT NULL;';
  494. $allSubnets = $database->getArray($querySubnets);
  495. /* set new Subnet array */
  496. $subnet['subnet'] = $subnetNew;
  497. /* IPv4 or ipv6? */
  498. $type = IdentifyAddress( $subnet['subnet'] );
  499. /* we need network and broadcast address and check for both if the exist in any network!*/
  500. if ($type == "IPv4")
  501. {
  502. /* verify new against each existing if they exist */
  503. if (!empty($allSubnets)) {
  504. foreach ($allSubnets as $existingSubnet) {
  505. /* we need cidr format! */
  506. $existingSubnet['subnet'] = Transform2long($existingSubnet['subnet']) .'/'. $existingSubnet['mask'];
  507. if ( verifyIPv4SubnetOverlapping ($subnetNew, $existingSubnet['subnet']) ) {
  508. return 'Subnet overlapps with '. $existingSubnet['subnet'];
  509. }
  510. }
  511. }
  512. }
  513. else
  514. {
  515. /* verify new against each existing */
  516. foreach ($allSubnets as $existingSubnet) {
  517. /* we need cidr format! */
  518. $existingSubnet['subnet'] = Transform2long($existingSubnet['subnet']) .'/'. $existingSubnet['mask'];
  519. if ( verifyIPv6SubnetOverlapping ($subnetNew, $existingSubnet['subnet']) ) {
  520. return 'Subnet overlapps with '. $existingSubnet['subnet'];
  521. }
  522. }
  523. }
  524. return false;
  525. }
  526. /**
  527. * Check if subnet contains slaves
  528. */
  529. function subnetContainsSlaves($subnetId)
  530. {
  531. global $db; # get variables from config file
  532. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  533. /* get all ip addresses in subnet */
  534. $query = 'SELECT count(*) from subnets where `masterSubnetId` = "'. $subnetId .'";';
  535. $slaveSubnets = $database->getArray($query);
  536. if($slaveSubnets[0]['count(*)']) {
  537. return true;
  538. }
  539. else {
  540. return false;
  541. }
  542. }
  543. /**
  544. * Verify IPv4 subnet overlapping
  545. *
  546. * both must be in CIDR format (10.4.5.0/24)!
  547. *
  548. */
  549. function verifyIPv4SubnetOverlapping ($subnet1, $subnet2)
  550. {
  551. /* IPv4 functions */
  552. require_once('PEAR/Net/IPv4.php');
  553. $Net_IPv4 = new Net_IPv4();
  554. /* subnet 2 needs to be parsed to get subnet and broadcast */
  555. $net1 = $Net_IPv4->parseAddress( $subnet1 );
  556. $net2 = $Net_IPv4->parseAddress( $subnet2 );
  557. /* network and broadcast */
  558. $nw1 = $net1->network;
  559. $nw2 = $net2->network;
  560. $bc1 = $net1->broadcast;
  561. $bc2 = $net2->broadcast;
  562. /* network and broadcast in decimal format */
  563. $nw1_dec = Transform2decimal( $net1->network);
  564. $nw2_dec = Transform2decimal( $net2->network);
  565. $bc1_dec = Transform2decimal( $net1->broadcast);
  566. $bc2_dec = Transform2decimal( $net2->broadcast);
  567. /* calculate delta */
  568. $delta1 = $bc1_dec - $nw1_dec;
  569. $delta2 = $bc2_dec - $nw2_dec;
  570. /* calculate if smaller is inside bigger */
  571. if ($delta1 < $delta2)
  572. {
  573. /* check smaller nw and bc against bigger network */
  574. if ( $Net_IPv4->ipInNetwork($nw1, $subnet2) || $Net_IPv4->ipInNetwork($bc1, $subnet2) ) {
  575. return true;
  576. }
  577. }
  578. else
  579. {
  580. /* check smaller nw and bc against bigger network */
  581. if ( $Net_IPv4->ipInNetwork($nw2, $subnet1) || $Net_IPv4->ipInNetwork($bc2, $subnet1) ) {
  582. return true;
  583. }
  584. }
  585. return false;
  586. }
  587. /**
  588. * Verify IPv6 subnet overlapping
  589. *
  590. * both must be in CIDR format (2001:fee1::/48)!
  591. * subnet1 will be checked against subnet2
  592. *
  593. */
  594. function verifyIPv6SubnetOverlapping ($subnet1, $subnet2)
  595. {
  596. /* IPv6 functions */
  597. require_once('PEAR/Net/IPv6.php');
  598. $Net_IPv6 = new Net_IPv6();
  599. /* remove netmask from subnet1 */
  600. $subnet1 = $Net_IPv6->removeNetmaskSpec ($subnet1);
  601. /* verify */
  602. if ($Net_IPv6->isInNetmask ( $subnet1 , $subnet2 ) ) {
  603. return true;
  604. }
  605. return false;
  606. }
  607. /**
  608. * Verify that new nested subnet is inside master subnet!
  609. *
  610. * $root = root subnet
  611. * $new = new subnet that we wish to add to root subnet
  612. */
  613. function verifySubnetNesting ($rootId, $new)
  614. {
  615. //first get details for root subnet
  616. $rootDetails = getSubnetDetailsById($rootId);
  617. $rootDetails = Transform2long($rootDetails['subnet']) . "/" . $rootDetails['mask'];
  618. /* IPv4 or ipv6? */
  619. $type1 = IdentifyAddress( $rootDetails );
  620. $type2 = IdentifyAddress( $new );
  621. /* both must be IPv4 or IPv6 */
  622. if($type1 != $type2) {
  623. return false;
  624. die();
  625. }
  626. /* we need network and broadcast address and check for both if the exist in any network!*/
  627. if(isSubnetInsideSubnet ($new, $rootDetails)) {
  628. return true;
  629. }
  630. else {
  631. return false;
  632. }
  633. }
  634. /**
  635. * Verify that subnet a is inside subnet b!
  636. *
  637. * both subnets must be in ip format (e.g. 10.10.10.0/24)
  638. */
  639. function isSubnetInsideSubnet ($subnetA, $subnetB)
  640. {
  641. $type = IdentifyAddress( $subnetA );
  642. /* IPv4 */
  643. if ($type == "IPv4") {
  644. /* IPv4 functions */
  645. require_once('PEAR/Net/IPv4.php');
  646. $Net_IPv4 = new Net_IPv4();
  647. /* subnet A needs to be parsed to get subnet and broadcast */
  648. $net = $Net_IPv4->parseAddress( $subnetA );
  649. //both network and broadcast must be inside root subnet!
  650. if( ($Net_IPv4->ipInNetwork($net->network, $subnetB)) && ($Net_IPv4->ipInNetwork($net->broadcast, $subnetB)) ) {
  651. return true;
  652. }
  653. else {
  654. return false;
  655. }
  656. }
  657. /* IPv6 */
  658. else {
  659. /* IPv6 functions */
  660. require_once('PEAR/Net/IPv6.php');
  661. $Net_IPv6 = new Net_IPv6();
  662. /* remove netmask from subnet1 */
  663. $subnetA = $Net_IPv6->removeNetmaskSpec ($subnetA);
  664. /* verify */
  665. if ($Net_IPv6->isInNetmask ( $subnetA, $subnetB ) ) {
  666. return true;
  667. }
  668. else {
  669. return false;
  670. }
  671. }
  672. }
  673. /**
  674. * Check if subnet is admin-locked
  675. */
  676. function isSubnetWriteProtected($subnetId)
  677. {
  678. global $db; # get variables from config file
  679. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  680. /* first update request */
  681. $query = 'select `adminLock` from subnets where id = '. $subnetId .';';
  682. $lock = $database->getArray($query);
  683. /* return true if locked */
  684. if($lock[0]['adminLock'] == 1) {
  685. return true;
  686. }
  687. else {
  688. return false;
  689. }
  690. }
  691. /**
  692. * Print dropdown menu for subnets in section!
  693. */
  694. function printDropdownMenuBySection($sectionId, $subnetMasterId = "0")
  695. {
  696. # get all subnets
  697. $subnets = fetchSubnets ($sectionId);
  698. $html = array();
  699. $rootId = 0; # root is 0
  700. foreach ( $subnets as $item )
  701. $children[$item['masterSubnetId']][] = $item;
  702. # loop will be false if the root has no children (i.e., an empty menu!)
  703. $loop = !empty( $children[$rootId] );
  704. # initializing $parent as the root
  705. $parent = $rootId;
  706. $parent_stack = array();
  707. # display selected subnet as opened
  708. $allParents = getAllParents ($_REQUEST['subnetId']);
  709. # structure
  710. $html[] = "<select name='masterSubnetId'>";
  711. # root
  712. $html[] = "<option disabled>Select Master subnet</option>";
  713. $html[] = "<option value='0'>Root subnet</option>";
  714. # return table content (tr and td's)
  715. while ( $loop && ( ( $option = each( $children[$parent] ) ) || ( $parent > $rootId ) ) )
  716. {
  717. # repeat
  718. $repeat = str_repeat( " - ", ( count($parent_stack)) );
  719. # dashes
  720. if(count($parent_stack) == 0) { $dash = ""; }
  721. else { $dash = $repeat; }
  722. # count levels
  723. $count = count( $parent_stack ) + 1;
  724. # print table line
  725. if(strlen($option['value']['subnet']) > 0) {
  726. # selected
  727. if($option['value']['id'] == $subnetMasterId) { $html[] = "<option value='".$option['value']['id']."' selected='selected'>$repeat ".transform2long($option['value']['subnet'])."/".$option['value']['mask']." (".$option['value']['description'].")</option>"; }
  728. else { $html[] = "<option value='".$option['value']['id']."'>$repeat ".transform2long($option['value']['subnet'])."/".$option['value']['mask']." (".$option['value']['description'].")</option>"; }
  729. }
  730. if ( $option === false ) { $parent = array_pop( $parent_stack ); }
  731. # Has slave subnets
  732. elseif ( !empty( $children[$option['value']['id']] ) ) {
  733. array_push( $parent_stack, $option['value']['masterSubnetId'] );
  734. $parent = $option['value']['id'];
  735. }
  736. # Last items
  737. else { }
  738. }
  739. $html[] = "</select>";
  740. print implode( "\n", $html );
  741. }
  742. /**
  743. * Get VLAN number form Id
  744. */
  745. function subnetGetVLANdetailsById($vlanId)
  746. {
  747. global $db; # get variables from config file
  748. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  749. /* first update request */
  750. $query = 'select * from `vlans` where `vlanId` = "'. $vlanId .'";';
  751. $vlan = $database->getArray($query);
  752. /* return vlan details if exists */
  753. if(sizeof($vlan) != 0) {
  754. return $vlan[0];
  755. }
  756. else {
  757. return false;
  758. }
  759. }
  760. /**
  761. * Get all VLANS
  762. */
  763. function getAllVlans($tools = false)
  764. {
  765. global $db; # get variables from config file
  766. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  767. # custom fields
  768. $myFields = getCustomVLANFields();
  769. $myFieldsInsert['id'] = '';
  770. if(sizeof($myFields) > 0) {
  771. /* set inserts for custom */
  772. foreach($myFields as $myField) {
  773. $myFieldsInsert['id'] .= ',`vlans`.`'. $myField['name'] .'`';
  774. }
  775. }
  776. /* check if it came from tools and use different query! */
  777. if($tools) {
  778. $query = 'SELECT vlans.number,vlans.name,vlans.description,subnets.subnet,subnets.mask,subnets.id'.$myFieldsInsert['id'].' AS subnetId,subnets.sectionId FROM vlans LEFT JOIN subnets ON subnets.vlanId = vlans.vlanId ORDER BY vlans.number ASC;';
  779. }
  780. else {
  781. $query = 'select * from `vlans` order by `number` asc;';
  782. }
  783. $vlan = $database->getArray($query);
  784. /* return vlan details */
  785. return $vlan;
  786. }
  787. /**
  788. * Get subnets by VLAN id
  789. */
  790. function getSubnetsByVLANid ($id)
  791. {
  792. global $db; # get variables from config file
  793. /* set query, open db connection and fetch results */
  794. $query = 'select * from `subnets` where `vlanId` = "'. $id .'";';
  795. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  796. $SubnetDetails = $database->getArray($query);
  797. $database->close();
  798. /* return subnet details - only 1st field! We cannot do getRow because we need associative array */
  799. return($SubnetDetails);
  800. }
  801. /**
  802. * Calculate maximum number of IPv4 / IPv6 hosts per subnet
  803. */
  804. function MaxHosts( $mask, $type = 0 )
  805. {
  806. /* IPv4 address */
  807. if($type == 0) {
  808. //31 and 31 networks
  809. if($mask==31 || $mask == 32) {
  810. return pow(2, (32 - $mask));
  811. }
  812. else {
  813. return pow(2, (32 - $mask)) -2;
  814. }
  815. }
  816. /* IPv6 address */
  817. else {
  818. //31 and 31 networks
  819. if($mask==127 || $mask == 128) {
  820. return gmp_strval(gmp_pow(2, 128 - $mask));
  821. }
  822. else {
  823. return gmp_strval(gmp_sub(gmp_pow(2, 128 - $mask) ,1));
  824. }
  825. }
  826. }
  827. /**
  828. * get all subnets belonging to vrf
  829. */
  830. function getAllSubnetsInVRF($vrfId)
  831. {
  832. global $db; # get variables from config file
  833. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  834. /* execute query */
  835. $query = 'select * from `subnets` where `vrfId` = "'. $vrfId .'";';
  836. /* update database */
  837. $vrf = $database->getArray($query);
  838. /* return false if none, else list */
  839. if(sizeof($vrf) == 0) {
  840. return false;
  841. }
  842. else {
  843. return $vrf;
  844. }
  845. }
  846. /* @IP address functions ---------------- */
  847. /**
  848. * Get all IP addresses
  849. */
  850. function fetchAllIPAddresses ($hostnameSort = false)
  851. {
  852. global $db; # get variables from config file
  853. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  854. /* set query */
  855. if(!$hostnameSort) {
  856. $query = 'select * from ipaddresses;';
  857. }
  858. else {
  859. $query = 'select * from ipaddresses order by dns_name desc;';
  860. }
  861. /* fetch results */
  862. $ipaddresses = $database->getArray($query);
  863. /* close database connection */
  864. $database->close();
  865. /* return subnets array */
  866. return($ipaddresses);
  867. }
  868. /**
  869. * Get all IP addresses by hostname
  870. */
  871. function fetchAllIPAddressesByName ($hostname)
  872. {
  873. global $db; # get variables from config file
  874. /* set query */
  875. $query = 'select * from ipaddresses where `dns_name` like "%'. $hostname .'%" order by `dns_name` desc;';
  876. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  877. /* fetch results */
  878. $ipaddresses = $database->getArray($query);
  879. /* close database connection */
  880. $database->close();
  881. /* return subnets array */
  882. return($ipaddresses);
  883. }
  884. /**
  885. * Get sectionId for requested name - needed for hash page loading
  886. */
  887. function getSectionIdFromSectionName ($sectionName)
  888. {
  889. global $db; # get variables from config file
  890. /* set query, open db connection and fetch results */
  891. $query = 'select id from sections where name = "'. $sectionName .'";';
  892. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  893. $SubnetDetails = $database->getArray($query);
  894. $database->close();
  895. /* return subnet details - only 1st field! We cannot do getRow because we need associative array */
  896. return($SubnetDetails[0]['id']);
  897. }
  898. /**
  899. * Check for duplicates on add
  900. */
  901. function checkDuplicate ($ip, $subnetId)
  902. {
  903. global $db; # get variables from config file
  904. /* we need to put IP in decimal format */
  905. $ip = Transform2decimal ($ip);
  906. /* set query, open db connection and fetch results */
  907. $query = 'select * from `ipaddresses` where `ip_addr` = "'. $ip .'" and subnetId = "'. $subnetId .'" ;';
  908. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  909. $unique = $database->getArray($query);
  910. $database->close();
  911. /* return false if it exists */
  912. if (sizeof($unique) != 0 ) {
  913. return true;
  914. }
  915. else {
  916. return false;
  917. }
  918. }
  919. /**
  920. * Modify ( add / edit / delete ) IP address
  921. */
  922. function modifyIpAddress ($ip)
  923. {
  924. global $db; # get variables from config file
  925. /* set query, open db connection and fetch results */
  926. $query = SetInsertQuery($ip);
  927. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  928. if ( !$database->executeQuery($query) ) {
  929. return false;
  930. }
  931. else {
  932. return true;
  933. }
  934. }
  935. /**
  936. * set insert / update / delete query for adding IP address
  937. * based on provided array
  938. */
  939. function SetInsertQuery( $ip )
  940. {
  941. /* First we need to get custom fields! */
  942. $myFields = getCustomIPaddrFields();
  943. $myFieldsInsert['query'] = '';
  944. $myFieldsInsert['values'] = '';
  945. if(sizeof($myFields) > 0) {
  946. /* set inserts for custom */
  947. foreach($myFields as $myField) {
  948. $myFieldsInsert['query'] .= ', `'. $myField['name'] .'`';
  949. $myFieldsInsert['values'] .= ", '". $ip[$myField['name']] . "'";
  950. }
  951. }
  952. /* insert */
  953. if( $ip['action'] == "add" )
  954. {
  955. $query = "insert into `ipaddresses` ";
  956. $query .= "(`subnetId`,`description`,`ip_addr`, `dns_name`,`mac`, `owner`, `state`, `switch`, `port`, `note` ". $myFieldsInsert['query'] .") ";
  957. $query .= "values ";
  958. $query .= "('". $ip['subnetId'] ."', '". $ip['description'] ."', '". Transform2decimal( $ip['ip_addr'] ) ."', ". "\n";
  959. $query .= " '". $ip['dns_name'] ."', '". $ip['mac'] ."', '". $ip['owner'] ."', '". $ip['state'] ."', ". "\n";
  960. $query .= " '". $ip['switch'] ."', '". $ip['port'] ."', '". $ip['note'] ."'". $myFieldsInsert['values'] .");";
  961. }
  962. /* edit multiple */
  963. else if( ($ip['action'] == "edit") && ($ip['type'] == "series") )
  964. {
  965. $query = "update `ipaddresses` ";
  966. $query .= "set `ip_addr` = '". Transform2decimal( $ip['ip_addr'] ) ."', ";
  967. $query .= "`description` = '". $ip['description'] ."', ";
  968. $query .= "`dns_name` = '". $ip['dns_name'] ."' ,";
  969. $query .= "`mac` = '". $ip['mac'] ."' ,";
  970. $query .= "`owner` = '". $ip['owner'] ."' ,";
  971. $query .= "`state` = '". $ip['state'] ."',";
  972. $query .= "`switch` = '". $ip['switch'] ."',";
  973. $query .= "`port` = '". $ip['port'] ."',";
  974. # custom!
  975. foreach($myFields as $myField) {
  976. $query .= "`". $myField['name'] ."` = '". $ip[$myField['name']] ."',";
  977. }
  978. $query .= "`note` = '". $ip['note'] ."' ";
  979. $query .= "where `subnetId` = '". $ip['subnetId'] ."' and `ip_addr` = '". Transform2decimal( $ip['ip_addr'] ) ."';";
  980. }
  981. /* edit */
  982. else if( $ip['action'] == "edit" )
  983. {
  984. $query = "update ipaddresses ";
  985. $query .= "set `ip_addr` = '". Transform2decimal( $ip['ip_addr'] ) ."', `description` = '". $ip['description'] ."', `dns_name` = '". $ip['dns_name'] ."' , `mac` = '". $ip['mac'] ."', ". "\n";
  986. #custom!
  987. foreach($myFields as $myField) {
  988. $query .= "`". $myField['name'] ."` = '". $ip[$myField['name']] ."',";
  989. }
  990. $query .= "`owner` = '". $ip['owner'] ."' , `state` = '". $ip['state'] ."', `switch` = '". $ip['switch'] ."', ". "\n";
  991. $query .= "`port` = '". $ip['port'] ."', `note` = '". $ip['note'] ."' ";
  992. $query .= "where `id` = '". $ip['id'] ."';";
  993. }
  994. /* delete multiple */
  995. else if( ($ip['action'] == "delete") && ($ip['type'] == "series") ) {
  996. $query = "delete from ipaddresses where `subnetId` = '". $ip['subnetId'] ."' and `ip_addr` = '". Transform2decimal( $ip['ip_addr'] ) ."';";
  997. }
  998. /* delete */
  999. else if( $ip['action'] == "delete" ) {
  1000. $query = "delete from ipaddresses where `id` = '". $ip['id'] ."';";
  1001. }
  1002. /* move */
  1003. else if ($ip['action'] == "move") {
  1004. $query = "update `ipaddresses` set `subnetId` = '$ip[newSubnet]' where `id` = '$ip[id]';";
  1005. }
  1006. /* return query */
  1007. return $query;
  1008. }
  1009. /**
  1010. * Get IP address details
  1011. */
  1012. function getIpAddrDetailsById ($id)
  1013. {
  1014. global $db; # get variables from config file
  1015. /* set query, open db connection and fetch results */
  1016. $query = 'select * from `ipaddresses` where `id` = "'. $id .'";';
  1017. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  1018. $details = $database->getArray($query);
  1019. //we only fetch 1 field
  1020. $details = $details[0];
  1021. //change IP address formatting to dotted(long)
  1022. $details['ip_addr'] = Transform2long( $details['ip_addr'] );
  1023. /* return result */
  1024. return($details);
  1025. }
  1026. /**
  1027. * verify ip address from edit / add
  1028. * noStrict ignores NW and Broadcast checks
  1029. */
  1030. function VerifyIpAddress( $ip , $subnet , $noStrict = false )
  1031. {
  1032. /* First identify it */
  1033. $type = IdentifyAddress( $ip );
  1034. $type = IdentifyAddress( $subnet );
  1035. /* get mask */
  1036. $mask = explode("/", $subnet);
  1037. /* IPv4 verification */
  1038. if ( $type == 'IPv4' )
  1039. {
  1040. require_once 'PEAR/Net/IPv4.php';
  1041. $Net_IPv4 = new Net_IPv4();
  1042. // is it valid?
  1043. if (!$Net_IPv4->validateIP($ip)) {
  1044. $error = "IP address not valid!";
  1045. }
  1046. // it must be in provided subnet
  1047. else if (!$Net_IPv4->ipInNetwork($ip, $subnet)) {
  1048. $error = "IP address not in selected subnet!";
  1049. }
  1050. //ignore /31 and /32 subnet broadcast and subnet checks!
  1051. else if ($mask[1] == "31" || $mask[1] == "32" || $noStrict == true) {
  1052. # skip
  1053. }
  1054. // It cannot be subnet or broadcast
  1055. else {
  1056. $net = $Net_IPv4->parseAddress($subnet);
  1057. if ($net->network == $ip) {
  1058. $error = "Cannot add subnet as IP address!";
  1059. }
  1060. else if ($net->broadcast == $ip) {
  1061. $error = "Cannot add broadcast as IP address!";
  1062. }
  1063. }
  1064. }
  1065. /* IPv6 verification */
  1066. else
  1067. {
  1068. require_once 'PEAR/Net/IPv6.php';
  1069. $Net_IPv6 = new Net_IPv6();
  1070. //remove /xx from subnet
  1071. $subnet_short = $Net_IPv6->removeNetmaskSpec($subnet);
  1072. // is it valid?
  1073. if (!$Net_IPv6->checkIPv6($ip)) {
  1074. $error = "IP address not valid!";
  1075. }
  1076. // it must be in provided subnet
  1077. else if (!$Net_IPv6->isInNetmask($ip, $subnet)) {
  1078. $error = "IP address not in selected subnet!";
  1079. }
  1080. //ignore /127 and /128 subnet broadcast and subnet checks!
  1081. else if ($mask[1] == "127" || $mask[1] == "128" || $noStrict == true) {
  1082. # skip
  1083. }
  1084. //it cannot be subnet
  1085. else if ($ip == $subnet_short) {
  1086. $error = "Cannot add subnet as IP address!";
  1087. }
  1088. }
  1089. /* return results */
  1090. if( isset($error) )
  1091. return $error;
  1092. else {
  1093. return false;
  1094. }
  1095. }
  1096. /**
  1097. * verify ip address /mask 10.10.10.10./24 - CIDR
  1098. *
  1099. * if subnet == 0 we dont check if IP is subnet -> needed for ipCalc
  1100. */
  1101. function verifyCidr( $cidr , $subnet = 1 )
  1102. {
  1103. /* split it to network and subnet */
  1104. $temp = explode("/", $cidr);
  1105. $network = $temp[0];
  1106. $netmask = $temp[1];
  1107. //if one part is missing die
  1108. if (empty($network) || empty($netmask)) {
  1109. $errors[] = "Invalid CIDR format!";
  1110. }
  1111. /* Identify address type */
  1112. $type = IdentifyAddress( $network );
  1113. /* IPv4 verification */
  1114. if ( $type == 'IPv4' )
  1115. {
  1116. require_once 'PEAR/Net/IPv4.php';
  1117. $Net_IPv4 = new Net_IPv4();
  1118. if ($net = $Net_IPv4->parseAddress ($cidr)) {
  1119. //validate IP
  1120. if (!$Net_IPv4->validateIP ($net->ip)) {
  1121. $errors[] = "Invalid IP address!";
  1122. }
  1123. //network must be same as provided IP address
  1124. else if (($net->network != $net->ip) && ($subnet == 1)) {
  1125. $errors[] = "IP address cannot be subnet! (Consider using ". $net->network .")";
  1126. }
  1127. //validate netmask
  1128. else if (!$Net_IPv4->validateNetmask ($net->netmask)) {
  1129. $errors[] = 'Invalid netmask ' . $net->netmask;
  1130. }
  1131. }
  1132. else {
  1133. $errors[] = 'Invalid CIDR format!';
  1134. }
  1135. }
  1136. /* IPv6 verification */
  1137. else
  1138. {
  1139. require_once 'PEAR/Net/IPv6.php';
  1140. $Net_IPv6 = new Net_IPv6();
  1141. //validate IPv6
  1142. if (!$Net_IPv6->checkIPv6 ($cidr) ) {
  1143. $errors[] = "Invalid IPv6 address!";
  1144. }
  1145. else {
  1146. //validate subnet
  1147. $subnet = $Net_IPv6->getNetmask($cidr);
  1148. $subnet = $Net_IPv6->compress($subnet);
  1149. $subnetParse = explode("/", $cidr);
  1150. $subnetMask = $subnetParse[1];
  1151. $subnetNet = $subnetParse[0];
  1152. if ( ($subnetParse[0] != $subnet) && ($subnet == 1) ) {
  1153. $errors[] = "IP address cannot be subnet! (Consider using ". $subnet ."/". $subnetMask .")";
  1154. }
  1155. }
  1156. }
  1157. /* return array of errors */
  1158. return($errors);
  1159. }
  1160. /**
  1161. * parse IP address
  1162. *
  1163. * IP must be in CIDR format - '192.168.0.50/16'
  1164. */
  1165. function parseIpAddress( $ip, $mask )
  1166. {
  1167. /* IPv4 address */
  1168. if ( IdentifyAddress( $ip ) == "IPv4" )
  1169. {
  1170. require('PEAR/Net/IPv4.php');
  1171. $Net_IPv4 = new Net_IPv4();
  1172. $net = $Net_IPv4->parseAddress( $ip .'/'. $mask );
  1173. $out['network'] = $net->network; // 192.168.0.0
  1174. $out['ip'] = $net->ip; // 192.168.0.50
  1175. $out['broadcast'] = $net->broadcast; // 192.168.255.255
  1176. $out['bitmask'] = $net->bitmask; // 16
  1177. $out['netmask'] = $net->netmask; // 255.255.0.0
  1178. }
  1179. /* IPv6 address */
  1180. else
  1181. {
  1182. require('PEAR/Net/IPv6.php');
  1183. $Net_IPv6 = new Net_IPv6();
  1184. $out['network'] = $ip; // 2a34:120:feel::
  1185. $out['bitmask'] = $mask; // 48
  1186. $out['netmask'] = $mask; // 48 - we just duplicate it
  1187. //broadcast - we fake it with highest IP in subnet
  1188. $net = $Net_IPv6->parseaddress( $ip .'/'. $mask );
  1189. $out['broadcast'] = $net['end']; // 2a34:120:feel::ffff:ffff:ffff:ffff:ffff
  1190. }
  1191. return( $out );
  1192. }
  1193. /**
  1194. * Find unused ip addresses between two provided
  1195. *
  1196. * checkType = NW, bcast and none(normal)
  1197. */
  1198. function FindUnusedIpAddresses ($ip1, $ip2, $type, $broadcast = 0, $checkType = "", $mask = false )
  1199. {
  1200. /* calculate difference */
  1201. $diff = gmp_strval(gmp_sub($ip2, $ip1));
  1202. /* /32 */
  1203. if($mask == "32" && $checkType=="networkempty" && $type=="IPv4") {
  1204. $result['ip'] = long2ip($ip1);
  1205. $result['hosts'] = "1";
  1206. }
  1207. /* /31 */
  1208. else if($mask == "31" && $type=="IPv4") {
  1209. if($diff == 1 && $checkType == "networkempty" ) {
  1210. $result['ip'] = long2ip($ip1);
  1211. $result['hosts'] = "2";
  1212. }
  1213. if($diff == 1 && $checkType == "network" ) {
  1214. $result['ip'] = long2ip($ip1);
  1215. $result['hosts'] = "1";
  1216. }
  1217. else if($diff == 1 && $checkType == "" ) {
  1218. /*
  1219. $result['ip'] = long2ip($ip1);
  1220. $result['hosts'] = "";
  1221. */
  1222. }
  1223. else if($diff == 1 && $checkType == "broadcast" ) {
  1224. $result['ip'] = long2ip($ip2);
  1225. $result['hosts'] = "1";
  1226. }
  1227. else if($diff == 2 ) {
  1228. $result['ip'] = long2ip($ip1);
  1229. $result['hosts'] = "2";
  1230. }
  1231. }
  1232. /* /128 */
  1233. else if($mask == "128" && $checkType=="networkempty" && $type=="IPv6") {
  1234. $result['ip'] = long2ip6($ip1);
  1235. $result['hosts'] = "1";
  1236. }
  1237. /* /127 */
  1238. else if($mask == "127" && $type=="IPv6") {
  1239. if($diff == 1 && $checkType == "networkempty" ) {
  1240. $result['ip'] = long2ip6($ip1);
  1241. $result['hosts'] = "2";
  1242. }
  1243. if($diff == 1 && $checkType == "network" ) {
  1244. $result['ip'] = long2ip6($ip1);
  1245. $result['hosts'] = "1";
  1246. }
  1247. else if($diff == 1 && $checkType == "" ) {
  1248. }
  1249. else if($diff == 1 && $checkType == "broadcast" ) {
  1250. $result['ip'] = long2ip6($ip2);
  1251. $result['hosts'] = "1";
  1252. }
  1253. else if($diff == 2 ) {
  1254. $result['ip'] = long2ip6($ip1);
  1255. $result['hosts'] = "2";
  1256. }
  1257. }
  1258. /* if diff is less than 2 return false */
  1259. else if ( $diff < 2 ) {
  1260. return false;
  1261. }
  1262. /* if diff is 2 return 1 IP address in the middle */
  1263. else if ( $diff == 2 )
  1264. {
  1265. if ($type == "IPv4")
  1266. { //ipv4
  1267. $result['ip'] = long2ip($ip1 +1);
  1268. $result['hosts'] = "1";
  1269. }
  1270. else
  1271. { //ipv6
  1272. $ip1_return = gmp_strval(gmp_add($ip1,1));
  1273. $result['ip'] = long2ip6( $ip1_return );
  1274. $result['hosts'] = "1";
  1275. }
  1276. }
  1277. /* if diff is more than 2 return pool */
  1278. else
  1279. {
  1280. if ($type == "IPv4")
  1281. { //ipv4
  1282. $free = long2ip($ip1 +1) . ' - ' . long2ip($ip2 -1);
  1283. $result['ip'] = $free;
  1284. $result['hosts'] = gmp_strval(gmp_sub($diff, 1));;
  1285. }
  1286. else
  1287. { //ipv6
  1288. $ip1_return = gmp_strval(gmp_add($ip1,1));
  1289. //No broadcast in IPv6
  1290. if ($broadcast == 0)
  1291. {
  1292. $ip2_return = gmp_strval(gmp_sub($ip2,1));
  1293. }
  1294. else
  1295. {
  1296. $ip2_return = gmp_strval($ip2);
  1297. }
  1298. $free = long2ip6( $ip1_return ) . ' - ' . long2ip6( $ip2_return );
  1299. $result['ip'] = $free;
  1300. $result['hosts'] = gmp_strval(gmp_sub($diff, 1));
  1301. }
  1302. }
  1303. /* return result array with IP range and free hosts */
  1304. return $result;
  1305. }
  1306. /**
  1307. * Get first available IP address
  1308. */
  1309. function getFirstAvailableIPAddress ($subnetId)
  1310. {
  1311. global $db; # get variables from config file
  1312. $database = new database($db['host'], $db['user'], $db['pass'], $db['name']);
  1313. /* get all ip addresses in subnet */
  1314. $query = 'SELECT `ip_addr` from `ipaddresses` where `subnetId` = "'. $subnetId .'" order by `ip_addr` ASC;';
  1315. $ipAddresses = $database->getArray($query);
  1316. /* get subnet */
  1317. $query = 'SELECT `subnet`,`mask` from `subnets` where `id` = "'. $subnetId .'";';
  1318. $subnet2 = $database->getArray($query);
  1319. $subnet = $subnet2[0]['subnet'];
  1320. $mask = $subnet2[0]['mask'];
  1321. /* create array of IP addresses */
  1322. $ipaddressArray[] = $subnet;
  1323. foreach($ipAddresses as $ipaddress) {
  1324. $ipaddressArray[] = $ipaddress['ip_addr'];
  1325. }
  1326. //get array size
  1327. $size = sizeof($ipaddressArray);
  1328. $curr = 0;
  1329. //get type
  1330. $type = IdentifyAddress($subnet);
  1331. //if subnet is /32
  1332. if($mask == "32" && $type == "IPv4") {
  1333. if($size == 1) { $firstAvailable = $ipaddressArray[0]; }
  1334. else { $firstAvailable = false; }
  1335. }
  1336. //if subnet /31
  1337. else if($mask == "31" && $type == "IPv4") {
  1338. if($size == 1) { $firstAvailable = $ipaddressArray[0]; }
  1339. else if($size == 2) {
  1340. $delta = $ipaddressArray[1] - $ipaddressArray[0];
  1341. if($delta == 1) { $firstAvailable = $ipaddressArray[0]; }
  1342. else { $firstAvailable = gmp_strval(gmp_add($ipaddressArray[0], 1)); }
  1343. }
  1344. else { $firstAvailable = false; }
  1345. }
  1346. //if subnet is /128
  1347. else if($mask == "128" && $type == "IPv6") {
  1348. if($size == 1) { $firstAvailable = $ipaddressArray[0]; }
  1349. else { $firstAvailable = false; }
  1350. }
  1351. //if subnet /127
  1352. else if($mask == "127" && $type == "IPv6") {
  1353. if($size == 1) { $firstAvailable = $ipaddressArray[0]; }
  1354. else if($size == 2) {
  1355. $delta = $ipaddressArray[1] - $ipaddressArray[0];
  1356. if($delta == 1) { $firstAvailable = $ipaddressArray[0]; }
  1357. else { $firstAvailable = gmp_strval(gmp_add($ipaddressArray[0], 1)); }
  1358. }
  1359. else { $firstAvailable = false; }
  1360. }
  1361. //if size = 0 return subnet +1
  1362. else if($size == 1) {
  1363. $firstAvailable = gmp_strval(gmp_add($ipaddressArray[0], 1));
  1364. }
  1365. else {
  1366. //get first change -> delta > 1
  1367. for($m=1; $m <= $size -1; $m++) {
  1368. $delta = gmp_strval(gmp_sub($ipaddressArray[$m],$ipaddressArray[$m-1]));
  1369. //compare with previous
  1370. if ($delta != 1 ) {
  1371. $firstAvailable = gmp_strval(gmp_add($ipaddressArray[$m-1],1));
  1372. $m = $size;
  1373. }
  1374. else {
  1375. $firstAvailable = gmp_strval(gmp_add($ipaddressArray[$m],1));
  1376. }
  1377. }
  1378. //if bcast ignore!
  1379. if($type == "IPv4") {
  1380. require_once 'PEAR/Net/IPv4.php';
  1381. $Net_IPv4 = new Net_IPv4();
  1382. $net = $Net_IPv4->parseAddress(transform2long($subnet)."/".$mask);
  1383. if ($net->broadcast <= transform2long($firstAvailable)) { $firstAvailable = false; }
  1384. }
  1385. else if ($type == "IPv6") {
  1386. require_once 'PEAR/Net/IPv6.php';
  1387. $Net_IPv6 = new Net_IPv6();
  1388. $net = $Net_IPv6->parseAddress(transform2long($subnet)."/".$mask);
  1389. if ($net->broadcast == transform2long($firstAvailable)) { $firstAvailable = false; }
  1390. }
  1391. //else return last
  1392. else {
  1393. $firstAvailable = gmp_strval(gmp_add($ipaddressArray[$size-1],1));
  1394. }
  1395. }
  1396. /* return first available IP address */
  1397. return $firstAvailable;
  1398. }
  1399. /**
  1400. * Functions to transform IPv6 to decimal and back
  1401. *
  1402. */
  1403. function ip2long6 ($ipv6)
  1404. {
  1405. if($ipv6 == ".255.255.255"

Large files files are truncated, but you can click here to view the full file