예제 #1
0
    def init_snmp_engine(self):
        # each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        # config.addTransport(self._snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode())
        config.addSocketTransport(self._snmpEngine, udp.domainName,
                                  udp.UdpTransport().openServerMode(('', self.port)))

        # SecurityName <-> CommunityName mapping.
        # config.addV1System(self._snmpEngine, 'my-area', 'public')

        # Allow read MIB access for this user / securityModels at VACM
        # config.addVacmUser(self._snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1, 3, 6))

        # ===== SNMP v2c =====
        # SecurityName <-> CommunityName mapping
        config.addV1System(self._snmpEngine, "public-v1-sec", "public")
        config.addVacmUser(self._snmpEngine, 2, 'public-v1-sec', 'noAuthNoPriv', (1, 3, 6))

        # ===== SNMP v3 support =====
        config.addV3User(self._snmpEngine, 'user1', config.usmHMACMD5AuthProtocol, 'authkey1')
        config.addVacmUser(self._snmpEngine, 3, 'user1', 'authNoPriv', (1, 3, 6))

        # each app has one or more contexts
        self._snmpContext = context.SnmpContext(self._snmpEngine)
예제 #2
0
 def cfgNtfOrg(self, authData, transportTarget, notifyType, tagList):
     addrName, paramsName = self.cfgCmdGen(
         authData, transportTarget, tagList
         )
     k = paramsName, tagList, notifyType
     if self.__knownNotifyNames.has_key(k):
         notifyName, _ = self.__knownNotifyNames[k]
     else:
         notifyName = 'n%s' % cmdgen.nextID()
         config.addNotificationTarget(
             self.snmpEngine,
             notifyName,
             paramsName,
             tagList,
             notifyType
             )
         self.__knownNotifyNames[k] = notifyName, paramsName
     if not self.__knownAuths.has_key(authData):
         subTree = (1,3,6)
         config.addTrapUser(
             self.snmpEngine,
             authData.securityModel,
             authData.securityName,
             authData.securityLevel,
             subTree
             )
         self.__knownAuths[authData] = subTree
     if self.snmpContext is None:
         self.snmpContext = context.SnmpContext(self.snmpEngine)
         config.addContext(
             self.snmpEngine, ''  # this is leaky
         )
     return notifyName
예제 #3
0
파일: ntforg.py 프로젝트: ithek/pysnmp
 def cfgNtfOrg(self, authData, transportTarget, notifyType):
     addrName, paramsName = self.cfgCmdGen(authData, transportTarget)
     tagList = transportTarget.tagList.split()
     if not tagList:
         tagList = ['']
     for tag in tagList:
         k = paramsName, tag, notifyType
         if k in self.__knownNotifyNames:
             notifyName, _ = self.__knownNotifyNames[k]
         else:
             notifyName = 'n%s' % nextID()
             config.addNotificationTarget(self.snmpEngine, notifyName,
                                          paramsName, tag, notifyType)
             self.__knownNotifyNames[k] = notifyName, paramsName
     k = (authData.securityModel, authData.securityName,
          authData.securityLevel)
     if k not in self.__knownAuths:
         subTree = (1, 3, 6)
         config.addTrapUser(self.snmpEngine, authData.securityModel,
                            authData.securityName, authData.securityLevel,
                            subTree)
         self.__knownAuths[k] = subTree
     if self.snmpContext is None:
         self.snmpContext = context.SnmpContext(self.snmpEngine)
         config.addContext(
             self.snmpEngine,
             ''  # this is leaky
         )
     return notifyName
예제 #4
0
    def run(self) -> None:
        self.snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(
            self.snmpEngine,
            udp.domainName,
            udp.UdpTransport().openServerMode(('127.0.0.1', 1161))
        )

        config.addV1System(self.snmpEngine, 'my-area', 'public', contextName='my-context')

        config.addVacmUser(self.snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1, 3, 6), (1, 3, 6))

        snmpContext = context.SnmpContext(self.snmpEngine)

        class SimpleController(instrum.AbstractMibInstrumController):
            def readVars(self, varBinds, acInfo=(None, None)):
                return [(ov[0], v2c.Integer(random.uniform(120, 140))) for ov in varBinds]

        snmpContext.registerContextName(
            v2c.OctetString('my-context'),  # Context Name
            SimpleController()  # Management Instrumentation
        )

        cmdrsp.GetCommandResponder(self.snmpEngine, snmpContext)
        # cmdrsp.SetCommandResponder(self.snmpEngine, snmpContext)

        self.snmpEngine.transportDispatcher.jobStarted(1)

        try:
            self.snmpEngine.transportDispatcher.runDispatcher()
        except:
            self.snmpEngine.transportDispatcher.closeDispatcher()
            raise
    def __init__(self, mibObjects):
        """
        mibObjects - a list of MibObject tuples that this agent
        will serve
        """

        #each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        #open a UDP socket on port 161 to listen for snmp requests
        config.addSocketTransport(self._snmpEngine, udp.domainName,
                                  udp.UdpTransport().openServerMode(('', 161)))

        #Here we configure two distinct Community Strings to control read and write
		#operations. public --> Read only, private --> Read/Write 
        config.addV1System(self._snmpEngine, "agent", "public")
        config.addV1System(self._snmpEngine, 'my-write-area', 'private')
        
        #let anyone accessing 'public' read anything in the subtree below,
        #which is the enterprises subtree that we defined our MIB to be in
        config.addVacmUser(self._snmpEngine, 2, "agent", "noAuthNoPriv",
                           readSubTree=(1,3,6,1,4,1))

        #let anyone accessing 'private' read and write anything in the subtree below,
        #which is the enterprises subtree that we defined our MIB to be in
        config.addVacmUser(self._snmpEngine, 2, 'my-write-area', 'noAuthNoPriv', readSubTree=(1, 3, 6, 1, 4, 1), writeSubTree=(1, 3, 6, 1, 4, 1))

        #Create Agent context
        self._snmpContext = context.SnmpContext(self._snmpEngine)

        #the builder is used to load mibs. tell it to look in the
        #current directory for our new MIB. We'll also use it to
        #export our symbols later
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'),)
        mibBuilder.setMibSources(*mibSources)
        
        MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI',
                                                      'MibScalarInstance')
        #export our custom mib
        for mibObject in mibObjects:
            nextVar, = mibBuilder.importSymbols(mibObject.mibName,
                                                mibObject.objectType)
            instance = createVariable(MibScalarInstance,
                                      mibObject.valueFunc,
                                      mibObject.valueSetFunc,
                                      nextVar.name, (0,),
                                      nextVar.syntax)
            #need to export as <var name>Instance
            instanceDict = {str(nextVar.name)+"Instance":instance}
            mibBuilder.exportSymbols(mibObject.mibName,
                                     **instanceDict)

        # tell pysnmp to respond to get, set, getnext, and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine,self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #6
0
    def __init__(self, host, port, log_queue):
        self.log_queue = log_queue
        # Create SNMP engine
        self.snmpEngine = engine.SnmpEngine()
        # Transport setup

        udp_sock = gevent.socket.socket(gevent.socket.AF_INET, gevent.socket.SOCK_DGRAM)
        udp_sock.setsockopt(gevent.socket.SOL_SOCKET, gevent.socket.SO_BROADCAST, 1)
        udp_sock.bind((host, port))
        # UDP over IPv4
        self.addSocketTransport(
            self.snmpEngine,
            udp.domainName,
            udp_sock
        )

        #SNMPv1
        config.addV1System(self.snmpEngine, 'public-read', 'public')

        # SNMPv3/USM setup
        # user: usr-md5-des, auth: MD5, priv DES
        config.addV3User(
            self.snmpEngine, 'usr-md5-des',
            config.usmHMACMD5AuthProtocol, 'authkey1',
            config.usmDESPrivProtocol, 'privkey1'
        )
        # user: usr-sha-none, auth: SHA, priv NONE
        config.addV3User(
            self.snmpEngine, 'usr-sha-none',
            config.usmHMACSHAAuthProtocol, 'authkey1'
        )
        # user: usr-sha-aes128, auth: SHA, priv AES/128
        config.addV3User(
            self.snmpEngine, 'usr-sha-aes128',
            config.usmHMACSHAAuthProtocol, 'authkey1',
            config.usmAesCfb128Protocol, 'privkey1'
        )

        # Allow full MIB access for each user at VACM
        config.addVacmUser(self.snmpEngine, 1, 'public-read', 'noAuthNoPriv',
                           (1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine, 3, 'usr-md5-des', 'authPriv',
                           (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine, 3, 'usr-sha-none', 'authNoPriv',
                           (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine, 3, 'usr-sha-aes128', 'authPriv',
                           (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))

        # Get default SNMP context this SNMP engine serves
        snmpContext = context.SnmpContext(self.snmpEngine)

        # Register SNMP Applications at the SNMP engine for particular SNMP context
        cmdrsp.GetCommandResponder(self.snmpEngine, snmpContext)
        cmdrsp.SetCommandResponder(self.snmpEngine, snmpContext)
        cmdrsp.NextCommandResponder(self.snmpEngine, snmpContext)
        cmdrsp.BulkCommandResponder(self.snmpEngine, snmpContext)
예제 #7
0
    def __init__(self, host, port, users, naming_scheme):
        """
        host = public ip to listen on
        port = port to listen on (usually 161)
        users = list of ('username', 'password', 'privatekey', 'authPriv') #authentication method for snmp v3
        if users is None, authentication will be snmp v1 public community string, read only
        """
        self.naming_scheme = naming_scheme

        self.run = True
        self.users = users
        # Create SNMP engine
        self.snmpEngine = engine.SnmpEngine()
        # Get default SNMP context this SNMP engine serves
        self.snmpContext = context.SnmpContext(self.snmpEngine)
        # MIB builder
        self.mibBuilder = self.snmpContext.getMibInstrum().getMibBuilder()
        self.MibScalar, self.MibScalarInstance = self.mibBuilder.importSymbols(
            'SNMPv2-SMI', 'MibScalar', 'MibScalarInstance')

        # Transport setup
        # UDP over IPv4
        try:
            config.addSocketTransport(
                self.snmpEngine, udp.domainName,
                udp.UdpTransport().openServerMode((host, port)))
            print('Serving on port %s' % port)
        except error.CarrierError as carrier_error:
            if "[Errno 98]" in carrier_error.message:
                raise RuntimeError('Port %s is in use' % port)

        # SNMPv3/USM setup
        # user: usr-md5-des, auth: MD5, priv DES
        if users:
            for user in users:
                self._add_v3_md5_des_user(user)
                # Allow full MIB access for each user at VACM
        else:
            # SNMPv1 public community string setup
            config.addV1System(self.snmpEngine, 'my-read-area', 'public')

        self._add_user_permission(
            "1.3.6.1.2.1"
        )  #full walk permission, without this snmpwalk returns None

        # Overwrite default strings with custom name
        sysDescr, = self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
            'SNMPv2-MIB', 'sysDescr')
        sysDescr = self.MibScalarInstance(
            sysDescr.name, (0, ),
            sysDescr.syntax.clone(
                "PySNMP engine - OVS 1.2.0 SNMP Agent"))  # Get from config?
        self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.exportSymbols(
            'SNMPv2-MIB', sysDescr)
        self._add_user_permission(self.naming_scheme.replace('.%s', ''))
예제 #8
0
 def __init__(self, host, port, rcommunity):
     self.snmpEngine = engine.SnmpEngine()
     config.addSocketTransport(self.snmpEngine, udp.domainName, udp.UdpTransport().openServerMode((host, port)))
     config.addV1System(self.snmpEngine, 'my-area', rcommunity)
     config.addVacmUser(self.snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1, 3, 6))
     self.snmpContext = context.SnmpContext(self.snmpEngine)
     self.mibBuilder = self.snmpContext.getMibInstrum().getMibBuilder()
     self.MibScalar, self.MibScalarInstance = self.mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalar', 'MibScalarInstance')
     cmdrsp.GetCommandResponder(self.snmpEngine, self.snmpContext)
     cmdrsp.NextCommandResponder(self.snmpEngine, self.snmpContext)
     cmdrsp.BulkCommandResponder(self.snmpEngine, self.snmpContext)
예제 #9
0
    def __init__(self, mibObjects):
        """
        mibObjects - a list of MibObject tuples that this agent
        will serve
        """

        #each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        #open a UDP socket to listen for snmp requests
        config.addSocketTransport(self._snmpEngine, udp.domainName,
                                  udp.UdpTransport().openServerMode(('', 161)))

        #add a v2 user with the community string public
        config.addV1System(self._snmpEngine, "agent", "public")
        #let anyone accessing 'public' read anything in the subtree below,
        #which is the enterprises subtree that we defined our MIB to be in
        config.addVacmUser(self._snmpEngine,
                           2,
                           "agent",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 4, 1))

        #each app has one or more contexts
        self._snmpContext = context.SnmpContext(self._snmpEngine)

        #the builder is used to load mibs. tell it to look in the
        #current directory for our new MIB. We'll also use it to
        #export our symbols later
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'), )
        mibBuilder.setMibSources(*mibSources)

        mibBuilder.loadModules('HOST-RESOURCES-MIB')

        #our variables will subclass this since we only have scalar types
        #can't load this type directly, need to import it
        MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI',
                                                      'MibScalarInstance')
        #export our custom mib
        for mibObject in mibObjects:
            nextVar, = mibBuilder.importSymbols(mibObject.mibName,
                                                mibObject.objectType)
            instance = createVariable(MibScalarInstance, mibObject.valueFunc,
                                      nextVar.name, (0, ), nextVar.syntax)
            #need to export as <var name>Instance
            instanceDict = {str(nextVar.name) + "Instance": instance}
            mibBuilder.exportSymbols(mibObject.mibName, **instanceDict)

        # tell pysnmp to respotd to get, getnext, and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #10
