index.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <?php
  2. if (cfr('SWITCHESEDIT')) {
  3. class SwitchScan {
  4. /**
  5. * Contains all available switches data
  6. *
  7. * @var array
  8. */
  9. protected $allSwitchesData = array();
  10. /**
  11. * Contains all available switches IPs as ip=>id
  12. *
  13. * @var array
  14. */
  15. protected $allSwitchesIp = array();
  16. /**
  17. * Array for IPs scanning
  18. *
  19. * @var array
  20. */
  21. protected $scanIps = array();
  22. /**
  23. * Contains array of available network CIDR masks
  24. *
  25. * @var array
  26. */
  27. protected $availMasks = array();
  28. /**
  29. * System messages helper placeholder
  30. *
  31. * @var object
  32. */
  33. protected $messages = '';
  34. /**
  35. * Creates new switch scan instance
  36. *
  37. * @return void
  38. */
  39. public function __construct() {
  40. $this->availMasks = array(29 => 29, 28 => 28, 27 => 27, 26 => 26, 25 => 25, 24 => 24, 23 => 23, 22 => 22, 21 => 21, 20 => 20, 19 => 19, 18 => 18);
  41. $this->initMessages();
  42. $this->loadSwitches();
  43. }
  44. /**
  45. * Initializes message helper object for further usage
  46. *
  47. * @return void
  48. */
  49. protected function initMessages() {
  50. $this->messages = new UbillingMessageHelper();
  51. }
  52. /**
  53. * Loads available switches from database and do some preprocessing
  54. *
  55. * @return void
  56. */
  57. protected function loadSwitches() {
  58. $tmp = zb_SwitchesGetAll();
  59. if (!empty($tmp)) {
  60. foreach ($tmp as $io => $each) {
  61. $this->allSwitchesData[$each['id']] = $each;
  62. if (!empty($each['ip'])) {
  63. $this->allSwitchesIp[$each['ip']] = $each['id'];
  64. }
  65. }
  66. }
  67. }
  68. /**
  69. * Renders search form
  70. *
  71. * @return string
  72. */
  73. public function renderForm() {
  74. $result = '';
  75. /**
  76. * Am C
  77. * Я знав тебе пацанкою малою
  78. * Em D
  79. * І ноль вніманія на тебе обращав
  80. * А як прийшов із армії додому
  81. * Тебе побачив і на дупу впав
  82. */
  83. $curNet = (ubRouting::checkPost('searchnetdevs')) ? ubRouting::post('searchnetdevs') : '';
  84. $curCidr = (ubRouting::checkPost('searchnetcidr')) ? ubRouting::post('searchnetcidr', 'int') : 21;
  85. $inputs = wf_TextInput('searchnetdevs', __('Network') . ' /', $curNet, false, 20);
  86. $inputs .= wf_Selector('searchnetcidr', $this->availMasks, __('CIDR'), $curCidr, false);
  87. $inputs .= wf_Submit(__('Search'));
  88. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  89. return ($result);
  90. }
  91. /**
  92. * Renders search form
  93. *
  94. * @return string
  95. */
  96. public function renderFormFree() {
  97. $result = '';
  98. $curNet = (ubRouting::checkPost('freenetdevs')) ? ubRouting::post('freenetdevs') : '';
  99. $curCidr = (ubRouting::checkPost('freecidr')) ? ubRouting::post('freenetcidr', 'int') : 21;
  100. $inputs = wf_TextInput('freenetdevs', __('Network') . ' /', $curNet, false, 20);
  101. $inputs .= wf_Selector('freenetcidr', $this->availMasks, __('CIDR'), $curCidr, false);
  102. $inputs .= wf_Submit(__('Show'));
  103. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  104. return ($result);
  105. }
  106. /**
  107. * Renders search form
  108. *
  109. * @return string
  110. */
  111. public function renderFormNP() {
  112. $result = '';
  113. $curNet = (ubRouting::checkPost('alivenpdevs')) ? ubRouting::post('alivenpdevs') : '';
  114. $curCidr = (ubRouting::checkPost('alivenpcidr')) ? ubRouting::post('alivenpcidr', 'int') : 21;
  115. $inputs = wf_TextInput('alivenpdevs', __('Network') . ' /', $curNet, false, 20);
  116. $inputs .= wf_Selector('alivenpcidr', $this->availMasks, __('CIDR'), $curCidr, false);
  117. $inputs .= wf_Submit(__('Show'));
  118. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  119. return ($result);
  120. }
  121. /**
  122. * Returns first/last IPs from some network
  123. *
  124. * @param string $cidr
  125. *
  126. * @return array
  127. */
  128. protected function getIpRange($cidr) {
  129. list($ip, $mask) = explode('/', $cidr);
  130. $maskBinStr = str_repeat("1", $mask) . str_repeat("0", 32 - $mask); //net mask binary string
  131. $inverseMaskBinStr = str_repeat("0", $mask) . str_repeat("1", 32 - $mask); //inverse mask
  132. $ipLong = ip2int($ip);
  133. $ipMaskLong = bindec($maskBinStr);
  134. $inverseIpMaskLong = bindec($inverseMaskBinStr);
  135. $netWork = $ipLong & $ipMaskLong;
  136. $start = $netWork + 1; //ignore network ID(eg: 192.168.1.0)
  137. $end = ($netWork | $inverseIpMaskLong) - 1; //ignore brocast IP(eg: 192.168.1.255)
  138. return array('firstIP' => $start, 'lastIP' => $end);
  139. }
  140. /**
  141. * Returns array of some IPs in network range as index=>ip
  142. *
  143. * @param string $cidr
  144. *
  145. * @return array
  146. */
  147. protected function getEachIpInRange($cidr) {
  148. $ips = array();
  149. $range = $this->getIpRange($cidr);
  150. for ($ip = $range['firstIP']; $ip <= $range['lastIP']; $ip++) {
  151. $ips[] = int2ip($ip);
  152. }
  153. return $ips;
  154. }
  155. /**
  156. * Preprocesses network range for further actions
  157. *
  158. * @param string $network
  159. * @param int $cidr
  160. *
  161. * @return void/string on error
  162. */
  163. public function extractIpData($network, $cidr) {
  164. $result = '';
  165. $networkCidr = $network . '/' . $cidr;
  166. if (!empty($networkCidr)) {
  167. if ((ispos($networkCidr, '/')) AND ( filter_var($network, FILTER_VALIDATE_IP))) {
  168. $this->scanIps = $this->getEachIpInRange($networkCidr);
  169. } else {
  170. $result = __('Wrong network format');
  171. }
  172. } else {
  173. $result = __('Wrong network format');
  174. }
  175. return ($result);
  176. }
  177. /**
  178. * Perform search of unregistered devices
  179. *
  180. * @return string
  181. */
  182. public function searchDevices() {
  183. $result = '';
  184. if (!empty($this->scanIps)) {
  185. foreach ($this->scanIps as $io => $eachIp) {
  186. if (!isset($this->allSwitchesIp[$eachIp])) {
  187. if (zb_PingICMP($eachIp)) {
  188. $result .= $this->messages->getStyledMessage(__('Unknown device') . ' ' . $eachIp, 'error');
  189. }
  190. }
  191. }
  192. }
  193. if (empty($result)) {
  194. $result .= $this->messages->getStyledMessage(__('Nothing found'), 'success');
  195. }
  196. return ($result);
  197. }
  198. /**
  199. * Perform search of online registered NP devices
  200. *
  201. * @return string
  202. */
  203. public function searchNPDevices() {
  204. $result = '';
  205. if (!empty($this->scanIps)) {
  206. foreach ($this->scanIps as $io => $eachIp) {
  207. if (isset($this->allSwitchesIp[$eachIp])) {
  208. $switchId = $this->allSwitchesIp[$eachIp];
  209. $switchData = $this->allSwitchesData[$this->allSwitchesIp[$eachIp]];
  210. $switchDesc = $switchData['desc'];
  211. $switchLocation = $switchData['location'];
  212. if (ispos($switchDesc, 'NP')) {
  213. if (zb_PingICMP($eachIp)) {
  214. $switchLink = wf_Link('?module=switches&edit=' . $switchId, '[' . $switchId . ']');
  215. $result .= $this->messages->getStyledMessage(__('Alive') . ' ' . $switchLink . ' ' . $eachIp . ' - ' . $switchLocation, 'warning');
  216. }
  217. }
  218. }
  219. }
  220. }
  221. if (empty($result)) {
  222. $result .= $this->messages->getStyledMessage(__('Nothing found'), 'success');
  223. }
  224. return ($result);
  225. }
  226. /**
  227. * Returns list of free IPs not used in some network by switch devicess
  228. *
  229. * @return string
  230. */
  231. public function lookupFreeIPs() {
  232. $result = '';
  233. $tmpArr = array();
  234. $count = 0;
  235. if (!empty($this->scanIps)) {
  236. foreach ($this->scanIps as $io => $eachIp) {
  237. if (!isset($this->allSwitchesIp[$eachIp])) {
  238. $tmpArr[] = $eachIp;
  239. }
  240. }
  241. }
  242. if (!empty($tmpArr)) {
  243. $cells = wf_TableCell(__('IP'));
  244. $rows = wf_TableRow($cells, 'row1');
  245. foreach ($tmpArr as $io => $each) {
  246. //ignoring some broadcasts and network addrs
  247. if (!preg_match("#\.(0|1|255)$#", $each)) {
  248. $cells = wf_TableCell($each, '', '', 'sorttable_customkey="' . ip2int($each) . '"');
  249. $rows .= wf_TableRow($cells, 'row5');
  250. $count++;
  251. }
  252. }
  253. $result .= wf_TableBody($rows, '100%', 0, 'sortable');
  254. $result .= __('Total') . ':' . $count;
  255. } else {
  256. $result .= $this->messages->getStyledMessage(__('Nothing found'), 'warning');
  257. }
  258. return ($result);
  259. }
  260. /**
  261. * Renders switches with duplicated IP addresses
  262. *
  263. * @return string
  264. */
  265. public function renderSwitchIpDuplicates() {
  266. $result = '';
  267. $tmp = array();
  268. $dupIpCount = 0;
  269. if (!empty($this->allSwitchesData)) {
  270. foreach ($this->allSwitchesData as $switchId => $switchData) {
  271. if (!empty($switchData['ip'])) {
  272. $tmp[$switchData['ip']][] = $switchData;
  273. }
  274. }
  275. foreach ($tmp as $switchIp => $switchesOn) {
  276. if (sizeof($switchesOn) > 1) {
  277. foreach ($switchesOn as $index => $swDupData) {
  278. $swLabel = wf_Link('?module=switches&edit=' . $swDupData['id'], '[' . $swDupData['id'] . ']') . ' ' . $swDupData['location'];
  279. $result .= $this->messages->getStyledMessage(__('IP') . ': ' . $switchIp . ' ' . $swLabel, 'warning');
  280. $dupIpCount++;
  281. }
  282. }
  283. }
  284. }
  285. if (!$dupIpCount) {
  286. $result .= $this->messages->getStyledMessage(__('Nothing found'), 'success');
  287. }
  288. return($result);
  289. }
  290. }
  291. $scan = new SwitchScan();
  292. //rendering of some interface
  293. show_window('', wf_BackLink('?module=switches'));
  294. show_window(__('Scan for unknown devices'), $scan->renderForm());
  295. show_window(__('Scan for free IPs'), $scan->renderFormFree());
  296. show_window(__('Scan for online NP devices'), $scan->renderFormNP());
  297. show_window(__('Duplicate') . ' ' . __('IP'), $scan->renderSwitchIpDuplicates());
  298. //searching for unknown devices
  299. if (ubRouting::checkPost(array('searchnetdevs', 'searchnetcidr'))) {
  300. $extractResult = $scan->extractIpData(ubRouting::post('searchnetdevs'), ubRouting::post('searchnetcidr'));
  301. if (empty($extractResult)) {
  302. show_window(__('Search results'), $scan->searchDevices());
  303. } else {
  304. show_error($extractResult);
  305. }
  306. }
  307. //looking for some freee IPs
  308. if (ubRouting::checkPost(array('freenetdevs', 'freenetcidr'))) {
  309. $extractResult = $scan->extractIpData(ubRouting::post('freenetdevs'), ubRouting::post('freenetcidr'));
  310. if (empty($extractResult)) {
  311. show_window(__('Free IPs'), $scan->lookupFreeIPs());
  312. } else {
  313. show_error($extractResult);
  314. }
  315. }
  316. //looking for online NP devices
  317. if (ubRouting::checkPost(array('alivenpdevs', 'alivenpcidr'))) {
  318. $extractResult = $scan->extractIpData(ubRouting::post('alivenpdevs'), ubRouting::post('alivenpcidr'));
  319. if (empty($extractResult)) {
  320. show_window(__('Search results'), $scan->searchNPDevices());
  321. } else {
  322. show_error($extractResult);
  323. }
  324. }
  325. } else {
  326. show_error(__('Access denied'));
  327. }