Пример #1
0
 def get_object_type(self, snmp_engine):
     mib_view = CommandGeneratorVarBinds().getMibViewController(
         snmpEngine=snmp_engine)
     object_identity = self._create_object_identity()
     object_type = ObjectType(object_identity, self.value)
     object_type.resolveWithMib(mib_view)
     return object_type
Пример #2
0
    def from_snmp(self, host, community):
        assert host
        assert community

        # switch port names and numbers
        # 1.3.6.1.2.1.31.1.1.1.1
        oid = ObjectType(ObjectIdentity('IF-MIB', 'ifName'))
        for port_num_raw, port_name in _snmp_walk(host, community, oid):
            sw_port_num = port_num_raw[port_num_raw.rfind('.') + 1:]
            self._add_switch_port(sw_port_num, port_name)

        # mac addresses table
        # 1.3.6.1.2.1.17.7.1.2.2.1.2
        oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.17.7.1.2.2.1.2'))
        for mac_raw, sw_port_num in _snmp_walk(host, community, oid):
            name_parts = mac_raw.split('.')
            mac_address = _normalize_mac("".join(
                [("%02x" % int(name_parts[x])).upper() for x in range(len(name_parts) - 6, len(name_parts))]
            )).upper()

            self._add_server_port(self.get_port_name(sw_port_num), mac_address)

        # arp address table
        # 3.6.1.2.1.4.22.1.2
        oid = ObjectType(ObjectIdentity('IP-MIB', 'ipNetToMediaPhysAddress'))
        for ip_addr_raw, mac_addr in _snmp_walk(host, community, oid):
            mac_addr = _normalize_mac(mac_addr)
            name_parts = ip_addr_raw.split('.')
            ip_address = ".".join([name_parts[x] for x in range(len(name_parts) - 4, len(name_parts))])
            self._add_server_port_ip(mac_addr, ip_address)
Пример #3
0
 def __init__(self, oid, value, snmp_engine, logger):
     self._raw_oid = oid
     self._snmp_mib_translator = CommandGeneratorVarBinds.getMibViewController(
         snmp_engine)
     self._logger = logger
     self._mib_id = None
     self._mib_name = None
     self._index = None
     self._raw_value = value
     self._object_id = ObjectIdentity(self._raw_oid)
     self._object_type = ObjectType(self._object_id, self._raw_value)
Пример #4
0
 def f(snmp, portstr):
     snmp._command(
         snmp.cmd_gen.setCmd,
         ObjectType(
             ObjectIdentity('GEIST-MIB-V3', 'ctrlOutletStatus',
                            int(portstr)), Gauge32(3)))
     sleep(delay)
     snmp._command(
         snmp.cmd_gen.setCmd,
         ObjectType(
             ObjectIdentity('GEIST-MIB-V3', 'ctrlOutletStatus',
                            int(portstr)), Gauge32(1)))