0
파일: ntforg.py 프로젝트: 4sp1r3/pysnmp
    def __init__(self, snmpEngine=None, snmpContext=None):
        if snmpEngine is None:
            self.snmpEngine = snmpEngine = SnmpEngine()
        else:
            self.snmpEngine = snmpEngine

        if snmpContext is None:
            self.snmpContext = context.SnmpContext(self.snmpEngine)
            config.addContext(
                self.snmpEngine, ''  # this is leaky
            )
        else:
            self.snmpContext = snmpContext

        self.mibViewController = self.vbProcessor.getMibViewController(self.snmpEngine)
예제 #11
0
    def __init__(self, snmpEngine=None, snmpContext=None):
        cmdgen.AsynCommandGenerator.__init__(self, snmpEngine)
        self.__asyncNtfOrg = AsyncNotificationOriginator()

        # grab/create MibViewController from/for the real AsyncCommandGen
        cache = self.__asyncNtfOrg._getCmdCache(self.snmpEngine)
        self.mibViewController = cache['mibViewController']

        if snmpContext is None:
            self.snmpContext = context.SnmpContext(self.snmpEngine)
            config.addContext(
                self.snmpEngine,
                ''  # this is leaky
            )
        else:
            self.snmpContext = snmpContext
예제 #12
0
    def __init__(self, host, port, mibObjects):
        self._snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(
            self._snmpEngine, udp.domainName,
            udp.UdpTransport().openServerMode((host, port)))

        config.addV1System(self._snmpEngine, "agent", "publick")  # password
        config.addV1System(self._snmpEngine, 'my-write-area', 'private')

        config.addVacmUser(self._snmpEngine,
                           2,
                           "agent",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 4, 1))

        config.addVacmUser(self._snmpEngine,
                           2,
                           'my-write-area',
                           'noAuthNoPriv',
                           readSubTree=(1, 3, 6, 1, 4, 1),
                           writeSubTree=(1, 3, 6, 1, 4, 1))

        self._snmpContext = context.SnmpContext(self._snmpEngine)

        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'), )
        mibBuilder.setMibSources(*mibSources)

        MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI',
                                                      'MibScalarInstance')
        for mibObject in mibObjects:
            nextVar, = mibBuilder.importSymbols(mibObject.mibName,
                                                mibObject.objectType)
            instance = createVariable(MibScalarInstance, mibObject.valueFunc,
                                      mibObject.valueSetFunc, nextVar.name,
                                      (0, ), nextVar.syntax)

            instanceDict = {str(nextVar.name) + "Instance": instance}
            mibBuilder.exportSymbols(mibObject.mibName, **instanceDict)

        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #13
0
def setMibController(snmpEngine, controller):
    """Register SNMP MIB instrumentation controller with SNMP engine.

    Args:
        snmpEngine (object): pysnmp `SnmpEngine` class instance
        controller (object): SNMP MIB instrumentation controller compliant to pysnmp
            MIB instrumentation API.

    Returns:
        object: pysnmp `SnmpContext` object representing SNMP context for which
            SNMP MIB instrumentation controller is registered.
    """
    snmpContextName = v2c.OctetString('')

    # https://github.com/openstack/virtualpdu/blob/master/virtualpdu/pdu/pysnmp_handler.py
    snmpContext = context.SnmpContext(snmpEngine)
    snmpContext.unregisterContextName(snmpContextName)
    snmpContext.registerContextName(snmpContextName, controller)

    return snmpContext
예제 #14
0
    def __init__(self, mibObjects):
        # Each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        # Open a UDP socket to listen for snmp requests (requset sudo command)
        config.addSocketTransport(self._snmpEngine, udp.domainName,
                                  udp.UdpTransport().openServerMode(('', 161)))
        config.addV1System(self._snmpEngine, 'agent', 'public')
        # add a v2 user with the community string public
        config.addVacmUser(self._snmpEngine,
                           2,
                           'agent',
                           'noAuthNoPriv',
                           readSubTree=(1, 3, 6, 1, 4, 1),
                           writeSubTree=(1, 3, 6, 1, 4, 1))
        # each app has one or more contexts
        self._snmpContext = context.SnmpContext(self._snmpEngine)
        # the builder is used to load mibs. tell it to look in the
        # current directory for our new MIB. We'll also use it to
        # export our symbols later
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'), )
        mibBuilder.setMibSources(*mibSources)
        # our variables will subclass this since we only have scalar types
        # can't load this type directly, need to import it
        (MibTable, MibTableRow, MibTableColumn,
         MibScalarInstance) = mibBuilder.importSymbols('SNMPv2-SMI',
                                                       'MibTable',
                                                       'MibTableRow',
                                                       'MibTableColumn',
                                                       'MibScalarInstance')
        # import and maintain Table
        maintaintable = maintainTableThread(0, mibObjects, mibBuilder,
                                            MibScalarInstance)
        maintaintable.start()
        # tell pysnmp to respotd to get, getnext, and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #15
0
    def run(self):
        snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(
            snmpEngine,
            udp.domainName,
            udp.UdpTransport().openServerMode(('127.0.0.1',
                                               self.__listening_port))
        )

        config.addV1System(
                     snmpEngine, 'my-area', 'public', contextName='my-context')

        config.addVacmUser(snmpEngine=snmpEngine,
                           securityModel=2,
                           securityName='my-area',
                           securityLevel='noAuthNoPriv',
                           readSubTree=SNMPAgentResponder.OID_PREFIX,
                           writeSubTree=(),
                           notifySubTree=())

        snmpContext = context.SnmpContext(snmpEngine)

        snmpContext.registerContextName(
            v2c.OctetString('my-context'),         # Context Name
            self.__responder                       # Management Instrumentation
        )

        cmdrsp.GetCommandResponder(snmpEngine, snmpContext)

        snmpEngine.transportDispatcher.jobStarted(1)
        self.__barrier.wait()

        # TODO with statement here!
        try:
            snmpEngine.transportDispatcher.runDispatcher()
        except:
            snmpEngine.transportDispatcher.closeDispatcher()
            raise
예제 #16
0
    def __init__(self, objects):

        self._snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(
            self._snmpEngine, udp.domainName,
            udp.UdpTransport().openServerMode((_addr, _port)))
        config.addV3User(self._snmpEngine, _account,
                         config.usmHMACMD5AuthProtocol, _auth_key,
                         config.usmDESPrivProtocol, _priv_key)
        config.addVacmUser(self._snmpEngine, 3, _account, "authPriv",
                           (1, 3, 6, 1, 4, 1), (1, 3, 6, 1, 4, 1))

        self._snmpContext = context.SnmpContext(self._snmpEngine)

        #builder create
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (
            builder.DirMibSource('.'), ) + (builder.DirMibSource(filepath), )
        mibBuilder.setMibSources(*mibSources)

        MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI',
                                                      'MibScalarInstance')

        for mibObject in objects:
            nextVar, = mibBuilder.importSymbols(mibObject.mibName,
                                                mibObject.objectType)
            instance = createVariable(MibScalarInstance,
                                      mibObject.valueGetFunc, nextVar.name,
                                      (0, ), nextVar.syntax)
            #need to export as <var name>Instance
            instanceDict = {str(nextVar.name) + "Instance": instance}
            mibBuilder.exportSymbols(mibObject.mibName, **instanceDict)

        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #17
0
    def __init__(self, array_config, access_config, engine_id=None,
                 transport_dispatcher=None):
        self.array_config = array_config
        self.access_config = access_config
        self.port = (int(array_config.agent_port) if array_config.agent_port
                     else 161)
        self.ip = (array_config.agent_ip if array_config.agent_ip
                   else '0.0.0.0')
        self.engine_id = engine_id
        self.transport_dispatcher = (dispatch.AsyncoreDispatcher()
                                     if transport_dispatcher is None
                                     else transport_dispatcher)

        self.engine = engine.SnmpEngine()
        self.context = context.SnmpContext(self.engine)

        self.setup_transport()
        self.setup_access()
        self.engine.unity_client = self.connect_backend_device()
        self.engine.parent = self
        self.create_managed_objects()
        self.register_cmd_responders()
        self.enable_observer()
# UDP over IPv4
config.addTransport(snmpEngine, udp.domainName,
                    udp.UdpTransport().openServerMode(('127.0.0.1', 161)))

# SNMPv3/USM setup

# user: usr-md5-none, auth: MD5, priv NONE
config.addV3User(snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol,
                 'authkey1')

# Allow full MIB access for each user at VACM
config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv',
                   (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))

# Create an SNMP context with ContextEngineId = 8000000001020304
snmpContext = context.SnmpContext(
    snmpEngine, contextEngineId=v2c.OctetString(hexValue='8000000001020304'))

# Create an [empty] set of Managed Objects (MibBuilder), pass it to
# Management Instrumentation Controller and register at SNMP Context
# under ContextName 'my-context'
snmpContext.registerContextName(
    v2c.OctetString('my-context'),  # Context Name
    instrum.MibInstrumController(builder.MibBuilder())  # Managed Objects
)

# Register SNMP Applications at the SNMP engine for particular SNMP context
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
예제 #19
0
# UDP over IPv4
config.addTransport(snmpEngine, udp.domainName,
                    udp.UdpTransport().openServerMode(('127.0.0.1', 161)))

# SNMPv3/USM setup

# user: usr-md5-none, auth: MD5, priv NONE
config.addV3User(snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol,
                 'authkey1')

# Allow full MIB access for each user at VACM
config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv',
                   (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))

# Create an SNMP context with default ContextEngineId (same as SNMP engine ID)
snmpContext = context.SnmpContext(snmpEngine)

