Exemplo n.º 1
0
    def address_index_to_ip(cls, index):
        """Convert a row index from cIpAddressTable to an IP object."""

        entry = cls.nodes['cIpAddressPfxOrigin']
        index = OID(index)
        if entry.oid.is_a_prefix_of(index):
            # Chop off the entry OID+column prefix
            index = OID(index.strip_prefix(entry.oid)[1:])

        return super(CiscoIetfIpMib, cls).address_index_to_ip(index)
Exemplo n.º 2
0
    def address_index_to_ip(cls, index):
        """Convert a row index from ipAddressTable to an IP object."""

        index = OID(index)
        if 'ipAddressEntry' in cls.nodes:
            entry = cls.nodes['ipAddressEntry']
            if entry.oid.is_a_prefix_of(index):
                # Chop off the entry OID+column prefix
                index = OID(index.strip_prefix(entry.oid)[1:])

        ip = cls.inetaddress_to_ip(index)
        return ip
Exemplo n.º 3
0
        def _result_formatter(result):
            formatted_result = {}
            for varlist in result.values():
                # Build a table structure
                for oid in sorted(varlist.keys()):
                    if not table.table.oid.is_a_prefix_of(oid):
                        raise MibRetrieverError(
                            "Received wrong response from client,"
                            "%s is not in %s" % (oid, table.table.oid))

                    # Extract table position of value
                    oid_suffix = OID(oid).strip_prefix(table.row.oid)
                    column_no = oid_suffix[0]
                    row_index = oid_suffix[1:]
                    if column_no not in table.reverse_column_index:
                        self._logger.warning(
                            "device response has bad table index %s in %s::%s, "
                            "ignoring",
                            oid_suffix, self.mib['moduleName'], table_name)
                        continue
                    column_name = table.reverse_column_index[column_no]

                    if row_index not in formatted_result:
                        formatted_result[row_index] = \
                            MibTableResultRow(row_index, table.columns.keys())
                    formatted_result[row_index][column_name] = varlist[oid]

            return formatted_result
Exemplo n.º 4
0
 def _make_result_dict(self, sensor_oid, base_oid, serial, desc,
                       u_o_m=None, precision=0, scale=None, name=None):
     """ Make a simple dictionary to return to plugin"""
     if not sensor_oid or not base_oid or not serial or not desc:
         return {}
     oid = OID(base_oid) + OID(sensor_oid)
     internal_name = serial + desc
     return {'oid': str(oid),
             'unit_of_measurement': u_o_m,
             'precision': precision,
             'scale': scale,
             'description': desc,
             'name': name,
             'internal_name': internal_name,
             'mib': self.get_module_name(),
             }
Exemplo n.º 5
0
    def prefix_index_to_ip(cls, index, prefix_entry=None):
        """Convert a row index from cIpAddressPfxTable to an IP object."""

        entry = cls.nodes['cIpAddressPfxOrigin']
        stripped_index = OID(index).strip_prefix(entry.oid)

        return super(CiscoIetfIpMib, cls).prefix_index_to_ip(stripped_index)
Exemplo n.º 6
0
    def retrieve_alternate_bridge_mibs(self):
        """Retrieves a list of alternate bridge mib instances.

        This is accomplished by looking at entLogicalTable.  Returns a
        deferred whose result value is a list of tuples::

          (entity_description, community)

        :NOTE: Some devices will return entities with the same community.
               These should effectively be filtered out for polling purposes.
               A Cisco WS-C3560CG-8PC-S running IOS 15.0(2)SE has also been
               shown to return communities with null bytes,
               which are unusable and will be filtered.

        """
        # Define this locally to avoid external overhead
        bridge_mib_oid = OID('.1.3.6.1.2.1.17')

        def _bridge_mib_filter(result):
            def _is_bridge_mib_instance_with_valid_community(row):
                return (row['entLogicalType']
                        and OID(row['entLogicalType']) == bridge_mib_oid
                        and '\x00' not in row['entLogicalCommunity'])

            new_result = [(r['entLogicalDescr'], r['entLogicalCommunity'])
                          for r in result.values()
                          if _is_bridge_mib_instance_with_valid_community(r)]
            return new_result

        df = self.retrieve_columns(
            ['entLogicalDescr', 'entLogicalType', 'entLogicalCommunity'])
        df.addCallback(_bridge_mib_filter)
        return df