Пример #5
0
def trap(self, work):

    var_bind_table = []
    not_translated_oids = []
    remaining_oids = []
    oid_values = set()
    remotemibs = set()
    metrics = {}
    for w in work["data"]:

        if OID_VALIDATOR.match(w[1]):
            with suppress(Exception):
                found, mib = self.is_mib_known(w[1], w[1], work["host"])
                if found and mib not in oid_values:
                    self.load_mibs([mib])
                    oid_values.add(mib)

        try:
            var_bind_table.append(
                ObjectType(ObjectIdentity(w[0]),
                           w[1]).resolveWithMib(self.mib_view_controller))
        except SmiError:
            not_translated_oids.append((w[0], w[1]))

    for oid in not_translated_oids:
        found, mib = self.is_mib_known(oid[0], oid[0], work["host"])
        if found:
            remotemibs.add(mib)
            remaining_oids.append((oid[0], oid[1]))

    if remotemibs:
        self.load_mibs(remotemibs)
        for w in remaining_oids:
            try:
                var_bind_table.append(
                    ObjectType(ObjectIdentity(w[0]),
                               w[1]).resolveWithMib(self.mib_view_controller))
            except SmiError:
                logger.warning(f"No translation found for {w[0]}")

    _, _, result = self.process_snmp_data(var_bind_table, metrics,
                                          work["host"])

    return {
        "time": time.time(),
        "result": result,
        "address": work["host"],
        "detectchange": False,
        "sourcetype": "sc4snmp:traps",
    }
    def set(self, oids):
        """SNMP Set operation.

        :param oids: list of oids to set. oid can be full dotted OID or (MIB, OID name, [index]).
            For example, the OID to get sysContact can by any of the following:
            ('SNMPv2-MIB', 'sysContact', 0)
            '1.3.6.1.2.1.1.4.0'
            snmp.set([(("CISCO-CONFIG-COPY-MIB", "ccCopyProtocol", 10), 1),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopySourceFileType", 10), 1),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopyDestFileType", 10), 3),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopyServerAddress", 10), "10.212.95.180"),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopyFileName", 10), "test_snmp_running_config_save"),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopyVrfName", 10), "management"),
                      (("CISCO-CONFIG-COPY-MIB", "ccCopyEntryRowStatus", 10), 4)])
        """

        if self.is_read_only:
            raise Exception(self.__class__.__name__, "SNMP Read Community doesn't support snmp set command")

        object_identities = []
        for oid in oids:
            if type(oid) is list or type(oid) is tuple:
                oid_0 = list(oid)
                if len(oid_0) < 2:
                    raise Exception(self.__class__.__name__, "Missing oid or value data")

                if type(oid[0]) is list or type(oid[0]) is tuple:
                    if (len(oid_0[0])) < 3:
                        raise Exception(self.__class__.__name__, "Missing oid index")
                object_identities.append(ObjectType(ObjectIdentity(*oid_0[0]), oid[1]))
            else:
                raise Exception(self.__class__.__name__, "Wrong oids parameter")

        self._write_command(self.cmd_gen.setCmd, *object_identities)
Пример #7
0
def get_security_engine_id(logger, ir: InventoryRecord,
                           snmpEngine: SnmpEngine):
    observerContext: Dict[Any, Any] = {}

    transportTarget = UdpTransportTarget((ir.address, ir.port),
                                         timeout=UDP_CONNECTION_TIMEOUT)

    # Register a callback to be invoked at specified execution point of
    # SNMP Engine and passed local variables at execution point's local scope
    snmpEngine.observer.registerObserver(
        lambda e, p, v, c: c.update(securityEngineId=v["securityEngineId"]),
        "rfc3412.prepareDataElements:internal",
        cbCtx=observerContext,
    )

    # Send probe SNMP request with invalid credentials
    authData = UsmUserData("non-existing-user")

    errorIndication, errorStatus, errorIndex, varBinds = next(
        getCmd(
            snmpEngine,
            authData,
            transportTarget,
            ContextData(),
            ObjectType(ObjectIdentity("SNMPv2-MIB", "sysDescr", 0)),
        ))

    # See if our SNMP engine received REPORT PDU containing securityEngineId
    securityEngineId = fetch_security_engine_id(observerContext,
                                                errorIndication)
    logger.debug(f"securityEngineId={securityEngineId}")
    return securityEngineId
Пример #8
0
def snmpRecvCallback(dispatcher, domain, address, msg):
    logger = logging.getLogger("apctrap")
    while msg:
        version = int(api.decodeMessageVersion(msg))
        if version in api.protoModules: module = api.protoModules[version]
        else:
            logger.error("SYSTEM\tERROR | Unsupported SNMP Version")
            return

        req, msg = decoder.decode(msg, asn1Spec=module.Message())
        logger.info("NOTIFICATION\t{} | {}".format(address, domain))

        pdu = module.apiMessage.getPDU(req)
        if not pdu.isSameTypeWith(module.TrapPDU()): continue

        if version == api.protoVersion1:
            varBinds = module.apiTrapPDU.getVarBindList(pdu)
        else:
            varBinds = module.apiPDU.getVarBindList(pdu)

        for v, b in varBinds:
            key = '.'.join([str(i) for i in v._value])
            value = b.getComponent('simple')._value

            parsed = ObjectType(ObjectIdentity(key), value)
            try:
                parsed.resolveWithMib(viewController)
            except Exception as e:
                logger.warning(
                    "TRAP\tERROR | Failed to resolve symbol ({}={})".format(
                        key, value))
                continue
            key, value = parsed.prettyPrint().split(" = ")
            logger.info("TRAP\t{} | {}".format(key, value))

            if key == "PowerNet-MIB::mtrapargsString.0":
                message = value
                for contact in contacts['contacts']:
                    phoneNumber = contact['phoneNumber']
                    _redis.publish(
                        'sms',
                        json.dumps(
                            dict(phoneNumber=phoneNumber, message=message)))

    return msg