# Create multiple independent trees of MIB managed objects (empty so far)
mibTreeA = instrum.MibInstrumController(builder.MibBuilder())
mibTreeB = instrum.MibInstrumController(builder.MibBuilder())

# Register MIB trees at distinct SNMP Context names
snmpContext.registerContextName(v2c.OctetString('context-a'), mibTreeA)
snmpContext.registerContextName(v2c.OctetString('context-b'), mibTreeB)

# Register SNMP Applications at the SNMP engine for particular SNMP context
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
예제 #20
0
파일: main.py 프로젝트: rema7/pysnmp
    def __init__(self, mibObjects):
        self._snmpEngine = engine.SnmpEngine()

        # open a UDP socket to listen for snmp requests
        config.addSocketTransport(
            self._snmpEngine, udp.domainName,
            udp.UdpTransport().openServerMode(('', 7757)))

        # add a v2 user with the community string public
        config.addV1System(self._snmpEngine, "agent", "public")
        # let anyone accessing 'public' read anything in the subtree below,
        # which is the enterprises subtree that we defined our MIB to be in
        config.addVacmUser(self._snmpEngine,
                           2,
                           "agent",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 4, 1))

        # each app has one or more contexts
        self._snmpContext = context.SnmpContext(self._snmpEngine)

        # the builder is used to load mibs. tell it to look in the
        # current directory for our new MIB. We'll also use it to
        # export our symbols later
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'), )
        mibBuilder.setMibSources(*mibSources)

        # our variables will subclass this since we only have scalar types
        # can't load this type directly, need to import it
        MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI', 'MibTable')

        mib = Mib()

        (nodeEntry, profileEntry, nodeIdxColumn, profileIdxColumn, dcdColumn,
         profileNameColumn) = mibBuilder.importSymbols('AKSION-CONTROL-MIB',
                                                       'nodeEntry',
                                                       'profileEntry',
                                                       'nodeIdx', 'profileIdx',
                                                       'dcd', 'profileName')
        rowInstanceId = nodeEntry.getInstIdFromIndices(1)
        mibInstrumentation = self._snmpContext.getMibInstrum()
        mibInstrumentation.writeVars(
            ((dcdColumn.name + rowInstanceId, 'xx1'), ))

        rowProfileInstanceId = profileEntry.getInstIdFromIndices(1)
        mibInstrumentation = self._snmpContext.getMibInstrum()
        mibInstrumentation.writeVars(
            ((profileNameColumn.name + rowInstanceId + rowProfileInstanceId,
              'ProfileNode1'), ))

        #
        rowInstanceId = nodeEntry.getInstIdFromIndices(2)
        mibInstrumentation = self._snmpContext.getMibInstrum()
        mibInstrumentation.writeVars(
            ((dcdColumn.name + rowInstanceId, 'xx 2'), ))

        rowProfileInstanceId = profileEntry.getInstIdFromIndices(2)
        mibInstrumentation = self._snmpContext.getMibInstrum()
        mibInstrumentation.writeVars(
            ((profileNameColumn.name + rowInstanceId + rowProfileInstanceId,
              'ProfileNode2'), ))

        # tell pysnmp to respotd to get, getnext, and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #21
0
    def _setup(self, q):
        """Setup a new agent in a separate process.

        The port the agent is listening too will be returned using the
        provided queue.
        """
        port = random.randrange(22000, 22989)
        snmpEngine = engine.SnmpEngine()
        if self.ipv6:
            config.addSocketTransport(
                snmpEngine, udp6.domainName,
                udp6.Udp6Transport().openServerMode(('::1', port)))
        else:
            config.addSocketTransport(
                snmpEngine, udp.domainName,
                udp.UdpTransport().openServerMode(('127.0.0.1', port)))
        # Community is public and MIB is writable
        config.addV1System(snmpEngine, 'read-write', 'public')
        config.addVacmUser(snmpEngine, 1, 'read-write', 'noAuthNoPriv',
                           (1, 3, 6), (1, 3, 6))
        config.addVacmUser(snmpEngine, 2, 'read-write', 'noAuthNoPriv',
                           (1, 3, 6), (1, 3, 6))
        config.addV3User(snmpEngine, 'read-write',
                         config.usmHMACMD5AuthProtocol, 'authpass',
                         config.usmAesCfb128Protocol, 'privpass')
        config.addVacmUser(snmpEngine, 3, 'read-write', 'authPriv', (1, 3, 6),
                           (1, 3, 6))

        # Build MIB
        def stringToOid(string):
            return [ord(x) for x in string]

        def flatten(*args):
            result = []
            for el in args:
                if isinstance(el, (list, tuple)):
                    for sub in el:
                        result.append(sub)
                else:
                    result.append(el)
            return tuple(result)

        snmpContext = context.SnmpContext(snmpEngine)
        mibBuilder = snmpContext.getMibInstrum().getMibBuilder()
        (MibTable, MibTableRow, MibTableColumn,
         MibScalar, MibScalarInstance) = mibBuilder.importSymbols(
             'SNMPv2-SMI', 'MibTable', 'MibTableRow', 'MibTableColumn',
             'MibScalar', 'MibScalarInstance')
        mibBuilder.exportSymbols(
            '__MY_SNMPv2_MIB',
            # SNMPv2-MIB::sysDescr
            MibScalar((1, 3, 6, 1, 2, 1, 1, 1), v2c.OctetString()),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 1, 1), (0, ),
                              v2c.OctetString("Snimpy Test Agent")))
        mibBuilder.exportSymbols(
            '__MY_IF_MIB',
            # IF-MIB::ifNumber
            MibScalar((1, 3, 6, 1, 2, 1, 2, 1), v2c.Integer()),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 1), (0, ), v2c.Integer(3)),
            # IF-MIB::ifTable
            MibTable((1, 3, 6, 1, 2, 1, 2, 2)),
            MibTableRow((1, 3, 6, 1, 2, 1, 2, 2, 1)).setIndexNames(
                (0, '__MY_IF_MIB', 'ifIndex')),
            # IF-MIB::ifIndex
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (1, ),
                              v2c.Integer(1)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (2, ),
                              v2c.Integer(2)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (3, ),
                              v2c.Integer(3)),
            # IF-MIB::ifDescr
            MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), v2c.OctetString()),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (1, ),
                              v2c.OctetString("lo")),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (2, ),
                              v2c.OctetString("eth0")),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (3, ),
                              v2c.OctetString("eth1")),
            # IF-MIB::ifType
            MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), v2c.Integer()),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (1, ),
                              v2c.Integer(24)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (2, ),
                              v2c.Integer(6)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (3, ),
                              v2c.Integer(6)),
            # IF-MIB::ifIndex
            ifIndex=MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 1),
                                   v2c.Integer()))
        mibBuilder.exportSymbols(
            '__MY_SNIMPY-MIB',
            # SNIMPY-MIB::snimpyIpAddress
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 1),
                      v2c.OctetString()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 1), (0, ),
                              v2c.OctetString("AAAA")),
            # SNIMPY-MIB::snimpyString
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 2),
                      v2c.OctetString()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 2), (0, ),
                              v2c.OctetString("bye")),
            # SNIMPY-MIB::snimpyInteger
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 3),
                      v2c.Integer()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 3), (0, ),
                              v2c.Integer(19)),
            # SNIMPY-MIB::snimpyEnum
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 4),
                      v2c.Integer()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 4), (0, ),
                              v2c.Integer(2)),
            # SNIMPY-MIB::snimpyObjectId
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 5),
                      v2c.ObjectIdentifier()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 5), (0, ),
                              v2c.ObjectIdentifier((1, 3, 6, 4454, 0, 0))),
            # SNIMPY-MIB::snimpyBoolean
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 6),
                      v2c.Integer()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 6), (0, ),
                              v2c.Integer(1)),
            # SNIMPY-MIB::snimpyCounter
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 7),
                      v2c.Counter32()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 7), (0, ),
                              v2c.Counter32(47)),
            # SNIMPY-MIB::snimpyGauge
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 8),
                      v2c.Gauge32()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 8), (0, ),
                              v2c.Gauge32(18)),
            # SNIMPY-MIB::snimpyTimeticks
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 9),
                      v2c.TimeTicks()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 9), (0, ),
                              v2c.TimeTicks(12111100)),
            # SNIMPY-MIB::snimpyCounter64
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 10),
                      v2c.Counter64()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 10), (0, ),
                              v2c.Counter64(2**48 + 3)),
            # SNIMPY-MIB::snimpyBits
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 11),
                      v2c.OctetString()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 11), (0, ),
                              v2c.OctetString(b"\xa0")),
            # SNIMPY-MIB::snimpyMacAddress
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 15),
                      v2c.OctetString()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 15), (0, ),
                              v2c.OctetString(b"\x11\x12\x13\x14\x15\x16")),
            # SNIMPY-MIB::snimpyMacAddressInvalid
            MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 16),
                      v2c.OctetString()).setMaxAccess("readwrite"),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 16), (0, ),
                              v2c.OctetString(b"\xf1\x12\x13\x14\x15\x16")),

            # SNIMPY-MIB::snimpyIndexTable
            MibTable((1, 3, 6, 1, 2, 1, 45121, 2, 3)),
            MibTableRow((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1)).setIndexNames(
                (0, "__MY_SNIMPY-MIB", "snimpyIndexVarLen"),
                (0, "__MY_SNIMPY-MIB", "snimpyIndexOidVarLen"),
                (0, "__MY_SNIMPY-MIB", "snimpyIndexFixedLen"),
                (1, "__MY_SNIMPY-MIB", "snimpyIndexImplied")),
            # SNIMPY-MIB::snimpyIndexInt
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6),
                              flatten(4, stringToOid('row1'), 3, 1, 2, 3,
                                      stringToOid('alpha5'),
                                      stringToOid('end of row1')),
                              v2c.Integer(4571)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6),
                              flatten(4, stringToOid('row2'), 4, 1, 0, 2, 3,
                                      stringToOid('beta32'),
                                      stringToOid('end of row2')),
                              v2c.Integer(78741)),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6),
                              flatten(4, stringToOid('row3'), 4, 120, 1, 2, 3,
                                      stringToOid('gamma7'),
                                      stringToOid('end of row3')),
                              v2c.Integer(4110)),

            # SNIMPY-MIB::snimpyInvalidTable
            MibTable((1, 3, 6, 1, 2, 1, 45121, 2, 5)),
            MibTableRow((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1)).setIndexNames(
                (0, "__MY_SNIMPY-MIB", "snimpyInvalidIndex")),
            # SNIMPY-MIB::snimpyInvalidDescr
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2), (1, ),
                              v2c.OctetString(b"Hello")),
            MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2), (2, ),
                              v2c.OctetString(b"\xf1\x12\x13\x14\x15\x16")),

            # Indexes
            snimpyIndexVarLen=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 1),
                v2c.OctetString()).setMaxAccess("noaccess"),
            snimpyIndexIntIndex=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 2),
                v2c.Integer()).setMaxAccess("noaccess"),
            snimpyIndexOidVarLen=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 3),
                v2c.ObjectIdentifier()).setMaxAccess("noaccess"),
            snimpyIndexFixedLen=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 4),
                v2c.OctetString().setFixedLength(6)).setMaxAccess("noaccess"),
            snimpyIndexImplied=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 5),
                v2c.OctetString()).setMaxAccess("noaccess"),
            snimpyIndexInt=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6),
                v2c.Integer()).setMaxAccess("readwrite"),
            snimpyInvalidIndex=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 1),
                v2c.Integer()).setMaxAccess("noaccess"),
            snimpyInvalidDescr=MibTableColumn(
                (1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2),
                v2c.OctetString()).setMaxAccess("readwrite"))
        # Start agent
        cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
        cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
        cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
        cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
        q.put(port)
        snmpEngine.transportDispatcher.jobStarted(1)
        snmpEngine.transportDispatcher.runDispatcher()
