Exemplo n.º 1
0
 /**
  * Update a switches ports using SNMP polling
  *
  * There is an optional ``$results`` array which can be passed by reference. If
  * so, it will be indexed by the SNMP port index (or a decresing nagative index
  * beginning -1 if the port only exists in the database). The contents of this
  * associative array is:
  *
  *     "port"   => \Entities\SwitchPort object
  *     "bullet" =>
  *         - false for existing ports
  *         - "new" for newly found ports
  *         - "db" for ports that exist in the database only
  *
  * **Note:** It is assumed that the Doctrine2 Entity Manager is available in the
  * Zend registry as ``d2em`` in this function.
  *
  * @throws \OSS_SNMP\Exception
  *
  * @param \OSS_SNMP\SNMP $host An instance of \OSS_SNMP\SNMP for this switch
  * @param \OSS_Logger $logger An instance of the logger or false
  * @param array Call by reference to an array in which to store results as outlined above
  * @return \Entities\Switcher For fluent interfaces
  */
 public function snmpPollSwitchPorts($host, $logger = false, &$result = false)
 {
     // clone the ports currently known to this switch as we'll be playing with this array
     $existingPorts = clone $this->getPorts();
     // iterate over all the ports discovered on the switch:
     foreach ($host->useIface()->indexes() as $index) {
         // we're only interested in Ethernet ports here (right?)
         if ($host->useIface()->types()[$index] != \OSS_SNMP\MIBS\Iface::IF_TYPE_ETHERNETCSMACD) {
             continue;
         }
         // find the matching switchport that may already be in the database (or create a new one)
         $switchport = false;
         foreach ($existingPorts as $ix => $ep) {
             if ($ep->getIfIndex() == $index) {
                 $switchport = $ep;
                 if (is_array($result)) {
                     $result[$index] = ["port" => $switchport, 'bullet' => false];
                 }
                 if ($logger) {
                     $logger->info(" - {$this->getName()} - found pre-existing port for ifIndex {$index}");
                 }
                 // remove this from the array so later we'll know what ports exist only in the database
                 unset($existingPorts[$ix]);
                 break;
             }
         }
         $new = false;
         if (!$switchport) {
             // no existing port in database so we have found a new port
             $switchport = new \Entities\SwitchPort();
             $switchport->setSwitcher($this);
             $this->addPort($switchport);
             $switchport->setType(\Entities\SwitchPort::TYPE_UNSET);
             $switchport->setIfIndex($index);
             $switchport->setActive(true);
             \Zend_Registry::get('d2em')['default']->persist($switchport);
             if (is_array($result)) {
                 $result[$index] = ["port" => $switchport, 'bullet' => "new"];
             }
             $new = true;
             if ($logger) {
                 $logger->info("Found new port for {$this->getName()} with index {$index}");
             }
         }
         // update / set port details from SNMP
         $switchport->snmpUpdate($host, $logger);
     }
     if (count($existingPorts)) {
         $i = -1;
         foreach ($existingPorts as $ep) {
             if (is_array($result)) {
                 $result[$i--] = ["port" => $ep, 'bullet' => "db"];
             }
             if ($logger) {
                 $logger->warn("{$this->getName()} - port found in database with no matching port on the switch: " . " [{$ep->getId()}] {$ep->getName()}");
             }
         }
     }
     return $this;
 }
Exemplo n.º 2
0
 /**
  * Update switch port details from a SNMP poll of the device.
  *
  * Pass an instance of OSS_Logger if you want logging enabled.
  *
  * @link https://github.com/opensolutions/OSS_SNMP
  *
  * @throws \OSS_SNMP\Exception
  *
  * @param \OSS_SNMP\SNMP $host An instance of the SNMP host object
  * @param \OSS_Logger $logger An instance of the logger or false
  * @return \Entities\SwitchPort For fluent interfaces
  */
 public function snmpUpdate($host, $logger = false)
 {
     foreach (self::$OSS_SNMP_MAP as $snmp => $entity) {
         $fn = "get{$entity}";
         switch ($snmp) {
             case 'lastChanges':
                 $n = $host->useIface()->{$snmp}(true)[$this->getIfIndex()];
                 // need to allow for small changes due to rounding errors
                 if ($logger && $this->{$fn}() != $n && abs($this->{$fn}() - $n) > 60) {
                     $logger->info("[{$this->getSwitcher()->getName()}]:{$this->getName()} [Index: {$this->getIfIndex()}] Updating {$entity} from [{$this->{$fn}()}] to [{$n}]");
                 }
                 break;
             default:
                 $n = $host->useIface()->{$snmp}()[$this->getIfIndex()];
                 if ($logger && $this->{$fn}() != $n) {
                     $logger->info("[{$this->getSwitcher()->getName()}]:{$this->getName()} [Index: {$this->getIfIndex()}] Updating {$entity} from [{$this->{$fn}()}] to [{$n}]");
                 }
                 break;
         }
         $fn = "set{$entity}";
         $this->{$fn}($n);
     }
     if ($this->getSwitcher()->getMauSupported()) {
         foreach (self::$OSS_SNMP_MAU_MAP as $snmp => $entity) {
             $getfn = "get{$entity['fn']}";
             $setfn = "set{$entity['fn']}";
             try {
                 if (isset($entity['xlate'])) {
                     $n = $host->useMAU()->{$snmp}($entity['xlate'])[$this->getIfIndex()];
                 } else {
                     $n = $host->useMAU()->{$snmp}()[$this->getIfIndex()];
                 }
             } catch (\OSS_SNMP\Exception $e) {
                 // looks like the switch supports MAU but not all of the MIBs
                 $logger->debug("[{$this->getSwitcher()->getName()}]:{$this->getName()} [Index: {$this->getIfIndex()}] MAU MIB for {$fn} not supported");
                 $n = null;
             }
             if ($n == '*** UNKNOWN ***' && $snmp == 'types') {
                 $n = '(empty)';
             }
             if ($logger && $this->{$getfn}() != $n) {
                 $logger->info("[{$this->getSwitcher()->getName()}]:{$this->getName()} [Index: {$this->getIfIndex()}] Updating {$entity['fn']} from [{$this->{$getfn}()}] to [{$n}]");
             }
             $this->{$setfn}($n);
         }
     }
     try {
         // not all switches support this
         // FIXME is there a vendor agnostic way of doing this?
         // are we a LAG port?
         $isAggregatePorts = $host->useLAG()->isAggregatePorts();
         if (isset($isAggregatePorts[$this->getIfIndex()]) && $isAggregatePorts[$this->getIfIndex()]) {
             $this->setLagIfIndex($host->useLAG()->portAttachedIds()[$this->getIfIndex()]);
         } else {
             $this->setLagIfIndex(null);
         }
     } catch (\OSS_SNMP\Exception $e) {
     }
     $this->setLastSnmpPoll(new \DateTime());
     return $this;
 }