Пример #9
0
def snmpRecvCallback(dispatcher, domain, address, msg):
    logger=logging.getLogger("apctrap")
    while msg:
        version=int(api.decodeMessageVersion(msg))
        if version in api.protoModules: module=api.protoModules[version]
        else:
            logger.error("SYSTEM\tERROR | Unsupported SNMP Version")
            return

        req,msg=decoder.decode(msg, asn1Spec=module.Message())
        logger.info("NOTIFICATION\t{} | {}".format(address, domain))

        pdu=module.apiMessage.getPDU(req)
        if not pdu.isSameTypeWith(module.TrapPDU()): continue

        if version==api.protoVersion1:
            varBinds=module.apiTrapPDU.getVarBindList(pdu)
        else: varBinds=module.apiPDU.getVarBindList(pdu)

        for v,b in varBinds:
            key='.'.join([str(i) for i in v._value])
            value=b.getComponent('simple')._value

            parsed=ObjectType(ObjectIdentity(key), value)
            try: parsed.resolveWithMib(viewController)
            except Exception as e: 
                logger.warning("TRAP\tERROR | Failed to resolve symbol ({}={})".format(key,value))
                continue
            key,value=parsed.prettyPrint().split(" = ")
            logger.info("TRAP\t{} | {}".format(key,value))

            if key=="PowerNet-MIB::mtrapargsString.0":
                message=value
                for contact in contacts['contacts']:
                    phoneNumber=contact['phoneNumber']
                    _redis.publish('sms', json.dumps(dict(phoneNumber=phoneNumber, message=message)))

    return msg
Пример #10
0
    def from_snmp(self, host, community):
        assert host
        assert community

        # load port id map
        oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.17.1.4.1.2'))
        for name, value in _snmp_walk(host, community, oid):
            self.snmpid__port_num__map[value] = name.split('.')[-1]

        # switch port names and numbers
        oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1'))
        for name, value in _snmp_walk(host, community, oid):
            snmp_port_id = name.split('.')[-1]
            if snmp_port_id in self.snmpid__port_num__map:
                real_port_number = self.snmpid__port_num__map[snmp_port_id]
                self._add_switch_port(real_port_number, value)
            else:
                logger.warning("There is no mapping for the SNMP port ID: %s" %
                               snmp_port_id)

        # mac addresses table
        oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.17.7.1.2.2.1.2'))
        for name, value in _snmp_walk(host, community, oid):
            name_parts = name.split('.')
            mac_address = "".join([
                ("%02x" % int(name_parts[x])).upper()
                for x in range(len(name_parts) - 6, len(name_parts))
            ]).upper()

            self._add_server_port(self.get_port_name(value), mac_address)

        # arp address table
        oid = ObjectType(ObjectIdentity('IP-MIB', 'ipNetToMediaPhysAddress'))
        for name, value in _snmp_walk(host, community, oid):
            ip_address = '.'.join(name.split('.')[-4:])
            self._add_server_port_ip(value.upper(), ip_address)
Пример #11
0
def _fetch_data(pipeline_: Pipeline):
    snmp_version = 0 if pipeline_.source.version == 'v1' else 1
    for host in pipeline_.source.hosts:
        host_ = host if '://' in host else f'//{host}'
        url = urlparse(host_)
        iterator = getCmd(SnmpEngine(),
                          CommunityData(pipeline_.source.read_community,
                                        mpModel=snmp_version),
                          UdpTransportTarget(
                              (url.hostname, url.port or SNMP_DEFAULT_PORT),
                              timeout=pipeline_.source.query_timeout,
                              retries=0),
                          ContextData(),
                          *[
                              ObjectType(ObjectIdentity(mib))
                              for mib in pipeline_.config['oids']
                          ],
                          lookupNames=True,
                          lookupMib=True)
        for i in iterator:
            yield i, host