예제 #22
0
    def __init__(self, host, port, mibpaths):

        self.oid_mapping = {}
        self.databus_mediator = DatabusMediator(self.oid_mapping)
        # mapping between OID and databus keys

        # Create SNMP engine
        self.snmpEngine = engine.SnmpEngine()

        # path to custom mibs
        mibBuilder = self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
        mibSources = mibBuilder.getMibSources()

        for mibpath in mibpaths:
            mibSources += (builder.DirMibSource(mibpath), )
        mibBuilder.setMibSources(*mibSources)

        # Transport setup
        udp_sock = gevent.socket.socket(gevent.socket.AF_INET,
                                        gevent.socket.SOCK_DGRAM)
        udp_sock.setsockopt(gevent.socket.SOL_SOCKET,
                            gevent.socket.SO_BROADCAST, 1)
        udp_sock.bind((host, port))
        self.server_port = udp_sock.getsockname()[1]
        # UDP over IPv4
        self.addSocketTransport(self.snmpEngine, udp.domainName, udp_sock)

        # SNMPv1
        config.addV1System(self.snmpEngine, 'public-read', 'public')

        # SNMPv3/USM setup
        # user: usr-md5-des, auth: MD5, priv DES
        config.addV3User(self.snmpEngine, 'usr-md5-des',
                         config.usmHMACMD5AuthProtocol, 'authkey1',
                         config.usmDESPrivProtocol, 'privkey1')
        # user: usr-sha-none, auth: SHA, priv NONE
        config.addV3User(self.snmpEngine, 'usr-sha-none',
                         config.usmHMACSHAAuthProtocol, 'authkey1')
        # user: usr-sha-aes128, auth: SHA, priv AES/128
        config.addV3User(self.snmpEngine, 'usr-sha-aes128',
                         config.usmHMACSHAAuthProtocol, 'authkey1',
                         config.usmAesCfb128Protocol, 'privkey1')

        # Allow full MIB access for each user at VACM
        config.addVacmUser(self.snmpEngine,
                           1,
                           'public-read',
                           'noAuthNoPriv',
                           readSubTree=(1, 3, 6, 1, 2, 1),
                           writeSubTree=(1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine,
                           3,
                           'usr-md5-des',
                           'authPriv',
                           readSubTree=(1, 3, 6, 1, 2, 1),
                           writeSubTree=(1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine,
                           3,
                           'usr-sha-none',
                           'authNoPriv',
                           readSubTree=(1, 3, 6, 1, 2, 1),
                           writeSubTree=(1, 3, 6, 1, 2, 1))
        config.addVacmUser(self.snmpEngine,
                           3,
                           'usr-sha-aes128',
                           'authPriv',
                           readSubTree=(1, 3, 6, 1, 2, 1),
                           writeSubTree=(1, 3, 6, 1, 2, 1))

        # Get default SNMP context this SNMP engine serves
        snmpContext = context.SnmpContext(self.snmpEngine)

        # Register SNMP Applications at the SNMP engine for particular SNMP context
        self.resp_app_get = conpot_cmdrsp.c_GetCommandResponder(
            self.snmpEngine, snmpContext, self.databus_mediator)
        self.resp_app_set = conpot_cmdrsp.c_SetCommandResponder(
            self.snmpEngine, snmpContext, self.databus_mediator)
        self.resp_app_next = conpot_cmdrsp.c_NextCommandResponder(
            self.snmpEngine, snmpContext, self.databus_mediator)
        self.resp_app_bulk = conpot_cmdrsp.c_BulkCommandResponder(
            self.snmpEngine, snmpContext, self.databus_mediator)
예제 #23
0
파일: agent.py 프로젝트: notbrain/scalarizr
    def start(self):
        if self._engine is None:
            # Create SNMP engine with autogenernated engineID and pre-bound
            # to socket transport dispatcher
            self._engine = engine.SnmpEngine()

            # Setup UDP over IPv4 transport endpoint
        try:
            iface = ('0.0.0.0', self.port)
            self._logger.info("[pid: %d] Starting SNMP server on %s:%d",  os.getpid(), iface[0], iface[1])
            config.addSocketTransport(
            self._engine,
            udp.domainName,
            udp.UdpSocketTransport().openServerMode(iface)
            )
        except CarrierError:
            self._logger.error('Can\'t run SNMP agent on port %d: Address already in use', self.port)
            raise

        mibBuilder = self._engine.msgAndPduDsp.mibInstrumController.mibBuilder

        MibSources = mibBuilder.getMibPath()
        sources =  ['/mibs','/mibs/instances']
        for source in sources:
            MibSources += ((os.path.realpath(os.path.dirname(__file__) + source), ))
        apply(mibBuilder.setMibPath, MibSources)

        try:
            mibBuilder.loadModules(*self._modules)
        except SmiError:
            self._logger.warn('Can\'t load modules')
            raise

        config.addV1System(self._engine, self._security_name, self._community_name)

        # VACM setup
        config.addContext(self._engine, '')
        config.addRwUser(self._engine, 1, self._security_name, 'noAuthNoPriv', (1,3,6)) # v1
        config.addRwUser(self._engine, 2, self._security_name, 'noAuthNoPriv', (1,3,6)) # v2c

        # SNMP context
        snmpContext = context.SnmpContext(self._engine)
        # Apps registration
        cmdrsp.GetCommandResponder(self._engine, snmpContext)
        cmdrsp.SetCommandResponder(self._engine, snmpContext)
        cmdrsp.NextCommandResponder(self._engine, snmpContext)
        cmdrsp.BulkCommandResponder(self._engine, snmpContext)

        # Start server
        self._logger.debug('Starting transport dispatcher')
        self._engine.transportDispatcher.jobStarted(1)
        try:
            self._logger.debug('Run transport dispatcher')
            self._engine.transportDispatcher.runDispatcher()
        except select.error, e:
            if e.args[0] == 9:
                # 'Bad file descriptor'
                # Throws when dispatcher closed from another thread
                pass
            else:
                raise
예제 #24
0
    def __init__(self):

        #each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        # Reading configuration
        self._read_conf()

        self._serialtcp = SerialHTTPProcess(
            self._CONF['LOG_DIR'] if 'LOG_DIR' in self._CONF else '')

        #open a UDP socket to listen for snmp requests
        port = int(self._CONF['PORT']
                   ) if 'PORT' in self._CONF and self._CONF['PORT'] else 161
        config.addSocketTransport(
            self._snmpEngine, udp.domainName,
            udp.UdpTransport().openServerMode(('0.0.0.0', port)))

        #add a v2 user with the community string public
        config.addV1System(
            self._snmpEngine, "read-area", self._CONF['PUBLIC']
            if 'PUBLIC' in self._CONF and self._CONF['PUBLIC'] else "public")
        config.addV1System(
            self._snmpEngine, 'write-area', self._CONF['PRIVATE'] if
            'PRIVATE' in self._CONF and self._CONF['PRIVATE'] else 'private')

        #let anyone accessing 'public' read anything in the subtree below,
        #which is the enterprises subtree that we defined our MIB to be in
        config.addVacmUser(self._snmpEngine,
                           1,
                           "read-area",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 2))
        #config.addVacmUser(self._snmpEngine, 1, "read-area", "noAuthNoPriv",
        #                   readSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1))
        config.addVacmUser(self._snmpEngine,
                           1,
                           "read-area",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 4, 1, 332, 11))

        config.addVacmUser(self._snmpEngine,
                           2,
                           "read-area",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 2, 1, 10, 33))
        config.addVacmUser(self._snmpEngine,
                           2,
                           "read-area",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1))
        config.addVacmUser(self._snmpEngine,
                           2,
                           "read-area",
                           "noAuthNoPriv",
                           readSubTree=(1, 3, 6, 1, 4, 1, 332, 11))

        # Write Subtree
        log('before enable write-area')
        if self._CONF and 'ALLOW' in self._CONF and self._CONF['ALLOW'].lower(
        ) in 'true':
            log('Adding Write community with write-area')
            config.addVacmUser(self._snmpEngine,
                               1,
                               'write-area',
                               'noAuthNoPriv',
                               readSubTree=(1, 3, 6, 1, 2, 1, 10, 33),
                               writeSubTree=(1, 3, 6, 1, 2, 1, 10, 33))
            config.addVacmUser(self._snmpEngine,
                               2,
                               'write-area',
                               'noAuthNoPriv',
                               readSubTree=(1, 3, 6, 1, 2, 1, 10, 33),
                               writeSubTree=(1, 3, 6, 1, 2, 1, 10, 33))
            config.addVacmUser(self._snmpEngine,
                               1,
                               'write-area',
                               'noAuthNoPriv',
                               readSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1),
                               writeSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1))
            config.addVacmUser(self._snmpEngine,
                               2,
                               'write-area',
                               'noAuthNoPriv',
                               readSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1),
                               writeSubTree=(1, 3, 6, 1, 2, 1, 19, 2, 1))

        #each app has one or more contexts
        self._snmpContext = context.SnmpContext(self._snmpEngine)

        #the builder is used to load mibs. tell it to look in the
        #MIBS directory for our new MIB. We'll also use it to
        #export our symbols later
        mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        pub = path.join(getcwd(), 'PYSNMP_MIBS')
        priv = path.join(getcwd(), 'MIBSPY')
        mibSources = mibBuilder.getMibSources() + (
            builder.DirMibSource(pub), ) + (builder.DirMibSource(priv), )
        mibBuilder.setMibSources(*mibSources)

        #export our custom mib
        self._exportprivMIBS(mibBuilder)
        self._exportpubMIBS(mibBuilder)

        # tell pysnmp to respotd to get, getnext, set and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)
예제 #25
0
        except error.PySnmpError:
            self.handleResponsePdu(
                snmpEngine, stateReference, 'error', None, cbCtx
            )

    # SNMP response relay
    # noinspection PyUnusedLocal
    def handleResponsePdu(self, snmpEngine, sendRequestHandle,
                          errorIndication, PDU, cbCtx):
        stateReference, reqPDU = cbCtx

        if errorIndication:
            PDU = v2c.apiPDU.getResponse(reqPDU)
            PDU.setErrorStatus(PDU, 5)

        self.sendPdu(snmpEngine, stateReference, PDU)

        self.releaseStateInformation(stateReference)


CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))

snmpEngine.transportDispatcher.jobStarted(1)  # this job would never finish

# Run I/O dispatcher which would receive queries and send responses
try:
    snmpEngine.transportDispatcher.runDispatcher()

finally:
    snmpEngine.transportDispatcher.closeDispatcher()
# * in behalf of contextEngineId 0x8000000004030201, contextName ''
# * over IPv4/UDP
# * with TRAP ID 'warmStart' specified as a string OID
#
# Sending SNMPv3 Notification in behalf of non-default ContextEngineId
# requires having a collection of Managed Objects registered under
# the ContextEngineId being used.
#
from pysnmp.entity import engine
from pysnmp.entity.rfc3413 import context
from pysnmp.entity.rfc3413.oneliner import ntforg
from pysnmp.proto import rfc1902

snmpEngine = engine.SnmpEngine()
snmpContext = context.SnmpContext(
    snmpEngine,contextEngineId=rfc1902.OctetString(hexValue='8000000004030201')
)

ntfOrg = ntforg.NotificationOriginator(snmpEngine, snmpContext)

errorIndication, errorStatus, errorIndex, varBinds = ntfOrg.sendNotification(
    ntforg.UsmUserData('usr-md5-none', 'authkey1'),
    ntforg.UdpTransportTarget(('localhost', 162)),
    'inform',
    '1.3.6.1.6.3.1.1.5.2'
)