Exemplo n.º 7
0
def transform_trap_type(pdu):
    """Transforms trap information from an SNMP-v1 pdu to something that
    is consistent with SNMP-v2c, as documented in RFC2576.

    :returns: A tuple of (snmpTrapOID, genericType)

    """
    enterprise_type = POINTER(c_long * pdu.enterprise_length)
    enterprise_p = cast(pdu.enterprise, enterprise_type)
    enterprise = OID(enterprise_p.contents)

    generic = pdu.trap_type

    # According to RFC2576 "Coexistence between Version 1, Version 2,
    # and Version 3 of the Internet-standard Network Management
    # Framework", we build snmpTrapOID from the snmp-v1 trap by
    # combining enterprise + 0 + specific trap parameter IF the
    # generic trap parameter is 6. If not, the traps are defined as
    # 1.3.6.1.6.3.1.1.5 + (generic trap parameter + 1)
    if generic == netsnmp.SNMP_TRAP_ENTERPRISESPECIFIC:
        snmp_trap_oid = enterprise + [0, pdu.specific_type]
    else:
        snmp_trap_oid = SNMP_TRAPS + [generic + 1]

    generic_type = TRAP_MAP.get(generic, str(generic)).upper()
    return snmp_trap_oid, generic_type
Exemplo n.º 8
0
    def get(self, query="1.3.6.1.2.1.1.1.0"):
        """Performs an SNMP GET query.

        :param query: OID to query for.
        :returns: The response value

        """
        oid = OID(query)
        response = self.handle.sget([oid])
        if response:
            value = response.get(oid, None)
            if isinstance(value, tuple):
                return OID(value)
            return value
        else:
            return None
Exemplo n.º 9
0
def value_to_str(value):
    """Converts a value from a varbind to a string, as that is what the
    SNMPTrap API expects :-P
    """
    if isinstance(value, tuple):
        return str(OID(value))
    else:
        return str(value)
Exemplo n.º 10
0
 def get_dot1x_enabled_interfaces(self):
     _logger.error("Querying for dot1x enabled interfaces on Cisco")
     names = self._get_interface_names()
     return {
         names.get(OID(oid)[-1]):
         six.byte2int(state) & self.DOT1X_AUTHENTICATOR
         for oid, state in self._bulkwalk(self.dot1xPortAuth)
     }
Exemplo n.º 11
0
 def _fetch_sysobjectid(self):
     result = yield self.snmpv2_mib.get_sysObjectID()
     if not result:
         raise InvalidResponseError(
             "No response on sysObjectID query.", result, self.agent
         )
     oid = OID(result)
     self._logger.debug("sysObjectID is %s", oid)
     defer.returnValue(oid)
Exemplo n.º 12
0
    def multi_set(self, varbinds):
        """Performs SNMP set with multiple operations

        :type varbinds: list[PDUVarbind]
        """
        self.handle.sset([
            PDUVarbind(OID(v.oid), self.translate_type(v.type), v.value)
            for v in varbinds
        ])
Exemplo n.º 13
0
    def callback(self, src, pdu):
        """Handles trap callbacks from a TrapSession"""
        if not self._client_callback:
            return

        agent_addr = None
        generic_type = None
        community = pdu.community[:pdu.community_len]

        varbinds = netsnmp.getResult(pdu, _logger)

        if pdu.version == netsnmp.SNMP_VERSION_1:
            version = 1
            agent_addr = ".".join(str(d) for d in pdu.agent_addr)
            snmp_trap_oid, generic_type = transform_trap_type(pdu)
            uptime = pdu.time
        elif pdu.version == netsnmp.SNMP_VERSION_2c:
            version = 2
            _time_oid, time_val = varbinds.pop(0)
            _trap_oid_oid, trap_oid = varbinds.pop(0)

            uptime = time_val
            snmp_trap_oid = OID(trap_oid)
        else:
            raise UnsupportedSnmpVersionError(pdu.version)

        # Dump varbinds to debug log
        _logger.debug("varbinds: %r", varbinds)
        # Add remaining varbinds to dict
        varbind_dict = dict(
            (str(OID(oid)), value_to_str(value)) for oid, value in varbinds)

        trap = SNMPTrap(
            str(src),
            agent_addr or str(src),
            None,
            generic_type,
            str(snmp_trap_oid),
            uptime,
            community,
            version,
            varbind_dict,
        )
        self._client_callback(trap)