Пример #12
0
 def validate_connection(self):
     errors = []
     snmp_version = 0 if self.source.version == 'v1' else 1
     for host in self.source.hosts:
         host_ = host if '://' in host else f'//{host}'
         url = urllib.parse.urlparse(host_)
         iterator = getCmd(
             SnmpEngine(),
             CommunityData(self.source.read_community, mpModel=snmp_version),
             UdpTransportTarget((url.hostname, url.port or SNMP_DEFAULT_PORT), timeout=10, retries=0),
             ContextData(),
             ObjectType(ObjectIdentity('1.3.6.1.2.1.1.5.0')),
             lookupNames=True,
             lookupMib=True
         )
         for response in iterator:
             if type(response[0]).__name__ == 'RequestTimedOut':
                 errors.append(f'Couldn\'t get response from `{host}`: {type(response[0]).__name__}')
                 logging.warning(f'Couldn\'t connect to {host}')
     if len(errors) == len(self.source.hosts):
         raise ValidationException(errors)
Пример #13
0
    def get_var_binds(self,
                      address,
                      walk=False,
                      profiles=[],
                      walked_first_time=True):
        varbinds_bulk = set()
        varbinds_get = set()
        get_mapping = {}
        bulk_mapping = {}
        if walk and (not walked_first_time or not profiles):
            varbinds_bulk.add(ObjectType(ObjectIdentity("1.3.6")))
        else:
            needed_mibs = []
            required_bulk = {}

            # First pass we only look at profiles for a full mib walk
            for profile in profiles:
                # Its possible a profile is removed on upgrade but schedule doesn't yet know
                if profile in self.profiles and "varBinds" in self.profiles[
                        profile]:
                    profile_spec = self.profiles[profile]
                    profile_varbinds = profile_spec["varBinds"]
                    for vb in profile_varbinds:
                        if len(vb) == 1:
                            if vb[0] not in required_bulk:
                                required_bulk[vb[0]] = None
                                if not walk:
                                    bulk_mapping[f"{vb[0]}"] = profile
                        if vb[0] not in needed_mibs:
                            needed_mibs.append(vb[0])

            for profile in profiles:
                # Its possible a profile is removed on upgrade but schedule doesn't yet know
                if profile in self.profiles and "varBinds" in self.profiles[
                        profile]:
                    profile_spec = self.profiles[profile]
                    profile_varbinds = profile_spec["varBinds"]
                    for vb in profile_varbinds:
                        if len(vb) == 2:
                            if vb[0] not in required_bulk or (
                                    required_bulk[vb[0]]
                                    and vb[1] not in required_bulk[vb[0]]):
                                if vb[0] not in required_bulk:
                                    required_bulk[vb[0]] = [vb[1]]
                                else:
                                    required_bulk[vb[0]].append(vb[1])
                                if not walk:
                                    bulk_mapping[f"{vb[0]}:{vb[1]}"] = profile

            for mib, entries in required_bulk.items():
                if entries is None:
                    varbinds_bulk.add(ObjectType(ObjectIdentity(mib)))
                else:
                    for entry in entries:
                        varbinds_bulk.add(
                            ObjectType(ObjectIdentity(mib, entry)))

            for profile in profiles:
                # Its possible a profile is removed on upgrade but schedule doesn't yet know
                if profile in self.profiles and "varBinds" in self.profiles[
                        profile]:
                    profile_spec = self.profiles[profile]
                    profile_varbinds = profile_spec["varBinds"]
                    for vb in profile_varbinds:
                        if len(vb) == 3:
                            if vb[0] not in required_bulk or (
                                    required_bulk[vb[0]]
                                    and vb[1] not in required_bulk[vb[0]]):
                                varbinds_get.add(
                                    ObjectType(
                                        ObjectIdentity(vb[0], vb[1], vb[2])))
                                if not walk:
                                    get_mapping[
                                        f"{vb[0]}:{vb[1]}:{vb[2]}"] = profile
            self.load_mibs(needed_mibs)

        logger.debug(f"host={address} varbinds_get={varbinds_get}")
        logger.debug(f"host={address} get_mapping={get_mapping}")
        logger.debug(f"host={address} varbinds_bulk={varbinds_bulk}")
        logger.debug(f"host={address} bulk_mapping={bulk_mapping}")

        return varbinds_get, get_mapping, varbinds_bulk, bulk_mapping