if errorIndication:
    print('Notification not sent: %s' % errorIndication)
elif errorStatus:
    print('Notification Receiver returned error: %s @%s' %
예제 #27
0
    def engine(self):
        """
        Setup SNMP engine and context
        """
        log = 'SNMP agent engine initialization sequence begun.  ' +\
              'This may take a minute or two.'
        logger.info(log)
        print(log)
        MPQ_ACT.put_nowait([datetime.now().isoformat(' '), 'INFO', log])

        # Create SNMP engine with auto generated engineID and pre-bound
        # to socket transport dispatcher
        self.eng_snmp = engine.SnmpEngine()

        # Transport setup

        # UDP over IPv4 at 0.0.0.0:8900
        config.addTransport(
            self.eng_snmp, udp.domainName,
            udp.UdpTransport().openServerMode(iface=('', 8900)))
        # UDP over IPv6 at [::]:8900
        config.addTransport(
            self.eng_snmp, udp6.domainName,
            udp6.Udp6Transport().openServerMode(iface=('::', 8900)))

        # SNMPv2c setup

        # SecurityName <-> CommunityName mapping.
        config.addV1System(snmpEngine=self.eng_snmp,
                           communityIndex='agent',
                           communityName='janusess')
        # Allow full MIB access for this user / securityModels at VACM
        # MIB 1.3.6.1.4.1.9934 refers to Janus Research Group
        # MIB 1.3.6.1.4.1.9934.0 refers to JanusESS Project
        config.addVacmUser(snmpEngine=self.eng_snmp,
                           securityModel=2,
                           securityName='agent',
                           securityLevel='noAuthNoPriv',
                           readSubTree=(1, 3, 6, 1, 4, 1, 9934, 0))

        # Get default SNMP context this SNMP engine serves
        self.ctx_snmp = context.SnmpContext(snmpEngine=self.eng_snmp)

        # Create custom Managed Object Instance
        self.mib_builder = self.ctx_snmp.getMibInstrum().getMibBuilder()
        mib_sources = self.mib_builder.getMibSources() + \
            (
                builder.DirMibSource('/opt/Janus/ESS/python3/server/snmp/mibs'),
            )
        self.mib_builder.setMibSources(*mib_sources)

        # JANUS-MIB defines and locates all Janus Research Group projects
        # JANUSESS-MIB defines all JanusESS project entries
        self.mib_builder.loadModules('JANUS-MIB', 'JANUSESS-MIB')

        self.config_base()
        self.config_lane()
        self.config_module()
        self.config_sensor()

        # Register SNMP Applications at the SNMP engine for particular SNMP context
        cmdrsp.GetCommandResponder(self.eng_snmp, self.ctx_snmp)
        cmdrsp.NextCommandResponder(self.eng_snmp, self.ctx_snmp)
        cmdrsp.BulkCommandResponder(self.eng_snmp, self.ctx_snmp)

        dispatcher = threading.Thread(target=self.dispatcher, args=())
        dispatcher.start()
        MPQ_STAT.put_nowait(['snmp_agent', dispatcher.ident])

        log = 'SNMP agent engine sequence concluded.'
        logger.info(log)
        MPQ_ACT.put_nowait([datetime.now().isoformat(' '), 'INFO', log])
        MPQ_STAT.put_nowait(['base', ['snmp_agent', STAT_LVL['op']]])

        log = 'SNMP agent listener started.'
        logger.info(log)
        print(log)
        MPQ_ACT.put_nowait([datetime.now().isoformat(' '), 'INFO', log])

        # Poll SNMP agent queues for values to update variables
        while True:
            if not MPQ_SNMPA_STOP.empty():
                MPQ_SNMPA_STOP.get()
                self.eng_snmp.transportDispatcher.closeDispatcher()
                break

            if not MPQ_SNMPA2.empty():
                mpq_record = MPQ_SNMPA2.get()
                self.base(mpq_record=mpq_record)

            if not MPQ_SNMPA3.empty():
                mpq_record = MPQ_SNMPA3.get()
                self.lane(mpq_record=mpq_record)

            if not MPQ_SNMPA4.empty():
                mpq_record = MPQ_SNMPA4.get()
                self.module(mpq_record=mpq_record)

            if not MPQ_SNMPA5.empty():
                mpq_record = MPQ_SNMPA5.get()
                self.sensor(mpq_record=mpq_record)

            time.sleep(0.1)

        MPQ_STAT.put_nowait(['snmp_agent', False])
        log = 'SNMP agent dispatcher stopped.'
        logger.info(log)
        MPQ_ACT.put_nowait([datetime.now().isoformat(' '), 'INFO', log])

        log = 'SNMP agent listener stopped.'
        logger.info(log)
        print(log)
        MPQ_ACT.put_nowait([datetime.now().isoformat(' '), 'INFO', log])
        MPQ_STAT.put_nowait(['base', ['snmp_agent', STAT_LVL['not_cfg']]])
예제 #28
0
def main():
    class CommandResponder(cmdrsp.CommandResponderBase):
        pduTypes = (rfc1905.SetRequestPDU.tagSet, rfc1905.GetRequestPDU.tagSet,
                    rfc1905.GetNextRequestPDU.tagSet,
                    rfc1905.GetBulkRequestPDU.tagSet)

        def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
                                pdu, acInfo):
            trunkReq = gCurrentRequestContext.copy()

            trunkReq['snmp-pdu'] = pdu

            pluginIdList = trunkReq['plugins-list']

            logCtx = LogString(trunkReq)

            reqCtx = {}

            for pluginNum, pluginId in enumerate(pluginIdList):

                st, pdu = pluginManager.processCommandRequest(
                    pluginId, snmpEngine, pdu, trunkReq, reqCtx)

                if st == status.BREAK:
                    log.debug('plugin %s inhibits other plugins' % pluginId,
                              ctx=logCtx)
                    pluginIdList = pluginIdList[:pluginNum]
                    break

                elif st == status.DROP:
                    log.debug(
                        'received SNMP message, plugin %s muted request' %
                        pluginId,
                        ctx=logCtx)
                    self.releaseStateInformation(stateReference)
                    return

                elif st == status.RESPOND:
                    log.debug(
                        'received SNMP message, plugin %s forced immediate response'
                        % pluginId,
                        ctx=logCtx)

                    try:
                        self.sendPdu(snmpEngine, stateReference, pdu)

                    except PySnmpError:
                        log.error('failure sending SNMP response', ctx=logCtx)

                    else:
                        self.releaseStateInformation(stateReference)

                    return

            # pass query to trunk

            trunkIdList = trunkReq['trunk-id-list']
            if trunkIdList is None:
                log.error('no route configured', ctx=logCtx)
                self.releaseStateInformation(stateReference)
                return

            for trunkId in trunkIdList:

                cbCtx = pluginIdList, trunkId, trunkReq, snmpEngine, stateReference, reqCtx

                try:
                    msgId = trunkingManager.sendReq(trunkId, trunkReq,
                                                    self.trunkCbFun, cbCtx)

                except SnmpfwdError:
                    log.error(
                        'received SNMP message, message not sent to trunk "%s"'
                        % sys.exc_info()[1],
                        ctx=logCtx)
                    return

                log.debug(
                    'received SNMP message, forwarded as trunk message #%s' %
                    msgId,
                    ctx=logCtx)

        def trunkCbFun(self, msgId, trunkRsp, cbCtx):
            pluginIdList, trunkId, trunkReq, snmpEngine, stateReference, reqCtx = cbCtx

            for key in tuple(trunkRsp):
                if key != 'callflow-id':
                    trunkRsp['client-' + key] = trunkRsp[key]
                    del trunkRsp[key]

            trunkRsp['callflow-id'] = trunkReq['callflow-id']

            logCtx = LogString(trunkRsp)

            if trunkRsp['client-error-indication']:
                log.info(
                    'received trunk message #%s, remote end reported error-indication "%s", NOT responding'
                    % (msgId, trunkRsp['client-error-indication']),
                    ctx=logCtx)

            elif 'client-snmp-pdu' not in trunkRsp:
                log.info(
                    'received trunk message #%s, remote end does not send SNMP PDU, NOT responding'
                    % msgId,
                    ctx=logCtx)

            else:
                pdu = trunkRsp['client-snmp-pdu']

                for pluginId in pluginIdList:
                    st, pdu = pluginManager.processCommandResponse(
                        pluginId, snmpEngine, pdu, trunkReq, reqCtx)

                    if st == status.BREAK:
                        log.debug('plugin %s inhibits other plugins' %
                                  pluginId,
                                  ctx=logCtx)
                        break
                    elif st == status.DROP:
                        log.debug('plugin %s muted response' % pluginId,
                                  ctx=logCtx)
                        self.releaseStateInformation(stateReference)
                        return

                try:
                    self.sendPdu(snmpEngine, stateReference, pdu)

                except PySnmpError:
                    log.error('failure sending SNMP response', ctx=logCtx)

                else:
                    log.debug(
                        'received trunk message #%s, forwarded as SNMP message'
                        % msgId,
                        ctx=logCtx)

            self.releaseStateInformation(stateReference)

    #
    # SNMPv3 NotificationReceiver implementation
    #

    class NotificationReceiver(ntfrcv.NotificationReceiver):
        pduTypes = (rfc1157.TrapPDU.tagSet, rfc1905.SNMPv2TrapPDU.tagSet)

        def processPdu(self, snmpEngine, messageProcessingModel, securityModel,
                       securityName, securityLevel, contextEngineId,
                       contextName, pduVersion, pdu, maxSizeResponseScopedPDU,
                       stateReference):

            trunkReq = gCurrentRequestContext.copy()

            if messageProcessingModel == 0:
                pdu = rfc2576.v1ToV2(pdu)

                # TODO: why this is not automatic?
                v2c.apiTrapPDU.setDefaults(pdu)

            trunkReq['snmp-pdu'] = pdu

            pluginIdList = trunkReq['plugins-list']

            logCtx = LogString(trunkReq)

            reqCtx = {}

            for pluginNum, pluginId in enumerate(pluginIdList):

                st, pdu = pluginManager.processNotificationRequest(
                    pluginId, snmpEngine, pdu, trunkReq, reqCtx)

                if st == status.BREAK:
                    log.debug('plugin %s inhibits other plugins' % pluginId,
                              ctx=logCtx)
                    pluginIdList = pluginIdList[:pluginNum]
                    break

                elif st == status.DROP:
                    log.debug('plugin %s muted request' % pluginId, ctx=logCtx)
                    return

                elif st == status.RESPOND:
                    log.debug('plugin %s NOT forced immediate response' %
                              pluginId,
                              ctx=logCtx)
                    # TODO: implement immediate response for confirmed-class PDU
                    return

            # pass query to trunk

            trunkIdList = trunkReq['trunk-id-list']
            if trunkIdList is None:
                log.error('no route configured', ctx=logCtx)
                return

            for trunkId in trunkIdList:

                # TODO: pass messageProcessingModel to respond
                cbCtx = pluginIdList, trunkId, trunkReq, snmpEngine, stateReference, reqCtx

                try:
                    msgId = trunkingManager.sendReq(trunkId, trunkReq,
                                                    self.trunkCbFun, cbCtx)

                except SnmpfwdError:
                    log.error(
                        'received SNMP message, message not sent to trunk "%s" %s'
                        % (trunkId, sys.exc_info()[1]),
                        ctx=logCtx)
                    return

                log.debug(
                    'received SNMP message, forwarded as trunk message #%s' %
                    msgId,
                    ctx=logCtx)

        def trunkCbFun(self, msgId, trunkRsp, cbCtx):
            pluginIdList, trunkId, trunkReq, snmpEngine, stateReference, reqCtx = cbCtx

            for key in tuple(trunkRsp):
                if key != 'callflow-id':
                    trunkRsp['client-' + key] = trunkRsp[key]
                    del trunkRsp[key]

            trunkRsp['callflow-id'] = trunkReq['callflow-id']

            logCtx = LazyLogString(trunkReq, trunkRsp)

            if trunkRsp['client-error-indication']:
                log.info(
                    'received trunk message #%s, remote end reported error-indication "%s", NOT responding'
                    % (msgId, trunkRsp['client-error-indication']),
                    ctx=logCtx)
            else:
                if 'client-snmp-pdu' not in trunkRsp:
                    log.debug(
                        'received trunk message #%s -- unconfirmed SNMP message'
                        % msgId,
                        ctx=logCtx)
                    return

                pdu = trunkRsp['client-snmp-pdu']

                for pluginId in pluginIdList:
                    st, pdu = pluginManager.processNotificationResponse(
                        pluginId, snmpEngine, pdu, trunkReq, reqCtx)

                    if st == status.BREAK:
                        log.debug('plugin %s inhibits other plugins' %
                                  pluginId,
                                  ctx=logCtx)
                        break
                    elif st == status.DROP:
                        log.debug(
                            'received trunk message #%s, plugin %s muted response'
                            % (msgId, pluginId),
                            ctx=logCtx)
                        return

                log.debug(
                    'received trunk message #%s, forwarded as SNMP message' %
                    msgId,
                    ctx=logCtx)

                # TODO: implement response part

                # # Agent-side API complies with SMIv2
                # if messageProcessingModel == 0:
                #     PDU = rfc2576.v2ToV1(PDU, origPdu)
                #
                # statusInformation = {}
                #
                # # 3.4.3
                # try:
                #     snmpEngine.msgAndPduDsp.returnResponsePdu(
                #         snmpEngine, messageProcessingModel, securityModel,
                #         securityName, securityLevel, contextEngineId,
                #         contextName, pduVersion, rspPDU, maxSizeResponseScopedPDU,
                #         stateReference, statusInformation)
                #
                # except error.StatusInformation:
                #         log.error('processPdu: stateReference %s, statusInformation %s' % (stateReference, sys.exc_info()[1]))

    class LogString(LazyLogString):

        GROUPINGS = [
            ['callflow-id'],
            [
                'snmp-engine-id', 'snmp-transport-domain', 'snmp-bind-address',
                'snmp-bind-port', 'snmp-security-model', 'snmp-security-level',
                'snmp-security-name', 'snmp-credentials-id'
            ],
            ['snmp-context-engine-id', 'snmp-context-name', 'snmp-context-id'],
            ['snmp-pdu', 'snmp-content-id'],
            ['snmp-peer-address', 'snmp-peer-port', 'snmp-peer-id'],
            ['trunk-id'],
            ['client-snmp-pdu'],
        ]

        FORMATTERS = {
            'client-snmp-pdu': LazyLogString.prettyVarBinds,
            'snmp-pdu': LazyLogString.prettyVarBinds,
        }

    def securityAuditObserver(snmpEngine, execpoint, variables, cbCtx):
        securityModel = variables.get('securityModel', 0)

        logMsg = 'SNMPv%s auth failure' % securityModel
        logMsg += ' at %s:%s' % variables['transportAddress'].getLocalAddress()
        logMsg += ' from %s:%s' % variables['transportAddress']

        statusInformation = variables.get('statusInformation', {})

        if securityModel in (1, 2):
            logMsg += ' using snmp-community-name "%s"' % statusInformation.get(
                'communityName', '?')
        elif securityModel == 3:
            logMsg += ' using snmp-usm-user "%s"' % statusInformation.get(
                'msgUserName', '?')

        try:
            logMsg += ': %s' % statusInformation['errorIndication']

        except KeyError:
            pass

        log.error(logMsg)

    def requestObserver(snmpEngine, execpoint, variables, cbCtx):

        trunkReq = {
            'callflow-id': '%10.10x' % random.randint(0, 0xffffffffff),
            'snmp-engine-id': snmpEngine.snmpEngineID,
            'snmp-transport-domain': variables['transportDomain'],
            'snmp-peer-address': variables['transportAddress'][0],
            'snmp-peer-port': variables['transportAddress'][1],
            'snmp-bind-address':
            variables['transportAddress'].getLocalAddress()[0],
            'snmp-bind-port':
            variables['transportAddress'].getLocalAddress()[1],
            'snmp-security-model': variables['securityModel'],
            'snmp-security-level': variables['securityLevel'],
            'snmp-security-name': variables['securityName'],
            'snmp-context-engine-id': variables['contextEngineId'],
            'snmp-context-name': variables['contextName'],
        }

        trunkReq['snmp-credentials-id'] = macro.expandMacro(
            credIdMap.get(
                (str(snmpEngine.snmpEngineID), variables['transportDomain'],
                 variables['securityModel'], variables['securityLevel'],
                 str(variables['securityName']))), trunkReq)

        k = '#'.join([
            str(x)
            for x in (variables['contextEngineId'], variables['contextName'])
        ])
        for x, y in contextIdList:
            if y.match(k):
                trunkReq['snmp-context-id'] = macro.expandMacro(x, trunkReq)
                break
            else:
                trunkReq['snmp-context-id'] = None

        addr = '%s:%s#%s:%s' % (
            variables['transportAddress'][0], variables['transportAddress'][1],
            variables['transportAddress'].getLocalAddress()[0],
            variables['transportAddress'].getLocalAddress()[1])

        for pat, peerId in peerIdMap.get(str(variables['transportDomain']),
                                         ()):
            if pat.match(addr):
                trunkReq['snmp-peer-id'] = macro.expandMacro(peerId, trunkReq)
                break
        else:
            trunkReq['snmp-peer-id'] = None

        pdu = variables['pdu']
        if pdu.tagSet == v1.TrapPDU.tagSet:
            pdu = rfc2576.v1ToV2(pdu)
            v2c.apiTrapPDU.setDefaults(pdu)

        k = '#'.join([
            snmpPduTypesMap.get(variables['pdu'].tagSet, '?'),
            '|'.join([str(x[0]) for x in v2c.apiTrapPDU.getVarBinds(pdu)])
        ])

        for x, y in contentIdList:
            if y.match(k):
                trunkReq['snmp-content-id'] = macro.expandMacro(x, trunkReq)
                break
            else:
                trunkReq['snmp-content-id'] = None

        trunkReq['plugins-list'] = pluginIdMap.get(
            (trunkReq['snmp-credentials-id'], trunkReq['snmp-context-id'],
             trunkReq['snmp-peer-id'], trunkReq['snmp-content-id']), [])
        trunkReq['trunk-id-list'] = trunkIdMap.get(
            (trunkReq['snmp-credentials-id'], trunkReq['snmp-context-id'],
             trunkReq['snmp-peer-id'], trunkReq['snmp-content-id']))

        cbCtx.clear()
        cbCtx.update(trunkReq)

    #
    # main script starts here
    #

    helpMessage = """\
        Usage: %s [--help]
            [--version ]
            [--debug-snmp=<%s>]
            [--debug-asn1=<%s>]
            [--daemonize]
            [--process-user=<uname>] [--process-group=<gname>]
            [--pid-file=<file>]
            [--logging-method=<%s[:args>]>]
            [--log-level=<%s>]
            [--config-file=<file>]""" % (sys.argv[0], '|'.join([
        x for x in pysnmp_debug.flagMap.keys() if x != 'mibview'
    ]), '|'.join([x for x in pyasn1_debug.flagMap.keys()]), '|'.join(
        log.methodsMap.keys()), '|'.join(log.levelsMap))

    try:
        opts, params = getopt.getopt(sys.argv[1:], 'hv', [
            'help', 'version', 'debug=', 'debug-snmp=', 'debug-asn1=',
            'daemonize', 'process-user='******'process-group=', 'pid-file=',
            'logging-method=', 'log-level=', 'config-file='
        ])

    except Exception:
        sys.stderr.write('ERROR: %s\r\n%s\r\n' %
                         (sys.exc_info()[1], helpMessage))
        return

    if params:
        sys.stderr.write('ERROR: extra arguments supplied %s\r\n%s\r\n' %
                         (params, helpMessage))
        return

    pidFile = ''
    cfgFile = CONFIG_FILE
    foregroundFlag = True
    procUser = procGroup = None

    loggingMethod = ['stderr']
    loggingLevel = None

    for opt in opts:
        if opt[0] == '-h' or opt[0] == '--help':
            sys.stderr.write("""\
        Synopsis:
          SNMP Proxy Forwarder: server part. Receives SNMP requests at one or many
          built-in SNMP Agents and routes them to encrypted trunks established with
          Forwarder's Manager part(s) running elsewhere.
          Can implement complex routing logic through analyzing parts of SNMP messages
          and matching them against proxying rules.

        Documentation:
          http://snmpfwd.sourceforge.io/

    %s
    """ % helpMessage)
            return
        if opt[0] == '-v' or opt[0] == '--version':
            import snmpfwd
            import pysnmp
            import pyasn1
            sys.stderr.write("""\
        SNMP Proxy Forwarder version %s, written by Ilya Etingof <*****@*****.**>
        Using foundation libraries: pysnmp %s, pyasn1 %s.
        Python interpreter: %s
        Software documentation and support at https://github.com/etingof/snmpfwd
        %s
        """ % (snmpfwd.__version__, hasattr(pysnmp, '__version__')
               and pysnmp.__version__ or 'unknown',
               hasattr(pyasn1, '__version__') and pyasn1.__version__
               or 'unknown', sys.version, helpMessage))
            return
        elif opt[0] == '--debug-snmp':
            pysnmp_debug.setLogger(
                pysnmp_debug.Debug(*opt[1].split(','),
                                   **dict(loggerName=PROGRAM_NAME +
                                          '.pysnmp')))
        elif opt[0] == '--debug-asn1':
            pyasn1_debug.setLogger(
                pyasn1_debug.Debug(*opt[1].split(','),
                                   **dict(loggerName=PROGRAM_NAME +
                                          '.pyasn1')))
        elif opt[0] == '--daemonize':
            foregroundFlag = False
        elif opt[0] == '--process-user':
            procUser = opt[1]
        elif opt[0] == '--process-group':
            procGroup = opt[1]
        elif opt[0] == '--pid-file':
            pidFile = opt[1]
        elif opt[0] == '--logging-method':
            loggingMethod = opt[1].split(':')
        elif opt[0] == '--log-level':
            loggingLevel = opt[1]
        elif opt[0] == '--config-file':
            cfgFile = opt[1]

    try:
        log.setLogger(PROGRAM_NAME, *loggingMethod, **dict(force=True))

        if loggingLevel:
            log.setLevel(loggingLevel)

    except SnmpfwdError:
        sys.stderr.write('%s\r\n%s\r\n' % (sys.exc_info()[1], helpMessage))
        return

    try:
        cfgTree = cparser.Config().load(cfgFile)
    except SnmpfwdError:
        log.error('configuration parsing error: %s' % sys.exc_info()[1])
        return

    if cfgTree.getAttrValue('program-name', '', default=None) != PROGRAM_NAME:
        log.error('config file %s does not match program name %s' %
                  (cfgFile, PROGRAM_NAME))
        return

    if cfgTree.getAttrValue('config-version', '',
                            default=None) != CONFIG_VERSION:
        log.error(
            'config file %s version is not compatible with program version %s'
            % (cfgFile, CONFIG_VERSION))
        return

    random.seed()

    gCurrentRequestContext = {}

    credIdMap = {}
    peerIdMap = {}
    contextIdList = []
    contentIdList = []
    pluginIdMap = {}
    trunkIdMap = {}
    engineIdMap = {}

    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRoutingCbFun(lambda td, t, d: td)
    transportDispatcher.setSocketMap()  # use global asyncore socket map

    #
    # Initialize plugin modules
    #

    pluginManager = PluginManager(macro.expandMacros(
        cfgTree.getAttrValue('plugin-modules-path-list',
                             '',
                             default=[],
                             vector=True),
        {'config-dir': os.path.dirname(cfgFile)}),
                                  progId=PROGRAM_NAME,
                                  apiVer=PLUGIN_API_VERSION)

    for pluginCfgPath in cfgTree.getPathsToAttr('plugin-id'):
        pluginId = cfgTree.getAttrValue('plugin-id', *pluginCfgPath)
        pluginMod = cfgTree.getAttrValue('plugin-module', *pluginCfgPath)
        pluginOptions = macro.expandMacros(
            cfgTree.getAttrValue('plugin-options', *pluginCfgPath,
                                 **dict(default=[], vector=True)),
            {'config-dir': os.path.dirname(cfgFile)})

        log.info(
            'configuring plugin ID %s (at %s) from module %s with options %s...'
            % (pluginId, '.'.join(pluginCfgPath), pluginMod,
               ', '.join(pluginOptions) or '<none>'))

        try:
            pluginManager.loadPlugin(pluginId, pluginMod, pluginOptions)

        except SnmpfwdError:
            log.error('plugin %s not loaded: %s' %
                      (pluginId, sys.exc_info()[1]))
            return

    for configEntryPath in cfgTree.getPathsToAttr('snmp-credentials-id'):
        credId = cfgTree.getAttrValue('snmp-credentials-id', *configEntryPath)
        configKey = []
        log.info('configuring snmp-credentials %s (at %s)...' %
                 (credId, '.'.join(configEntryPath)))

        engineId = cfgTree.getAttrValue('snmp-engine-id', *configEntryPath)

        if engineId in engineIdMap:
            snmpEngine, snmpContext, snmpEngineMap = engineIdMap[engineId]
            log.info('using engine-id %s' %
                     snmpEngine.snmpEngineID.prettyPrint())
        else:
            snmpEngine = engine.SnmpEngine(snmpEngineID=engineId)
            snmpContext = context.SnmpContext(snmpEngine)
            snmpEngineMap = {'transportDomain': {}, 'securityName': {}}

            snmpEngine.observer.registerObserver(
                securityAuditObserver,
                'rfc2576.prepareDataElements:sm-failure',
                'rfc3412.prepareDataElements:sm-failure',
                cbCtx=gCurrentRequestContext)

            snmpEngine.observer.registerObserver(
                requestObserver,
                'rfc3412.receiveMessage:request',
                cbCtx=gCurrentRequestContext)

            CommandResponder(snmpEngine, snmpContext)

            NotificationReceiver(snmpEngine, None)

            engineIdMap[engineId] = snmpEngine, snmpContext, snmpEngineMap

            log.info('new engine-id %s' %
                     snmpEngine.snmpEngineID.prettyPrint())

        configKey.append(str(snmpEngine.snmpEngineID))

        transportDomain = cfgTree.getAttrValue('snmp-transport-domain',
                                               *configEntryPath)
        transportDomain = rfc1902.ObjectName(transportDomain)

        if transportDomain in snmpEngineMap['transportDomain']:
            h, p, transportDomain = snmpEngineMap['transportDomain'][
                transportDomain]
            log.info('using transport endpoint %s:%s, transport ID %s' %
                     (h, p, transportDomain))
        else:
            if transportDomain[:len(udp.domainName)] == udp.domainName:
                transport = udp.UdpTransport()
            elif transportDomain[:len(udp6.domainName)] == udp6.domainName:
                transport = udp6.Udp6Transport()
            else:
                log.error('unknown transport domain %s' % (transportDomain, ))
                return

            h, p = cfgTree.getAttrValue('snmp-bind-address',
                                        *configEntryPath).split(':', 1)

            snmpEngine.registerTransportDispatcher(transportDispatcher,
                                                   transportDomain)

            transportOptions = cfgTree.getAttrValue(
                'snmp-transport-options', *configEntryPath,
                **dict(default=[], vector=True))

            t = transport.openServerMode((h, int(p)))

            if 'transparent-proxy' in transportOptions:
                t.enablePktInfo()
                t.enableTransparent()
            elif 'virtual-interface' in transportOptions:
                t.enablePktInfo()

            config.addSocketTransport(snmpEngine, transportDomain, t)

            snmpEngineMap['transportDomain'][
                transportDomain] = h, p, transportDomain

            log.info(
                'new transport endpoint %s:%s, options %s, transport ID %s' %
                (h, p, transportOptions and '/'.join(transportOptions)
                 or '<none>', transportDomain))

        configKey.append(transportDomain)

        securityModel = cfgTree.getAttrValue('snmp-security-model',
                                             *configEntryPath)
        securityModel = rfc1902.Integer(securityModel)
        securityLevel = cfgTree.getAttrValue('snmp-security-level',
                                             *configEntryPath)
        securityLevel = rfc1902.Integer(securityLevel)
        securityName = cfgTree.getAttrValue('snmp-security-name',
                                            *configEntryPath)

        if securityModel in (1, 2):
            if securityName in snmpEngineMap['securityName']:
                if snmpEngineMap['securityName'][
                        securityModel] == securityModel:
                    log.info('using security-name %s' % securityName)
                else:
                    raise SnmpfwdError(
                        'snmp-security-name %s already in use at snmp-security-model %s'
                        % (securityName, securityModel))
            else:
                communityName = cfgTree.getAttrValue('snmp-community-name',
                                                     *configEntryPath)
                config.addV1System(snmpEngine,
                                   securityName,
                                   communityName,
                                   securityName=securityName)
                log.info(
                    'new community-name %s, security-model %s, security-name %s, security-level %s'
                    % (communityName, securityModel, securityName,
                       securityLevel))
                snmpEngineMap['securityName'][securityName] = securityModel

            configKey.append(securityModel)
            configKey.append(securityLevel)
            configKey.append(securityName)

        elif securityModel == 3:
            if securityName in snmpEngineMap['securityName']:
                log.info('using USM security-name: %s' % securityName)
            else:
                usmUser = cfgTree.getAttrValue('snmp-usm-user',
                                               *configEntryPath)
                log.info(
                    'new USM user %s, security-model %s, security-level %s, security-name %s'
                    % (usmUser, securityModel, securityLevel, securityName))

                if securityLevel in (2, 3):
                    usmAuthProto = cfgTree.getAttrValue(
                        'snmp-usm-auth-protocol', *configEntryPath,
                        **dict(default=config.usmHMACMD5AuthProtocol))
                    usmAuthProto = rfc1902.ObjectName(usmAuthProto)
                    usmAuthKey = cfgTree.getAttrValue('snmp-usm-auth-key',
                                                      *configEntryPath)
                    log.info(
                        'new USM authentication key: %s, authentication protocol: %s'
                        % (usmAuthKey, usmAuthProto))

                    if securityLevel == 3:
                        usmPrivProto = cfgTree.getAttrValue(
                            'snmp-usm-priv-protocol', *configEntryPath,
                            **dict(default=config.usmDESPrivProtocol))
                        usmPrivProto = rfc1902.ObjectName(usmPrivProto)
                        usmPrivKey = cfgTree.getAttrValue(
                            'snmp-usm-priv-key', *configEntryPath,
                            **dict(default=None))
                        log.info(
                            'new USM encryption key: %s, encryption protocol: %s'
                            % (usmPrivKey, usmPrivProto))

                        config.addV3User(snmpEngine, usmUser, usmAuthProto,
                                         usmAuthKey, usmPrivProto, usmPrivKey)

                    else:
                        config.addV3User(snmpEngine, usmUser, usmAuthProto,
                                         usmAuthKey)

                else:
                    config.addV3User(snmpEngine, usmUser)

                snmpEngineMap['securityName'][securityName] = securityModel

            configKey.append(securityModel)
            configKey.append(securityLevel)
            configKey.append(securityName)

        else:
            raise SnmpfwdError('unknown snmp-security-model: %s' %
                               securityModel)

        configKey = tuple(configKey)
        if configKey in credIdMap:
            log.error(
                'ambiguous configuration for key snmp-credentials-id=%s at %s'
                % (credId, '.'.join(configEntryPath)))
            return

        credIdMap[configKey] = credId

    duplicates = {}

    for peerCfgPath in cfgTree.getPathsToAttr('snmp-peer-id'):
        peerId = cfgTree.getAttrValue('snmp-peer-id', *peerCfgPath)
        if peerId in duplicates:
            log.error(
                'duplicate snmp-peer-id=%s at %s and %s' %
                (peerId, '.'.join(peerCfgPath), '.'.join(duplicates[peerId])))
            return

        duplicates[peerId] = peerCfgPath

        log.info('configuring peer ID %s (at %s)...' %
                 (peerId, '.'.join(peerCfgPath)))
        transportDomain = cfgTree.getAttrValue('snmp-transport-domain',
                                               *peerCfgPath)
        if transportDomain not in peerIdMap:
            peerIdMap[transportDomain] = []
        for peerAddress in cfgTree.getAttrValue(
                'snmp-peer-address-pattern-list', *peerCfgPath,
                **dict(vector=True)):
            for bindAddress in cfgTree.getAttrValue(
                    'snmp-bind-address-pattern-list', *peerCfgPath,
                    **dict(vector=True)):
                peerIdMap[transportDomain].append(
                    (re.compile(peerAddress + '#' + bindAddress), peerId))

    duplicates = {}

    for contextCfgPath in cfgTree.getPathsToAttr('snmp-context-id'):
        contextId = cfgTree.getAttrValue('snmp-context-id', *contextCfgPath)
        if contextId in duplicates:
            log.error('duplicate snmp-context-id=%s at %s and %s' %
                      (contextId, '.'.join(contextCfgPath), '.'.join(
                          duplicates[contextId])))
            return

        duplicates[contextId] = contextCfgPath

        k = '#'.join((cfgTree.getAttrValue('snmp-context-engine-id-pattern',
                                           *contextCfgPath),
                      cfgTree.getAttrValue('snmp-context-name-pattern',
                                           *contextCfgPath)))

        log.info('configuring context ID %s (at %s), composite key: %s' %
                 (contextId, '.'.join(contextCfgPath), k))

        contextIdList.append((contextId, re.compile(k)))

    duplicates = {}

    for contentCfgPath in cfgTree.getPathsToAttr('snmp-content-id'):
        contentId = cfgTree.getAttrValue('snmp-content-id', *contentCfgPath)
        if contentId in duplicates:
            log.error('duplicate snmp-content-id=%s at %s and %s' %
                      (contentId, '.'.join(contentCfgPath), '.'.join(
                          duplicates[contentId])))
            return

        duplicates[contentId] = contentCfgPath

        for x in cfgTree.getAttrValue('snmp-pdu-oid-prefix-pattern-list',
                                      *contentCfgPath, **dict(vector=True)):
            k = '#'.join([
                cfgTree.getAttrValue('snmp-pdu-type-pattern', *contentCfgPath),
                x
            ])

            log.info('configuring content ID %s (at %s), composite key: %s' %
                     (contentId, '.'.join(contentCfgPath), k))

            contentIdList.append((contentId, re.compile(k)))

    del duplicates

    for pluginCfgPath in cfgTree.getPathsToAttr('using-plugin-id-list'):
        pluginIdList = cfgTree.getAttrValue('using-plugin-id-list',
                                            *pluginCfgPath,
                                            **dict(vector=True))
        log.info('configuring plugin ID(s) %s (at %s)...' %
                 (','.join(pluginIdList), '.'.join(pluginCfgPath)))
        for credId in cfgTree.getAttrValue('matching-snmp-credentials-id-list',
                                           *pluginCfgPath,
                                           **dict(vector=True)):
            for peerId in cfgTree.getAttrValue('matching-snmp-peer-id-list',
                                               *pluginCfgPath,
                                               **dict(vector=True)):
                for contextId in cfgTree.getAttrValue(
                        'matching-snmp-context-id-list', *pluginCfgPath,
                        **dict(vector=True)):
                    for contentId in cfgTree.getAttrValue(
                            'matching-snmp-content-id-list', *pluginCfgPath,
                            **dict(vector=True)):
                        k = credId, contextId, peerId, contentId
                        if k in pluginIdMap:
                            log.error(
                                'duplicate snmp-credentials-id %s, snmp-context-id %s, snmp-peer-id %s, snmp-content-id %s at plugin-id(s) %s'
                                % (credId, contextId, peerId, contentId,
                                   ','.join(pluginIdList)))
                            return
                        else:
                            log.info(
                                'configuring plugin(s) %s (at %s), composite key: %s'
                                % (','.join(pluginIdList),
                                   '.'.join(pluginCfgPath), '/'.join(k)))

                            for pluginId in pluginIdList:
                                if not pluginManager.hasPlugin(pluginId):
                                    log.error(
                                        'undefined plugin ID %s referenced at %s'
                                        % (pluginId, '.'.join(pluginCfgPath)))
                                    return

                            pluginIdMap[k] = pluginIdList

    for routeCfgPath in cfgTree.getPathsToAttr('using-trunk-id-list'):
        trunkIdList = cfgTree.getAttrValue('using-trunk-id-list',
                                           *routeCfgPath, **dict(vector=True))
        log.info('configuring destination trunk ID(s) %s (at %s)...' %
                 (','.join(trunkIdList), '.'.join(routeCfgPath)))
        for credId in cfgTree.getAttrValue('matching-snmp-credentials-id-list',
                                           *routeCfgPath, **dict(vector=True)):
            for peerId in cfgTree.getAttrValue('matching-snmp-peer-id-list',
                                               *routeCfgPath,
                                               **dict(vector=True)):
                for contextId in cfgTree.getAttrValue(
                        'matching-snmp-context-id-list', *routeCfgPath,
                        **dict(vector=True)):
                    for contentId in cfgTree.getAttrValue(
                            'matching-snmp-content-id-list', *routeCfgPath,
                            **dict(vector=True)):
                        k = credId, contextId, peerId, contentId
                        if k in trunkIdMap:
                            log.error(
                                'duplicate snmp-credentials-id %s, snmp-context-id %s, snmp-peer-id %s, snmp-content-id %s at trunk-id(s) %s'
                                % (credId, contextId, peerId, contentId,
                                   ','.join(trunkIdList)))
                            return
                        else:
                            trunkIdMap[k] = trunkIdList

                        log.info(
                            'configuring trunk routing to %s (at %s), composite key: %s'
                            % (','.join(trunkIdList), '.'.join(routeCfgPath),
                               '/'.join(k)))

    def dataCbFun(trunkId, msgId, msg):
        log.debug('message ID %s received from trunk %s' % (msgId, trunkId))

    trunkingManager = TrunkingManager(dataCbFun)

    def getTrunkAddr(a, port=0):
        f = lambda h, p=port: (h, int(p))
        try:
            return f(*a.split(':'))

        except Exception:
            raise SnmpfwdError('improper IPv4 endpoint %s' % a)

    for trunkCfgPath in cfgTree.getPathsToAttr('trunk-id'):
        trunkId = cfgTree.getAttrValue('trunk-id', *trunkCfgPath)
        secret = cfgTree.getAttrValue('trunk-crypto-key', *trunkCfgPath,
                                      **dict(default=''))
        secret = secret and (secret * ((16 // len(secret)) + 1))[:16]
        log.info('configuring trunk ID %s (at %s)...' %
                 (trunkId, '.'.join(trunkCfgPath)))
        connectionMode = cfgTree.getAttrValue('trunk-connection-mode',
                                              *trunkCfgPath)
        if connectionMode == 'client':
            trunkingManager.addClient(
                trunkId,
                getTrunkAddr(
                    cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath)),
                getTrunkAddr(
                    cfgTree.getAttrValue('trunk-peer-address', *trunkCfgPath),
                    30201),
                cfgTree.getAttrValue('trunk-ping-period',
                                     *trunkCfgPath,
                                     default=0,
                                     expect=int), secret)
            log.info(
                'new trunking client from %s to %s' %
                (cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath),
                 cfgTree.getAttrValue('trunk-peer-address', *trunkCfgPath)))
        if connectionMode == 'server':
            trunkingManager.addServer(
                getTrunkAddr(
                    cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath),
                    30201),
                cfgTree.getAttrValue('trunk-ping-period',
                                     *trunkCfgPath,
                                     default=0,
                                     expect=int), secret)
            log.info(
                'new trunking server at %s' %
                (cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath)))

    transportDispatcher.registerTimerCbFun(trunkingManager.setupTrunks,
                                           random.randrange(1, 5))
    transportDispatcher.registerTimerCbFun(trunkingManager.monitorTrunks,
                                           random.randrange(1, 5))

    try:
        daemon.dropPrivileges(procUser, procGroup)

    except Exception:
        log.error('can not drop privileges: %s' % sys.exc_info()[1])
        return

    if not foregroundFlag:
        try:
            daemon.daemonize(pidFile)

        except Exception:
            log.error('can not daemonize process: %s' % sys.exc_info()[1])
            return

    # Run mainloop

    log.info('starting I/O engine...')

    transportDispatcher.jobStarted(1)  # server job would never finish

    # Python 2.4 does not support the "finally" clause

    while True:
        try:
            transportDispatcher.runDispatcher()

        except (PySnmpError, SnmpfwdError, socket.error):
            log.error(str(sys.exc_info()[1]))
            continue

        except Exception:
            transportDispatcher.closeDispatcher()
            raise
