Пример #1
0
 /**
  * Recursivily crawls all CDP neighbours to build up a flat array of all devices
  * indexed by the CDP device id.
  *
  * Array form is same as that returned by neighbours()
  *
  * @see neighbours()
  * @param array $devices Unless you're doing something funky, just pass an empty array. This is where the result will be found.
  * @param string $device CDP device ID of next host to crawl. On first pass, set to null - used internally when recursing
  * @param array $ignore An array of CDP device IDs to *ignore*. I.e. to not include in recursive crawling
  * @return array The resultant array of all crawled devices (same as that passed in the @param $devices parameter)
  */
 public function crawl(&$devices = array(), $device = null, $ignore = array())
 {
     if (!count($devices)) {
         $device = $this->id();
         $devices[$device] = $this->neighbours(true, $ignore);
     }
     foreach ($devices[$device] as $feNeighbour => $feConnections) {
         if (in_array($feNeighbour, $ignore)) {
             if (isset($devices[$device][$feNeighbour])) {
                 unset($devices[$device][$feNeighbour]);
             }
             continue;
         }
         if (!isset($devices[$feNeighbour])) {
             $snmp = new \OSS_SNMP\SNMP($feNeighbour, $this->getSNMP()->getCommunity());
             try {
                 $devices[$feNeighbour] = $snmp->useCisco_CDP()->neighbours(true, $ignore);
                 unset($snmp);
                 $this->crawl($devices, $feNeighbour, $ignore);
             } catch (\OSS_SNMP\Exception $e) {
                 // this device did not respond / have CDP enabled / CDP available - skip
                 unset($devices[$feNeighbour]);
             }
         }
     }
     return $devices;
 }
Пример #2
0
 /**
  * Similar to L2 Topology above but this takes a specific VLAN / instance and identifies and graphs Per-VLAN/instance Spanning Tree port roles.
  *
  * @see https://github.com/opensolutions/NOCtools/wiki/CDP-RSTP-Port-Roles
  */
 public function stpTopologyAction()
 {
     $this->view->cdp_root = $host = $this->getParam('cdp_root', '');
     $this->view->type = $type = $this->getParam('type', 'rstp');
     $this->view->instance = $instance = $this->getParam('instance', false);
     $this->view->excludeNonParticipants = true;
     $this->view->showPortRoles = true;
     $this->view->ignoreList = implode("\n", $this->_getIgnoreList());
     if (strlen($host)) {
         $root = new \OSS_SNMP\SNMP($host, $this->_options['community']);
         if ($type == 'mst') {
             $this->view->instances = $instances = $root->useCisco_SMST()->instances();
         } else {
             $this->view->instances = $instances = $root->useCisco_VTP()->vlanNames();
         }
     }
     if ($this->getRequest()->isPost()) {
         do {
             if ($instance !== false && $this->getParam('excludeNonParticipants', null) === null) {
                 $this->view->excludeNonParticipants = $excludeNonParticipants = false;
             }
             if ($instance !== false && $this->getParam('showPortRoles', null) === null) {
                 $this->view->showPortRoles = $showPortRoles = false;
             }
             $this->view->ignoreList = isset($this->view->ignoreList) ? $this->view->ignoreList : $this->getParam('ignoreList');
             $ignoreList = array();
             foreach (explode("\n", $this->getParam('ignoreList')) as $i) {
                 $ignoreList[] = trim($i);
             }
             if (!strlen($host)) {
                 $this->addMessage('You must select a device as the root for CDP neighbour discovery and a VLAN / instance', OSS_Message::ERROR);
                 break;
             }
             if ($instance === false) {
                 break;
             }
             $devices = array();
             $root->useCisco_CDP()->crawl($devices, null, $ignoreList);
             // we're not splitting LAGs, we need to sanitise the links
             $devices = $root->useCisco_CDP()->collapseDevicesLAGs($devices);
             // now, find the links which are participating in RSTP / MST and their roles
             $portRoles = [];
             foreach ($devices as $aDevice => $neighbours) {
                 if (!isset($portRoles[$aDevice])) {
                     $portRoles[$aDevice] = $this->_stpTopologyPortRoles($aDevice, $type, $instance);
                 }
                 foreach ($neighbours as $bDevice => $ports) {
                     if (!isset($portRoles[$bDevice])) {
                         $portRoles[$bDevice] = $this->_stpTopologyPortRoles($bDevice, $type, $instance);
                     }
                 }
             }
             foreach ($devices as $aDevice => $neighbours) {
                 foreach ($neighbours as $bDevice => $ports) {
                     foreach ($ports as $idx => $portDetails) {
                         if (isset($portRoles[$aDevice][$portDetails['localPortId']]) && isset($portRoles[$bDevice][$portDetails['remotePortId']])) {
                             $devices[$aDevice][$bDevice][$idx]['localRSTP'] = $portRoles[$aDevice][$portDetails['localPortId']];
                             $devices[$aDevice][$bDevice][$idx]['remoteRSTP'] = $portRoles[$bDevice][$portDetails['remotePortId']];
                             // indicate if the link is passing traffic or not
                             if (in_array($devices[$aDevice][$bDevice][$idx]['localRSTP'], \OSS_SNMP\MIBS\Cisco\RSTP::$STP_X_RSTP_PASSING_PORT_ROLES) && in_array($devices[$aDevice][$bDevice][$idx]['remoteRSTP'], \OSS_SNMP\MIBS\Cisco\RSTP::$STP_X_RSTP_PASSING_PORT_ROLES)) {
                                 $devices[$aDevice][$bDevice][$idx]['RSTPpassing'] = true;
                             } else {
                                 $devices[$aDevice][$bDevice][$idx]['RSTPpassing'] = false;
                             }
                         } else {
                             $devices[$aDevice][$bDevice][$idx]['localRSTP'] = false;
                             $devices[$aDevice][$bDevice][$idx]['remoteRSTP'] = false;
                             $devices[$aDevice][$bDevice][$idx]['RSTPpassing'] = null;
                         }
                     }
                 }
             }
             $links = $root->useCisco_CDP()->linkTopology($devices);
             $this->view->devices = $devices;
             $this->view->links = $links;
             $this->view->locations = call_user_func("{$this->_options['utilsClass']}::extractLocations", $devices);
             $this->view->file = $file = $this->generateGraphFilename(array($host, $vlanid));
             if ($this->_getParam('submit') == 'Download DOT File') {
                 header('Content-type: text/plain');
                 header('Content-Disposition: attachment; filename="' . $file . '.dot"');
                 Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer');
                 echo $this->view->render('cdp/stp-topology-graph.dot');
                 return;
             }
             $this->getSessionNamespace()->stp_topology_file = $this->generateDotGraph($file, $this->view->render('cdp/stp-topology-graph.dot'), APPLICATION_PATH . '/../var/tmp');
         } while (false);
     }
 }