add_port_profile.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <?php
  2. #-
  3. # Copyright (c) 2011-2015 Joe Clarke <jclarke@cisco.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. # SUCH DAMAGE.
  26. #
  27. #
  28. include_once 'db.inc.php';
  29. include_once 'swreg/swreg.inc.php';
  30. include_once 'swreg_web.inc.php';
  31. require_once 'MDB2.php';
  32. require_once 'Log.php';
  33. require_once 'functions.php';
  34. $dsn = "mysql://$db_user:$db_pass@$db_host/$db_name";
  35. $options = array('result_buffering', false);
  36. $dbh = MDB2::factory($dsn, $options);
  37. if (PEAR::isError($dbh)) {
  38. die($dbh->getMessage());
  39. }
  40. $dbh->setFetchMode(MDB2_FETCHMODE_ASSOC);
  41. $logger = Log::singleton('file', LOGFILE, TOOL_NAME . ' : Add Port Profile');
  42. if ($logger === FALSE) {
  43. die("Failed to open logfile.\n");
  44. }
  45. $mask = Log::UPTO(LOG_LEVEL);
  46. $logger->setMask($mask);
  47. $base = get_base($_SERVER['SCRIPT_NAME']);
  48. $errors = array();
  49. if (isset($_REQUEST['submit'])) {
  50. $pname = $_REQUEST['pname'];
  51. $pid = $_REQUEST['pid'];
  52. $vlans = $_REQUEST['vlan'];
  53. $start_ports = $_REQUEST['start_port'];
  54. $end_ports = $_REQUEST['end_port'];
  55. if (!isset($pname) || !isset($pid) || $pname == "") {
  56. array_push($errors, "You must specify a profile name and PID");
  57. } else {
  58. $profile = '';
  59. $seen_sports = array();
  60. $seen_eports = array();
  61. $max_port = 0;
  62. for ($i = 0; $i < count($start_ports); $i++) {
  63. $vlan = $vlans[$i];
  64. $start_port = $start_ports[$i];
  65. $end_port = $end_ports[$i];
  66. $row = $i + 1;
  67. if ($vlan == '__BOGUS__') {
  68. continue;
  69. }
  70. if ($start_port == '__BOGUS__' || $end_port == '__BOGUS__') {
  71. array_push($errors, "You must select a starting and ending port at row $row");
  72. continue;
  73. }
  74. if ($pid != "__ANY__") {
  75. preg_match("/\/(\d+)$/", $start_port, $sm);
  76. if ($sm[1] > $end_port) {
  77. array_push($errors, "Starting port must be less than equal to the ending port at row $row");
  78. continue;
  79. }
  80. } else if ($vlan == "DYNAMIC") {
  81. array_push($errors, "In order to make ports dynamic, you must choose an explicit PID at row $row");
  82. continue;
  83. }
  84. if (isset($seen_sports[$start_port])) {
  85. array_push($errors, "Starting port $start_port was already used at row {$seen_sports[$start_port]}");
  86. continue;
  87. }
  88. $seen_sports[$start_port] = $row;
  89. if (isset($seen_eports[$end_port])) {
  90. array_push($errors, "Ending port $end_port was already used at row {$seen_eports[$end_port]}");
  91. continue;
  92. }
  93. $seen_eports[$end_port] = $row;
  94. $profile .= generate_port_profile($start_port, $end_port, $vlan, $pid);
  95. $profile .= "!\n";
  96. if ($pid != "__ANY__" && $end_port > $max_port) {
  97. $max_port = $end_port;
  98. }
  99. }
  100. if ($profile == '') {
  101. array_push($errors, "No profile ranges specified");
  102. }
  103. if (!preg_match("/^[\w\d\-_]+$/", $pname)) {
  104. array_push($errors, "Profile name can only contain letters, numbers, hyphens, and underscores");
  105. }
  106. if ($pid != "__ANY__") {
  107. $ports = 8;
  108. foreach ($PID_PORTS as $pp => $np) {
  109. if ($pid == $pp) {
  110. $ports = $np;
  111. break;
  112. }
  113. }
  114. if ($max_port != $ports) {
  115. array_push($errors, "All ports must be specified for a port profile");
  116. }
  117. }
  118. }
  119. if (count($errors) == 0) {
  120. $fd = fopen(PORT_PROFILE_DIR . "/{$pname}.tmpl", "w");
  121. fwrite($fd, $profile);
  122. fclose($fd);
  123. $sql = "INSERT INTO EXCEPTIONS VALUES (?, ?, ?)";
  124. $sth = $dbh->prepare($sql);
  125. if (PEAR::isError($sth)) {
  126. array_push($errors, "Failed to prepare query $sql: {$sth->getUserInfo()}");
  127. } else {
  128. if (isset($PID_MAP[$pid])) {
  129. $pid = $PID_MAP[$pid];
  130. }
  131. $res = $sth->execute(array($pname, $pid, "{$pname}.tmpl"));
  132. if (PEAR::isError($res)) {
  133. array_push($errors, "Failed to execute query $sql: {$res->getUserInfo()}");
  134. } else {
  135. $logger->info("User {$_SERVER['REMOTE_USER']} add port profile: name={$pname}, pid={$pid}, path={$pname}.tmpl");
  136. }
  137. }
  138. cleanup();
  139. if (count($errors) == 0) {
  140. header("Location: $base/port_profiles.php");
  141. exit;
  142. }
  143. }
  144. }
  145. $nports = array_values($PID_PORTS);
  146. rsort($nports);
  147. $mport = $nports[0];
  148. print_header(TOOL_NAME . ": Add Port Profile");
  149. ?>
  150. <script language="Javascript">
  151. var lastStart = 1;
  152. var PID_PORTS = [];
  153. var PORT_PATTERNS = [];
  154. <?php
  155. foreach ($PID_PORTS as $pp => $np) {
  156. ?>
  157. PID_PORTS["<?=$pp?>"] = <?=$np?>;
  158. <?php
  159. }
  160. foreach ($PORT_PATTERNS as $p => $pa) {
  161. ?>
  162. PORT_PATTERNS["<?=$p?>"] = "<?=$pa?>";
  163. <?php
  164. }
  165. ?>
  166. function setLastStart(port, increment) {
  167. var regex = /([0-9]+)$/;
  168. try {
  169. var matches = regex.exec(port);
  170. lastStart = matches[1];
  171. if (increment) {
  172. lastStart++;
  173. }
  174. } catch (err) { }
  175. }
  176. function purgePorts() {
  177. for (var i = 0; i < <?=$mport?>; i++) {
  178. var sSelect = document.getElementById("start_port[" + i + "]");
  179. var eSelect = document.getElementById("end_port[" + i + "]");
  180. deleteOptions(sSelect);
  181. deleteOptions(eSelect);
  182. createOption(sSelect, '--Please Select--', '__BOGUS__');
  183. createOption(eSelect, '--Please Select--', '__BOGUS__');
  184. }
  185. }
  186. function updatePorts(pid, sidx, eidx, send, eend) {
  187. if (typeof send === undefined) {
  188. send = <?=$mport?>;
  189. }
  190. if (typeof eend === undefined) {
  191. eend = <?=$mport?>;
  192. }
  193. for (var i = sidx; i < send; i++) {
  194. var sSelect = document.getElementById("start_port[" + i + "]");
  195. if (pid == "__ANY__") {
  196. createOption(sSelect, 'First Switch Port', '%%START_PORT%%');
  197. } else {
  198. endp = PID_PORTS[pid] + 1;
  199. ppat = PORT_PATTERNS[pid];
  200. for (var j = lastStart; j < endp; j++) {
  201. createOption(sSelect, ppat+j, ppat+j);
  202. }
  203. }
  204. }
  205. for (var i = eidx; i < eend; i++) {
  206. var eSelect = document.getElementById("end_port[" + i + "]");
  207. if (pid == "__ANY__") {
  208. createOption(eSelect, 'Last Switch Port', '%%MAX_PORT%%');
  209. } else {
  210. endp = PID_PORTS[pid] + 1;
  211. for (var j = lastStart; j < endp; j++) {
  212. createOption(eSelect, j, j);
  213. }
  214. }
  215. }
  216. }
  217. </script>
  218. <body class="flex" onLoad='purgePorts(); updatePorts("__ANY__", 0, 0, 1, 0); return true;'>
  219. <div id="headswreg">
  220. <div id="header">
  221. <h1><?=TOOL_NAME?>: Add Port Profile</h1>
  222. </div>
  223. <br/>
  224. </div>
  225. <div class="apage">
  226. <form name="port_profile_add_form" method="POST" action="<?=$_SERVER['PHP_SELF']?>">
  227. <table class="noborder" summary="Profile Options">
  228. <tr>
  229. <td class="left_act">Profile Name:
  230. <input type="text" name="pname" size="16">
  231. </td>
  232. <td>Select PID:
  233. <select name="pid" id="pid" onChange='purgePorts(); updatePorts(this.options[this.selectedIndex].value, 0, 0, 1, 0); return true;'>
  234. <option value="__ANY__" selected>Any</option>
  235. <?php
  236. foreach ($PID_PORTS as $p => $n) {
  237. ?>
  238. <option value="<?=$p?>"><?=$p?></option>
  239. <?php
  240. }
  241. ?>
  242. </select></td>
  243. </tr>
  244. </table>
  245. </div>
  246. <div id="page">
  247. <div id="itemhead">
  248. <h2 class="tabeltitle">Port Profile</h2>
  249. </div>
  250. <div align="center">
  251. <?php
  252. foreach ($errors as $error) {
  253. ?>
  254. <p class="error"><?=$error?></p>
  255. <?php
  256. }
  257. ?>
  258. </div>
  259. <table class="full" summary="New Port Profile Table">
  260. <tr>
  261. <th>Row No.</th>
  262. <th>Starting Port</th>
  263. <th>Ending Port</th>
  264. <th>VLAN</th>
  265. </tr>
  266. <?php
  267. for ($i = 0; $i < $mport; $i++) {
  268. ?>
  269. <tr <?=get_row_color($i)?>>
  270. <td><?=$i + 1?>.</td>
  271. <td><select name="start_port[<?=$i?>]" id="start_port[<?=$i?>]" onChange='setLastStart(this.options[this.selectedIndex].value, false); pSelect = document.getElementById("pid"); updatePorts(pSelect.options[pSelect.selectedIndex].value, <?=$i+1?>, <?=$i?>, <?=$i+1?>, <?=$i+1?>); return true;'>
  272. </select></td>
  273. <td><select name="end_port[<?=$i?>]" id="end_port[<?=$i?>]" onChange='setLastStart(this.options[this.selectedIndex].value, true); pSelect = document.getElementById("pid"); updatePorts(pSelect.options[pSelect.selectedIndex].value, <?=$i+1?>, <?=$i+1?>, <?=$i+2?>, <?=$i+1?>); return true;'>
  274. </select></td>
  275. <td><select name="vlan[<?=$i?>]">
  276. <option value="__BOGUS__" selected>--Please Select--</option>
  277. <option value="DYNAMIC">DYNAMIC</option>
  278. <option value="TRUNK">TRUNK</option>
  279. <option value="UPLINK TRUNK">UPLINK TRUNK</option>
  280. <option disabled>&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;</option>
  281. <?php
  282. ksort($VLANS);
  283. foreach ($VLANS as $vn => $vi) {
  284. ?>
  285. <option value="<?=$vn?>"><?=$vn?></option>
  286. <?php
  287. }
  288. ?>
  289. </select></td>
  290. </tr>
  291. <?php
  292. }
  293. ?>
  294. </table>
  295. <br/>
  296. <div align="center">
  297. <input type="reset" name="reset" value="Reset">
  298. <input type="submit" name="preview" value="Preview" onClick='this.form.action="<?=$base?>/profile_preview.php"; this.form.target="_blank";'>
  299. <input type="submit" name="submit" value="Add" onClick='this.form.action="<?=$_SERVER['PHP_SELF']?>"; this.form.target="_self";'>
  300. </div>
  301. </form>
  302. <table class="noborder" summary="Return Table">
  303. <tr>
  304. <td class="left_act">
  305. <a href="<?=$base?>/port_profiles.php">&lt;&lt;&lt;Return to Main Page</a>
  306. </td>
  307. </tr>
  308. </table>
  309. </div>
  310. </body>
  311. </html>
  312. <?php
  313. cleanup();
  314. ?>