예제 #29
0
    def __init__(self,
                 mibPath,
                 temperatureValue,
                 snmpRelays,
                 criticalStatus=True):
        from types import ListType, TupleType, StringTypes
        from re import compile, search
        from socket import gethostbyname

        extractPaths = compile(r'[,:]')
        checkIP = compile(r'(\d{1,3}\.){3}\d{1,3}')

        # Create SNMP engine instance
        self.snmpEngine = engine.SnmpEngine()

        if not temperatureValue:
            raise ValueError, 'A temperature must be provided'

        self.temperature = temperatureValue
        #print "============>mibPath type: %s" %type(mibPath)
        if type(mibPath) in StringTypes:
            mibPathTuple = tuple(extractPaths.split(mibPath))
        elif type(mibPath) in (ListType, TupleType):
            mibPathTuple = tuple(mibPath)
        else:
            mibPathTuple = ('/usr/local/share/snmp/python/', )

        mibBuilder = self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder

        #print mibPathTuple
        mibSources = mibBuilder.getMibPath() + mibPathTuple
        mibBuilder.setMibPath(*mibSources)

        mibBuilder.loadModules('USC-IGFAE-MIB')

        if type(snmpRelays) in StringTypes:
            snmpRelays = snmpRelays.split(',')
        elif not type(snmpRelays) in (ListType, TupleType):
            raise TypeError, 'The list of SNMP relays must be a string or a list or tuple of strings'

        (temperatureCritical, temperatureOK,
         self.roomTemp) = mibBuilder.importSymbols('USC-IGFAE-MIB',
                                                   'temperatureCritical',
                                                   'temperatureOK', 'roomTemp')

        # SecurityName <-> CommunityName mapping
        config.addV1System(self.snmpEngine, 'Arduino', 'ups')

        # Specify security settings per SecurityName (SNMPv2c -> 1)
        config.addTargetParams(self.snmpEngine, 'creds', 'Arduino',
                               'noAuthNoPriv', 0)

        # Setup transport endpoint and bind it with security settings yielding
        # a target name
        config.addSocketTransport(self.snmpEngine, udp.domainName,
                                  udp.UdpSocketTransport().openClientMode())

        index = 0
        for machine in snmpRelays:
            index = index + 1
            if not checkIP.match(machine):
                try:
                    machine = gethostbyname(machine)
                except:
                    continue

            #print "==============>SNMP relay  IP: %s" % machine
            config.addTargetAddr(self.snmpEngine,
                                 'NMS%s' % index,
                                 udp.domainName, (machine, 162),
                                 'creds',
                                 tagList='managers')

        # Specify what kind of notification should be sent (TRAP or INFORM),
        # to what targets (chosen by tag) and what filter should apply to
        # the set of targets (selected by tag)
        config.addNotificationTarget(self.snmpEngine, 'sendShutdownTrap',
                                     'my-filter', 'managers', 'trap')

        # Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
        # and SecurityName
        config.addContext(self.snmpEngine, '')
        config.addVacmUser(self.snmpEngine, 1, 'Arduino', 'noAuthNoPriv', (),
                           (), (1, 3, 6))

        # *** SNMP engine configuration is complete by this line ***

        # Create default SNMP context where contextEngineId == SnmpEngineId
        snmpContext = context.SnmpContext(self.snmpEngine)

        if criticalStatus:
            self.trap = temperatureCritical
        else:
            self.trap = temperatureOK

        # Create Notification Originator App instance.
        ntforg.NotificationOriginator.__init__(self, snmpContext)
