api.dhcp.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. <?php
  2. /**
  3. * ISC-DHCPD server management class
  4. */
  5. class UbillingDHCP {
  6. /**
  7. * Contains available DHCP networks
  8. *
  9. * @var array
  10. */
  11. protected $allDhcpNets = array();
  12. /**
  13. * Contains available multinet networks
  14. *
  15. * @var array
  16. */
  17. protected $allMultinetNets = array();
  18. /**
  19. * Default message helper placeholder
  20. *
  21. * @var object
  22. */
  23. protected $messages = '';
  24. /**
  25. * Pregenerated DHCP configs path
  26. */
  27. const MULTINET_PATH = 'multinet/';
  28. /**
  29. * Default module URL
  30. */
  31. const URL_ME = '?module=dhcp';
  32. /**
  33. * DHCP config generation templates path
  34. */
  35. const TEMPLATES_PATH = 'config/dhcp/';
  36. public function __construct() {
  37. $this->loadMultinetNets();
  38. $this->loadDhcpNets();
  39. $this->initMessages();
  40. }
  41. /**
  42. * Loads existing DHCP subnets from database into protected property
  43. */
  44. protected function loadDhcpNets() {
  45. $query = "SELECT * from `dhcp` ORDER BY `id` ASC";
  46. $all = simple_queryall($query);
  47. if (!empty($all)) {
  48. foreach ($all as $io => $each) {
  49. $this->allDhcpNets[$each['id']] = $each;
  50. }
  51. }
  52. }
  53. /**
  54. * Loads all of multinet networks for further usage
  55. *
  56. * @return void
  57. */
  58. protected function loadMultinetNets() {
  59. $query = "SELECT * from `networks` ORDER BY `id` ASC";
  60. $all = simple_queryall($query);
  61. if (!empty($all)) {
  62. foreach ($all as $io => $each) {
  63. $this->allMultinetNets[$each['id']] = $each;
  64. }
  65. }
  66. }
  67. /**
  68. * Creates new instance of message helper
  69. *
  70. * @return void
  71. */
  72. protected function initMessages() {
  73. $this->messages = new UbillingMessageHelper();
  74. }
  75. /**
  76. * Renders list of available DHCP networks with some controls
  77. *
  78. * @return string
  79. */
  80. public function renderNetsList() {
  81. $result = '';
  82. $cells = wf_TableCell(__('ID'));
  83. $cells .= wf_TableCell(__('Network/CIDR'));
  84. $cells .= wf_TableCell(__('DHCP custom subnet template'));
  85. $cells .= wf_TableCell(__('DHCP config name'));
  86. $cells .= wf_TableCell(__('Actions'));
  87. $rows = wf_TableRow($cells, 'row1');
  88. if (!empty($this->allDhcpNets)) {
  89. foreach ($this->allDhcpNets as $io => $eachnet) {
  90. $rowClass = 'row5';
  91. if (isset($this->allMultinetNets[$eachnet['netid']])) {
  92. $cidr = $this->allMultinetNets[$eachnet['netid']]['desc'];
  93. } else {
  94. $cidr = __('Network does not exist anymore');
  95. }
  96. $cells = wf_TableCell($eachnet['id']);
  97. $cells .= wf_TableCell($cidr);
  98. $cells .= wf_TableCell(web_bool_led($eachnet['dhcpconfig']));
  99. $cells .= wf_TableCell($eachnet['confname']);
  100. $actLinks = wf_JSAlert('?module=dhcp&delete=' . $eachnet['id'], web_delete_icon(), 'Removing this may lead to irreparable results') . ' ';
  101. $actLinks .= wf_Link('?module=dhcp&edit=' . $eachnet['id'], web_edit_icon(), false);
  102. $cells .= wf_TableCell($actLinks);
  103. $rows .= wf_TableRow($cells, 'row5');
  104. }
  105. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  106. } else {
  107. $result = $this->messages->getStyledMessage(__('No available DHCP networks found'), 'info');
  108. }
  109. return ($result);
  110. }
  111. /**
  112. * Renders main module controls
  113. *
  114. * @return string
  115. */
  116. public function renderPanel() {
  117. $result = '';
  118. $result .= wf_modalAuto(wf_img('skins/add_icon.png') . ' ' . __('Add DHCP network'), __('Add DHCP network'), $this->addForm(), 'ubButton') . ' ';
  119. $result .= wf_Link('?module=dhcplog', wf_img('skins/log_icon_small.png') . ' ' . __('View log'), false, 'ubButton') . ' ';
  120. if (cfr('ROOT')) {
  121. $result .= wf_Link('?module=dhcpzen', wf_img('skins/zen.png') . ' ' . __('DHCP') . ' ' . __('Zen'), false, 'ubButton') . ' ';
  122. }
  123. $result .= wf_Link(self::URL_ME . '&restartserver=true', wf_img('skins/refresh.gif') . ' ' . __('Restart DHCP server'), false, 'ubButton');
  124. return ($result);
  125. }
  126. /**
  127. * Renders generated configs previews list
  128. *
  129. * @return string
  130. */
  131. public function renderConfigPreviews() {
  132. $result = '';
  133. if (!empty($this->allDhcpNets)) {
  134. $cells = wf_TableCell(__('ID'));
  135. $cells .= wf_TableCell(__('Network/CIDR'));
  136. $cells .= wf_TableCell(__('DHCP config name'));
  137. $cells .= wf_TableCell(__('Actions'));
  138. $rows = wf_TableRow($cells, 'row1');
  139. if (file_exists(self::MULTINET_PATH . 'dhcpd.conf')) {
  140. $dhcpdconf = str_replace("\n", '<br>', file_get_contents(self::MULTINET_PATH . 'dhcpd.conf'));
  141. } else {
  142. $dhcpdconf = $this->messages->getStyledMessage(__('File not found') . ': dhcpd.conf', 'error');
  143. }
  144. $actLinks = wf_Link(self::URL_ME . '&downloadconfig=dhcpd.conf', web_icon_download(), false) . ' ';
  145. $actLinks .= wf_modal(web_icon_search(__('Preview') . ' dhcpd.conf'), 'dhcpd.conf', $dhcpdconf, '', 800, 600);
  146. $cells = wf_TableCell('-');
  147. $cells .= wf_TableCell('-');
  148. $cells .= wf_TableCell('dhcpd.conf');
  149. $cells .= wf_TableCell($actLinks);
  150. $rows .= wf_TableRow($cells, 'row5');
  151. foreach ($this->allDhcpNets as $io => $eachnet) {
  152. $subconfname = trim($eachnet['confname']);
  153. if (file_exists(self::MULTINET_PATH . $subconfname)) {
  154. $subconfdata = str_replace("\n", '<br>', file_get_contents(self::MULTINET_PATH . $subconfname));
  155. } else {
  156. $subconfdata = $this->messages->getStyledMessage(__('File not found') . ': ' . $subconfname, 'error');
  157. }
  158. $actLinks = wf_Link(self::URL_ME . '&downloadconfig=' . $subconfname, web_icon_download(), false);
  159. $actLinks .= wf_modal(web_icon_search(__('Preview') . ' ' . $subconfname), $subconfname, $subconfdata, '', 800, 600);
  160. $cells = wf_TableCell($eachnet['id']);
  161. $netLabel = '';
  162. if (isset($this->allMultinetNets[$eachnet['netid']])) {
  163. $netLabel = $this->allMultinetNets[$eachnet['netid']]['desc'];
  164. } else {
  165. $netLabel = __('Network does not exist anymore');
  166. }
  167. $cells .= wf_TableCell($netLabel);
  168. $cells .= wf_TableCell($subconfname);
  169. $cells .= wf_TableCell($actLinks);
  170. $rows .= wf_TableRow($cells, 'row5');
  171. }
  172. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  173. } else {
  174. $result = $this->messages->getStyledMessage(__('No available DHCP configs found'), 'info');
  175. }
  176. return ($result);
  177. }
  178. /**
  179. * Returns json array of all available DHCP configs for remote deploy
  180. *
  181. * @return string
  182. */
  183. public function getConfigsRemote() {
  184. $result = array();
  185. if (!empty($this->allDhcpNets)) {
  186. if (file_exists(self::MULTINET_PATH . 'dhcpd.conf')) {
  187. $dhcpdconf = file_get_contents(self::MULTINET_PATH . 'dhcpd.conf');
  188. } else {
  189. $dhcpdconf = '#EX_DHCPDCONF_NOT_EXISTS';
  190. }
  191. //main config
  192. $result['dhcpd.conf']['content'] = $dhcpdconf;
  193. foreach ($this->allDhcpNets as $io => $eachnet) {
  194. $subconfname = trim($eachnet['confname']);
  195. if (file_exists(self::MULTINET_PATH . $subconfname)) {
  196. $subconfdata = file_get_contents(self::MULTINET_PATH . $subconfname);
  197. } else {
  198. $subconfdata = '#' . $subconfname . '_NOT_EXISTS';
  199. }
  200. $result[$subconfname]['content'] = $subconfdata;
  201. }
  202. }
  203. $result = json_encode($result);
  204. return($result);
  205. }
  206. /**
  207. * Downloads pregenerated DHCP config
  208. *
  209. * @param string $filename
  210. *
  211. * @return void
  212. */
  213. public function downloadConfig($filename) {
  214. $filename = vf($filename);
  215. if (file_exists(self::MULTINET_PATH . $filename)) {
  216. zb_DownloadFile(self::MULTINET_PATH . $filename, 'text');
  217. } else {
  218. show_error(__('File not found') . ': ' . $filename);
  219. }
  220. }
  221. /**
  222. * Downloads DHCP config template
  223. *
  224. * @param string $filename
  225. *
  226. * @return void
  227. */
  228. public function downloadTemplate($filename) {
  229. $filename = vf($filename);
  230. if (file_exists(self::TEMPLATES_PATH . $filename)) {
  231. zb_DownloadFile(self::TEMPLATES_PATH . $filename, 'text');
  232. } else {
  233. show_error(__('File not found') . ': ' . $filename);
  234. }
  235. }
  236. /**
  237. * Renders DHCP config templates previews
  238. *
  239. * @return string
  240. */
  241. public function renderConfigTemplates() {
  242. $allTemplates = rcms_scandir(self::TEMPLATES_PATH);
  243. $result = '';
  244. if (!empty($allTemplates)) {
  245. $cells = wf_TableCell(__('Filename'));
  246. $cells .= wf_TableCell(__('Actions'));
  247. $rows = wf_TableRow($cells, 'row1');
  248. foreach ($allTemplates as $eachfilename) {
  249. $templateData = file_get_contents(self::TEMPLATES_PATH . $eachfilename);
  250. $templateData = nl2br($templateData);
  251. $actLinks = wf_Link(self::URL_ME . '&downloadtemplate=' . $eachfilename, web_icon_download(), false) . ' ';
  252. $actLinks .= wf_modal(web_icon_search(__('Preview') . ' ' . $eachfilename), $eachfilename, $templateData, '', 800, 600) . ' ';
  253. $cells = wf_TableCell($eachfilename);
  254. $cells .= wf_TableCell(__($actLinks));
  255. $rows .= wf_TableRow($cells, 'row5');
  256. }
  257. $result = wf_TableBody($rows, '100%', 0, 'sortable');
  258. } else {
  259. $result = $this->messages->getStyledMessage(__('Nothing found'), 'warning');
  260. }
  261. return ($result);
  262. }
  263. /**
  264. * Checks is multinet netid used for one of DHCP nets or not
  265. *
  266. * @param int $netId
  267. *
  268. * @return bool
  269. */
  270. protected function isNetUnused($netId) {
  271. $result = true;
  272. if (!empty($this->allDhcpNets)) {
  273. foreach ($this->allDhcpNets as $io => $each) {
  274. if ($each['netid'] == $netId) {
  275. $result = false;
  276. break;
  277. }
  278. }
  279. }
  280. return ($result);
  281. }
  282. /**
  283. * Checks is config name unused?
  284. *
  285. * @param string $filename
  286. *
  287. * @return bool
  288. */
  289. public function isConfigNameFree($filename) {
  290. $result = true;
  291. $filename = vf($filename);
  292. $filename = trim($filename);
  293. if (!empty($this->allDhcpNets)) {
  294. foreach ($this->allDhcpNets as $io => $each) {
  295. if ($each['confname'] == $filename) {
  296. $result = false;
  297. break;
  298. }
  299. }
  300. }
  301. return ($result);
  302. }
  303. /**
  304. * Renders network selector with not set DHCP handlers
  305. *
  306. * @return string
  307. */
  308. protected function networkSelector() {
  309. $tmpArr = array();
  310. $result = '';
  311. /**
  312. * V čůráckým vobdobí, kdy mě serou fronty,
  313. * sem na pokraji sil, už nepomáhaj jointy.
  314. * Rodinu nemám, večeřim sám, žeru šproty,
  315. * Vánoce zmrdem na Štědrej den do rachoty.
  316. */
  317. if (!empty($this->allMultinetNets)) {
  318. foreach ($this->allMultinetNets as $io => $each) {
  319. if ($this->isNetUnused($each['id'])) {
  320. $tmpArr[$each['id']] = $each['desc'];
  321. }
  322. }
  323. if (!empty($tmpArr)) {
  324. $result = wf_Selector('networkselect', $tmpArr, __('Network'), '', true);
  325. }
  326. }
  327. return ($result);
  328. }
  329. /**
  330. * Returns DHCP network data by its id
  331. *
  332. * @param int $dhcpid
  333. *
  334. * @return array
  335. */
  336. public function getNetworkData($dhcpid) {
  337. $result = array();
  338. if (isset($this->allDhcpNets)) {
  339. $result = $this->allDhcpNets[$dhcpid];
  340. }
  341. return($result);
  342. }
  343. /**
  344. * Returns DHCP network addition form
  345. *
  346. * @return string
  347. */
  348. public function addForm() {
  349. $result = '';
  350. //any multinet nets available
  351. if (!empty($this->allMultinetNets)) {
  352. $networkSelector = $this->networkSelector();
  353. //some of it have no DHCP handlers
  354. if (!empty($networkSelector)) {
  355. $inputs = $networkSelector;
  356. $inputs .= wf_HiddenInput('adddhcp', 'true');
  357. $inputs .= wf_TextInput('dhcpconfname', __('DHCP config name'), '', true, '20');
  358. $inputs .= wf_Submit(__('Create'));
  359. $result = wf_Form('', 'POST', $inputs, 'glamour');
  360. } else {
  361. $result = $this->messages->getStyledMessage(__('All networks already has DHCP configured'), 'info');
  362. }
  363. } else {
  364. $result = $this->messages->getStyledMessage(__('No networks for DHCP setup available'), 'error');
  365. }
  366. return ($result);
  367. }
  368. /**
  369. * Renders network template editing form
  370. *
  371. * @param int $dhcpid
  372. *
  373. * @return string
  374. */
  375. public function editForm($dhcpid) {
  376. $dhcpid = vf($dhcpid, 3);
  377. $result = '';
  378. if (isset($this->allDhcpNets[$dhcpid])) {
  379. $dhcpnetdata = $this->getNetworkData($dhcpid);
  380. $inputs = wf_TextInput('editdhcpconfname', __('DHCP config name'), $dhcpnetdata['confname'], true, 20);
  381. $inputs .= __('DHCP custom subnet template') . wf_tag('br');
  382. $inputs .= wf_TextArea('editdhcpconfig', '', $dhcpnetdata['dhcpconfig'], true, '60x10');
  383. $inputs .= wf_Submit(__('Save'));
  384. $result = wf_Form('', 'POST', $inputs, 'glamour');
  385. $result .= wf_CleanDiv();
  386. $result .= wf_BackLink(self::URL_ME);
  387. } else {
  388. $result = $this->messages->getStyledMessage(__('Something went wrong'), 'errors');
  389. }
  390. return ($result);
  391. }
  392. /**
  393. * Creates new DHCP network
  394. *
  395. * @param int $netid
  396. * @param string $dhcpconfname
  397. *
  398. * @return void
  399. */
  400. public function createNetwork($netid, $dhcpconfname) {
  401. $netid = vf($netid, 3);
  402. $dhcpconfname = vf($dhcpconfname);
  403. $dhcpconfname = trim($dhcpconfname);
  404. $query = "INSERT INTO `dhcp` (`id` ,`netid` , `dhcpconfig` , `confname`)
  405. VALUES (NULL , '" . $netid . "', '', '" . $dhcpconfname . "');";
  406. nr_query($query);
  407. $newID = simple_get_lastid('dhcp');
  408. log_register('CREATE DHCPNet [' . $newID . '] NETWORK [' . $netid . ']');
  409. }
  410. /**
  411. * Updates existing DHCP network handler
  412. *
  413. * @param int $dhcpid
  414. * @param string $dhcpconfname
  415. * @param string $dhcpconfig
  416. *
  417. * @return void
  418. */
  419. public function updateNetwork($dhcpid, $dhcpconfname, $dhcpconfig) {
  420. $dhcpid = vf($dhcpid, 3);
  421. $dhcpconfname = vf($dhcpconfname);
  422. $dhcpconfname = trim($dhcpconfname);
  423. $dhcpconfig = mysql_real_escape_string($dhcpconfig);
  424. $query = "UPDATE `dhcp` SET `dhcpconfig` = '" . $dhcpconfig . "',"
  425. . "`confname` = '" . $dhcpconfname . "' WHERE `id` ='" . $dhcpid . "';";
  426. nr_query($query);
  427. log_register('CHANGE DHCPNet [' . $dhcpid . ']');
  428. }
  429. /**
  430. * Deletes existing DHCP network
  431. *
  432. * @param int $dhcpid
  433. *
  434. * @return void
  435. */
  436. public function deleteNetwork($dhcpid) {
  437. $dhcpid = vf($dhcpid, 3);
  438. $query = "DELETE from `dhcp` WHERE `id`='" . $dhcpid . "'";
  439. nr_query($query);
  440. log_register('DELETE DHCPNet [' . $dhcpid . ']');
  441. }
  442. /**
  443. * Rebuilds all configs and restarts DHCP server
  444. *
  445. * @return void
  446. */
  447. public function restartDhcpServer() {
  448. multinet_rebuild_all_handlers();
  449. }
  450. }
  451. ?>