Exemplo n.º 14
0
    def _get_sysvariable(self, var):
        """Retrieves a system variable of the first agent instance.

        Will first try get-next on {var}, then fall back to getting {var}.0 on
        failure.  This is a workaround for a faulty SNMP agent implementation
        observed in Weathergoose devices, where e.g. a GET-NEXT on sysObjectID
        would consistently return sysUpTime.0 instead.

        """
        oid = self.nodes[var].oid
        result = yield self.get_next(var)
        if result:
            defer.returnValue(result)
        else:
            oid = oid + OID('0')
            result = yield self.agent_proxy.get([str(oid)])
            for key, value in result.items():
                if oid == OID(key):
                    defer.returnValue(value)
Exemplo n.º 15
0
    def _process_alias_mapping(self, alias_mapping):
        mapping = defaultdict(list)
        for (phys_index, _logical), rowpointer in alias_mapping.items():
            # Last element is ifindex. Preceding elements is an OID.
            ifindex = OID(rowpointer)[-1]

            mapping[phys_index].append(ifindex)

        self._logger.debug("alias mapping: %r", mapping)
        return mapping
Exemplo n.º 16
0
 def _get_cpu_names(self, indexes):
     if not indexes:
         defer.returnValue({})
     self._logger.debug("getting cpu names from ENTITY-MIB")
     base_oid = EntityMib.nodes['entPhysicalName'].oid
     oids = [str(base_oid + (index, )) for index in indexes]
     names = yield self.agent_proxy.get(oids)
     self._logger.debug("cpu name result: %r", names)
     names = {OID(oid)[-1]: value for oid, value in names.items() if value}
     defer.returnValue(names)
Exemplo n.º 17
0
    def bulkwalk(self, query="1.3.6.1.2.1.1.1.0", strip_prefix=False):
        """Performs an SNMP walk on the host, using GETBULK requests.

        Will raise an UnsupportedSnmpVersionError if the current
        version is anything other than 2c.

        :param query: root OID for walk
        :param strip_prefix: A boolean. Set to True to strip the query prefix
                             from the OIDs in the response. Default is False.
        :returns: A list of (response_oid, value) pairs,
                  where the query prefix has been stripped from the
                  response_oids.

        """
        if str(self.version) != "2c":
            raise errors.UnsupportedSnmpVersionError(
                "Cannot use BULKGET in SNMP version " + self.version)
        result = []
        root_oid = OID(query)
        current_oid = root_oid

        while 1:
            response = self.handle.sgetbulk(self.NON_REPEATERS,
                                            self.MAX_REPETITIONS,
                                            [current_oid])
            if response is None:
                break
            for response_oid, value in response:
                if value is None:
                    return result

                current_oid = OID(response_oid)
                if (not root_oid.is_a_prefix_of(current_oid)
                        or current_oid == root_oid):
                    return result

                if isinstance(value, tuple):
                    value = str(OID(value))[1:]
                result.append((str(current_oid)[1:], value))

        return result
Exemplo n.º 18
0
 def _make_result_dict(self,
                       sensor_oid,
                       base_oid,
                       serial,
                       desc,
                       u_o_m=None,
                       **kwargs):
     """Make a simple dictionary to return to plugin"""
     if not sensor_oid or not base_oid or not serial or not desc:
         return {}
     oid = OID(base_oid) + OID(sensor_oid)
     internal_name = smart_str(serial) + desc
     res = {
         'oid': oid,
         'unit_of_measurement': u_o_m,
         'description': desc,
         'internal_name': internal_name,
         'mib': self.get_module_name(),
     }
     res.update(kwargs)
     return res
Exemplo n.º 19
0
 def test_entity_to_powersupply_or_fan(self):
     entity = {
         "entPhysicalName": "PSU 1",
         "entPhysicalModelName": "ABCDEF 720",
         "entPhysicalDescr": "Next-gen PSU Power fidelity foobar",
         "entPhysicalClass": NetboxEntity.CLASS_POWERSUPPLY,
         "entPhysicalSerialNum": "123ABC",
         0: OID('.1'),
     }
     unit = _entity_to_powersupply_or_fan(entity)
     assert isinstance(unit, PowerSupplyOrFan)
     assert isinstance(unit.device, Device)