예제 #30
0
    def sendTrap(self,
                 version,
                 enterprise,
                 varList,
                 community=False,
                 destPort=False):
        if destPort:
            trapPort = destPort
        else:
            trapPort = TRAP_PORT
        if community:
            comm = community
        else:
            comm = DEFAULT_COMM
        snmpEngine = engine.SnmpEngine()
        # v1/2 setup
        config.addV1System(snmpEngine, TEST_AGENT, comm)
        # v3 setup
        config.addV3User(snmpEngine, TEST_USER, config.usmHMACMD5AuthProtocol,
                         'authKey1', config.usmDESPrivProtocol, 'privKey1')
        # Transport params
        config.addTargetParams(snmpEngine, PARAM, TEST_USER, AUTHPRIV)
        #config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 0)
        # Transport addresses
        config.addTargetAddr(snmpEngine,
                             NMS,
                             config.snmpUDPDomain,
                             (self.dataCollector, trapPort),
                             PARAM,
                             tagList='myManagementStations')
        # Notification targets
        config.addNotificationTarget(
            #    snmpEngine, 'myNotifyName', 'myParams', 'myManagementStations', 'trap'
            snmpEngine,
            'myNotifyName',
            PARAM,
            'myManagementStations',
            'inform')
        # Setup transport endpoint
        config.addSocketTransport(snmpEngine, udp.domainName,
                                  udp.UdpSocketTransport().openClientMode())
        # Agent-side VACM setup
        config.addContext(snmpEngine, '')
        config.addTrapUser(snmpEngine, 1, 'test-agent', 'noAuthNoPriv',
                           (1, 3, 6))  # v1
        config.addTrapUser(snmpEngine, 2, 'test-agent', 'noAuthNoPriv',
                           (1, 3, 6))  # v2c
        config.addTrapUser(snmpEngine, 3, 'test-user', 'authPriv',
                           (1, 3, 6))  # v3

        # SNMP context
        snmpContext = context.SnmpContext(snmpEngine)

        def cbFun(sendRequestHandle, errorIndication, cbCtx):
            if errorIndication:
                print errorIndication

        ntforg.NotificationOriginator(snmpContext).sendNotification(
            snmpEngine, 'myNotifyName', ('SNMPv2-MIB', 'coldStart'),
            (((1, 3, 6, 1, 2, 1, 1, 5),
              v2c.OctetString('Example Notificator')), ), cbFun)

        snmpEngine.transportDispatcher.runDispatcher()