Пример #14
0
    cmdgen.BulkCommandGenerator().sendVarBinds(
        snmpEngine,
        addrName,
        contextData.contextEngineId,
        contextData.contextName,
        nonRepeaters,
        maxRepetitions,
        varbinds,
        __bulkSubTreeCmdcbFun,
        (lookupMib, deferred, [], oidTuple, oidTupleLen, logValues)
    )
    return deferred

engine = SnmpEngine()
transportTarget = UdpTransportTarget(transportAddr=('1.2.3.4', 161))
blankContextData = ContextData()

dfd = bulkSubTreeCmd(
    engine,
    CommunityData('public'),
    transportTarget,
    blankContextData,
    0, 15,
    ObjectType(ObjectIdentity('1.3.6.1.2.1'))
)
dfd.addCallback(printList)
dfd.addErrback(println)
dfd.addCallback(lambda _: reactor.stop())

reactor.run()
Пример #15
0
class SnmpResponse(object):
    def __init__(self, oid, value, snmp_engine, logger):
        self._raw_oid = oid
        self._snmp_mib_translator = CommandGeneratorVarBinds.getMibViewController(
            snmp_engine)
        self._logger = logger
        self._mib_id = None
        self._mib_name = None
        self._index = None
        self._raw_value = value
        self._object_id = ObjectIdentity(self._raw_oid)
        self._object_type = ObjectType(self._object_id, self._raw_value)

    @property
    def _object_identity(self):
        if not self._object_id.isFullyResolved():
            self._object_id.resolveWithMib(self._snmp_mib_translator)
        return self._object_id

    @property
    def object_type(self):
        if not self._object_type.isFullyResolved():
            self._object_type.resolveWithMib(self._snmp_mib_translator)
        return self._object_type

    @property
    def raw_value(self):
        return self._raw_value

    @property
    def oid(self):
        return self._object_identity.getOid()

    @property
    def mib_name(self):
        if not self._mib_name:
            self._get_oid()
        return self._mib_name

    @property
    def mib_id(self):
        if not self._mib_id:
            self._get_oid()
        return self._mib_id

    @property
    def index(self):
        if not self._index:
            self._get_oid()
        return self._index

    @property
    def safe_value(self):
        result = ""
        try:
            result = self.value or ""
        except TranslateSNMPException:
            pass

        return result

    @property
    def value(self):
        try:
            if self._raw_value is None or not self.object_type:
                return
            if hasattr(self.object_type[1], "prettyPrint"):
                value = self.object_type[1].prettyPrint()
            else:
                value = str(self.object_type[1])
            if value.lower().startswith("0x"):
                value = str(self._raw_value)
            return value
        except (PySnmpError, SmiError):
            raise TranslateSNMPException("Error parsing snmp response")

    def _get_oid(self):
        oid = self._object_identity.getMibSymbol()
        self._mib_name = oid[0]
        self._mib_id = oid[1]
        if isinstance(oid[-1], tuple):
            self._index = ".".join(map(lambda x: x.prettyPrint(), oid[-1]))

    def __str__(self):
        return self.safe_value

    def __repr__(self):
        return self.__str__()
 def set(self, object_identity, value):
     """ Sets the value at object_identity"""
     # TODO This should not use the internal _command function
     handler = self._handler('set')
     return handler._command(handler.cmd_gen.setCmd,
                             ObjectType(object_identity, value))
Пример #17
0
    def get(self, object_identity):
        handler = self._get_handler('get')

        return handler.get(ObjectType(object_identity))
Пример #18
0
    def set(self, object_identity, value):
        handler = self._get_handler('set')

        return handler._command(handler.cmd_gen.setCmd,
                                ObjectType(object_identity, value))