Exemplo n.º 20
0
 def test_get_vlan_hp(self):
     self.handler = ManagementFactory.get_instance(self.netboxHP)
     # get hold of the read-only Snmp-object
     self.snmpReadOnlyHandler = self.handler._get_read_only_handle()
     # replace get-method on Snmp-object with a mock-method
     # this get-method returns a vlan-number
     self.snmpReadOnlyHandler.get = Mock(return_value=666)
     ifc = Mock(baseport=1)
     self.assertEqual(self.handler.get_interface_native_vlan(ifc), 666,
                      "getVlan-test failed")
     self.snmpReadOnlyHandler.get.assert_called_with(
         OID('.1.3.6.1.2.1.17.7.1.4.5.1.1.1'))
Exemplo n.º 21
0
def convert_oids(mib):
    """Converts a mib data structure's oid strings to OID objects.

    mib is expected to be a data structure as dumped by the smidump utility
    (using the -f python option).

    """
    for node in chain(
        mib.get('nodes', {}).values(), mib.get('notifications', {}).values()
    ):
        if isinstance(node['oid'], str):
            node['oid'] = OID(node['oid'])
Exemplo n.º 22
0
def convert_oids(mib):
    """Convert a mib data structure's oid strings to OID objects.

    mib is expected to be a data structure as dumped by the smidump utility
    (using the -python option).

    """
    for node_name in mib['nodes']:
        node = mib['nodes'][node_name]
        if isinstance(node['oid'], basestring):
            #oid_tuple = tuple(int(i) for i in node['oid'].split('.'))
            node['oid'] = OID(node['oid'])
Exemplo n.º 23
0
    def _get_sensor_count(self):
        """Count all available sensors in this WxGoose"""
        sensor_counts_oid = self.mib['nodes']['sensorCounts']['oid']
        sensor_counts = yield self.retrieve_column('sensorCounts')
        mapped_counts = ((sensor_counts_oid + OID(key[0:1]), count)
                         for key, count in sensor_counts.items())

        result = dict((self.oid_name_map[oid], count)
                      for oid, count in mapped_counts
                      if oid in self.oid_name_map)
        self._debug('_get_sensor_count: result = %s', result)
        defer.returnValue(result)
Exemplo n.º 24
0
def value_to_str(value):
    """Converts a value from a varbind to a string, as that is what the
    SNMPTrap API expects :-P
    """
    if isinstance(value, tuple):
        return str(OID(value))
    elif isinstance(value, six.binary_type):
        try:
            return value.decode("utf-8")
        except UnicodeDecodeError:
            pass

    return str(value)
Exemplo n.º 25
0
    def _process_alias_mapping(self, alias_mapping):
        mapping = defaultdict(list)
        try:
            for (phys_index, _logical), rowpointer in alias_mapping.items():
                # Last element is ifindex. Preceding elements is an OID.
                ifindex = OID(rowpointer)[-1]

                mapping[phys_index].append(ifindex)
        except ValueError:
            self._logger.warning(
                "device has broken entAliasMappingTable implementation")
        self._logger.debug("alias mapping: %r", mapping)
        return mapping
Exemplo n.º 26
0
    def prefix_index_to_ip(cls, index, prefix_entry='ipAddressPrefixEntry'):
        """Convert a row index from ipAddressPrefixTable to an IP object."""

        index = OID(index)
        if prefix_entry in cls.nodes:
            entry = cls.nodes[prefix_entry]
            if entry.oid.is_a_prefix_of(index):
                # Chop off the entry OID+column prefix
                index = OID(index.strip_prefix(entry.oid)[1:])

        if len(index) < 4:
            cls._logger.debug("prefix_index_to_ip: index too short: %r", index)
            return None

        ifindex = index[0]
        addr_oid = index[1:-1]
        prefix_length = index[-1]

        ip = cls.inetaddress_to_ip(addr_oid)
        if ip:
            prefix = ip.make_net(prefix_length)
            return prefix
Exemplo n.º 27
0
    def prefix_index_to_ip(cls, index,
                           prefix_entry='ipAddressPrefixEntry'):
        """Convert a row index from ipAddressPrefixTable to an IP object."""

        index = OID(index)
        if prefix_entry in cls.nodes:
            entry = cls.nodes[prefix_entry]
            if entry.oid.is_a_prefix_of(index):
                # Chop off the entry OID+column prefix
                index = OID(index.strip_prefix(entry.oid)[1:])

        if len(index) < 4:
            cls._logger.debug("prefix_index_to_ip: index too short: %r", index)
            return None

        ifindex = index[0]
        addr_oid = index[1:-1]
        prefix_length = index[-1]

        ip = cls.inetaddress_to_ip(addr_oid)
        if ip:
            prefix = ip.make_net(prefix_length)
            return prefix
Exemplo n.º 28
0
    def _response_handler(self, result):
        """Handles a sysObjectID response."""
        if not result:
            raise InvalidResponseError("No response on sysObjectID query.",
                                       result, self.agent)
        # Just pick the first result, there should never really be multiple
        self.sysobjectid = str(OID(result))
        # ObjectIDs in the database are stored without the preceding dot.
        if self.sysobjectid[0] == '.':
            self.sysobjectid = self.sysobjectid[1:]

        self._logger.debug("sysObjectID is %s", self.sysobjectid)

        df = self._get_type_from_db()
        df.addCallback(self._check_for_typechange)
        df.addCallback(self._set_type)
        return df
Exemplo n.º 29
0
    def set(self, query, type, value):
        """Performs an SNMP SET operations.

        :param query: OID to set
        :param type: type of value to set. This may be
        i: INTEGER
        u: unsigned INTEGER
        t: TIMETICKS
        a: IPADDRESS
        o: OBJID
        s: OCTETSTRING
        U: COUNTER64 (version 2 and above)
        x: OCTETSTRING
        :param value: the value to set. Must ofcourse match type: i = 2,
         s = 'string'
        """
        self.handle.sset([PDUVarbind(OID(query), self.translate_type(type), value)])
Exemplo n.º 30
0
        def resultFormatter(result):
            formatted_result = {}
            # result keys may be OID objects/tuples or strings, depending on
            # snmp library used
            if node.oid not in result and str(node.oid) not in result:
                self._logger.debug(
                    "%s (%s) seems to be unsupported, result "
                    "keys were: %r", column_name, node.oid, result.keys())
                return {}
            varlist = result.get(node.oid, result.get(str(node.oid), None))

            for oid, value in varlist.items():
                # Extract index information from oid
                row_index = OID(oid).strip_prefix(node.oid)
                formatted_result[row_index] = value

            return formatted_result
Exemplo n.º 31
0
class GeistMibV3(ItWatchDogsMibV3):
    """
    A MibRetriever for retrieving information from Geist branded
    WeatherGoose products.

    Based on the GEIST-MIB-V3, which is more or less derived from the
    IT-WATCHDOGS-MIB-V3. Objects names in the derived MIB are mostly the
    same, except for a `cm` prefix on notification objects, which has changed
    to the `gst` prefix. This implementation does not use the notification
    objects for anything, so we don't need to care about this name change here.

    """
    mib = get_mib('GEIST-MIB-V3')

    oid_name_map = {OID(attrs['oid']): name
                    for name, attrs in mib['nodes'].items()}

    lowercase_nodes = {key.lower(): key for key in mib['nodes']}
Exemplo n.º 32
0
class GeistMibV4(ItWatchDogsMibV4):
    """
    A MibRetriever for retrieving information from Geist branded
    WeatherGoose products.

    Based on the GEIST-V4-MIB, which is more or less derived from the
    IT-WATCHDOGS-V4-MIB. Objects names in the derived MIB seems to be the
    same.

    """
    from nav.smidumps.geist_mibv4 import MIB as mib

    oid_name_map = {
        OID(attrs['oid']): name
        for name, attrs in mib['nodes'].items()
    }

    lowercase_nodes = {key.lower(): key for key in mib['nodes']}
Exemplo n.º 33
0
 def _verify_sensor(self, object_name):
     result = yield self.get_next(object_name)
     if result:
         node = self.nodes[object_name]
         oid = node.oid + OID('.0')
         sensor = {
             'oid': str(oid),
             'internal_name': object_name,
             'name': object_name,
             'description': node.raw_mib_data.get('description',
                                                  object_name),
             'mib': self.mib['moduleName'],
             'scale': None,
         }
         units = node.raw_mib_data.get('units', '')
         sensor['unit_of_measurement'] = units
         for mibunits, navunits in UNIT_TRANSLATION.items():
             if units.lower().startswith(mibunits.lower()):
                 sensor.update(navunits)
         if object_name == 'loadDistributionBreakerStatus':
             sensor['unit_of_measurement'] = 'boolean'
         returnValue(sensor)