def testtrapv2(self):
        '''testtrapv2'''
        # Traps have quite different semantics among proto versions
        if verID == api.protoVersion2c:
            var = []
            oid = (1, 3, 6, 1, 4, 1, 2011, 2, 235, 1, 1, 4, 1, 0)
            # 1.3.6.1.4.1.2011.2.235.1.1.15.50.1.5(cpuClockRate).0
            # 1.3.6.1.4.1.2011.2.235.1.1.4.1.0  trapEnable
            val = pMod.Integer(1)
            var.append((oid, val))

            pMod.apiTrapPDU.setVarBinds(trapPDU, var)

        # Build message
        trapMsg = pMod.Message()
        pMod.apiMessage.setDefaults(trapMsg)
        pMod.apiMessage.setCommunity(trapMsg, community)
        pMod.apiMessage.setPDU(trapMsg, trapPDU)

        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openClientMode())
        # 本机测试使用localhost,应为对应trap server 的IP地址。
        transportDispatcher.sendMessage(encoder.encode(trapMsg),
                                        udp.domainName, (trapdip, 162))
        transportDispatcher.runDispatcher()
        transportDispatcher.closeDispatcher()

        self.assertTrue(True)
Exemple #2
0
def runDispatcherFunction():

    transportDispatcher = AsynsockDispatcher()

    transportDispatcher.registerRecvCbFun(cbFun)

    # UDP/IPv4
    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode(('', 162))
        # if test.py is running inside a container named "ra", the traps messages will be for exampleL:
        #snmptrap -v2c -c public ra:162 '' SNMPv2-MIB::coldStart.0 SNMPv2-MIB::sysContact.0 s 'trap testing number #7'
    )

    # UDP/IPv6
    #transportDispatcher.registerTransport(
    #    udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
    #)

    transportDispatcher.jobStarted(1)

    try:
        # Dispatcher will never finish as job#1 never reaches zero
        print('run dispatcher')
        transportDispatcher.runDispatcher()
    except:
        transportDispatcher.closeDispatcher()
        raise
def setup_snmp():
    """Configure SNMP server listener"""

    transport_dispatcher = AsynsockDispatcher()

    transport_dispatcher.registerRecvCbFun(snmp_trap_receiver)

    # UDP/IPv4
    transport_dispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162)))

    # UDP/IPv6
    transport_dispatcher.registerTransport(
        udp6.domainName,
        udp6.Udp6SocketTransport().openServerMode(('::1', 162)))

    transport_dispatcher.jobStarted(1)

    try:
        # Dispatcher will never finish as job#1 never reaches zero
        transport_dispatcher.runDispatcher()
    except:
        transport_dispatcher.closeDispatcher()
        raise
Exemple #4
0
def main(options, args):

    logname = 'summit_ups'
    logger = ssdlog.make_logger(logname, options)

    power_off = 'obcpPoff'
    power_off = os.path.join(options.dir, power_off)

    try:
        os.remove(power_off)
    except Exception as e:
        logger.warn('warn: is %s there??  %s' % (power_off, e))

    snmp = SnmpTrap(power_off, logger)

    try:
        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openServerMode(
                ('%s' % options.mgrhost, 162)))
        transportDispatcher.registerRecvCbFun(snmp.trap_cb)
        transportDispatcher.jobStarted(1)  # this job would never finish
        transportDispatcher.runDispatcher()
    except KeyboardInterrupt:
        logger.info('keyboard interrupting...')
        snmp.ev_quit.set()
    except Exception as e:
        logger.error('error: %s' % e)
        snmp.ev_quit.set()
        logger.error('error: snmp trap terminated..')
Exemple #5
0
def receive_trap(self):
    
    transportDispatcher = AsynsockDispatcher()

    transportDispatcher.registerRecvCbFun(cbFun)

    # UDP/IPv4
    transportDispatcher.registerTransport(
        udp.domainName, udp.UdpSocketTransport().openServerMode(('192.168.115.187', 162))
        )

    # UDP/IPv6
    transportDispatcher.registerTransport(
        udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
        )

    transportDispatcher.jobStarted(1)

    try:
        # Dispatcher will never finish as job#1 never reaches zero
        print('run dispatcher')
        transportDispatcher.runDispatcher()
    except:
        transportDispatcher.closeDispatcher()
        raise
Exemple #6
0
    def send(self, host, community, oid, value):
        self.pMod.apiPDU.setDefaults(self.reqPDU)
        self.pMod.apiPDU.setVarBinds(
            self.reqPDU,
            ((oid, self.pMod.OctetString(value)),
            )
        )

        # Build message
        reqMsg = self.pMod.Message()
        self.pMod.apiMessage.setDefaults(reqMsg)
        self.pMod.apiMessage.setCommunity(reqMsg, community)
        self.pMod.apiMessage.setPDU(reqMsg, self.reqPDU)

        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerRecvCbFun(self.cbRecvFun)
        transportDispatcher.registerTimerCbFun(self.cbTimerFun)

        # UDP/IPv4
        transportDispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openClientMode()
        )

        # Pass message to dispatcher
        transportDispatcher.sendMessage(
            encoder.encode(reqMsg), udp.domainName, (host, 161)
        )
        transportDispatcher.jobStarted(1)

        # Dispatcher will finish as job#1 counter reaches zero
        transportDispatcher.runDispatcher()
        transportDispatcher.closeDispatcher()
Exemple #7
0
	def query(self, oidCountersDict):
		resultsDict = dict()

		# SNMP protocol version to use
		pMod = api.protoModules[api.protoVersion1]
		
		# Build PDU
		reqPDU = pMod.GetRequestPDU()
		pMod.apiPDU.setDefaults(reqPDU)
		
		# Create a tuple of OIDs tuples
		oidList = list()
		for oid in oidCountersDict.values():
			oidList.append((oid, pMod.Null()))
		OIDs = tuple(oidList)
		
		pMod.apiPDU.setVarBinds(reqPDU, (OIDs))

		# Build message
		reqMsg = pMod.Message()
		pMod.apiMessage.setDefaults(reqMsg)
		pMod.apiMessage.setCommunity(reqMsg, 'public')
		pMod.apiMessage.setPDU(reqMsg, reqPDU)

		def cbTimerFun(timeNow, startedAt=time()):
			if timeNow - startedAt > self.snmpTimeout:
				transportDispatcher.jobFinished(1)
				raise SNMPTimeOutError("The host %s has not responded in the specified timeout of %ss!" % (self.host, self.snmpTimeout))
    
		def cbRecvFun(transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU=reqPDU):
			while wholeMsg:
				rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
				rspPDU = pMod.apiMessage.getPDU(rspMsg)
				# Match response to request
				if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
					# Check for SNMP errors reported
					errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
					if errorStatus:
						print errorStatus.prettyPrint()
						raise SNMPoIDNotSupported("%s: An requested OID is not supported by this device!" % errorStatus.prettyPrint())
					else:
						for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
							#print '%s = %s' % (oid.prettyPrint(), val)
							resultsDict[str(oid)] = str(val)

					transportDispatcher.jobFinished(1)
			return wholeMsg

		transportDispatcher = AsynsockDispatcher()
		transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openClientMode())
		transportDispatcher.registerRecvCbFun(cbRecvFun)
		transportDispatcher.registerTimerCbFun(cbTimerFun)
		transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName, (self.host, int(self.port)))
		transportDispatcher.jobStarted(1)
		transportDispatcher.runDispatcher()
		transportDispatcher.closeDispatcher()

		return resultsDict
Exemple #8
0
def Send_GetSystemPDUName(reqMsg, hostname, port=161):
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openClientMode())
    transportDispatcher.registerRecvCbFun(cbRecvFun)
    transportDispatcher.registerTimerCbFun(cbTimerFun)
    transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName, (hostname, 161))
    transportDispatcher.jobStarted(1)
    transportDispatcher.runDispatcher()
    transportDispatcher.closeDispatcher()
Exemple #9
0
    def run(self):
        transport_dispatcher = AsynsockDispatcher()
        transport_dispatcher.registerRecvCbFun(self._callback)
        transport_dispatcher.registerTransport(udp.domainName,
            udp.UdpSocketTransport().openServerMode((self.address, self.port)))
        transport_dispatcher.jobStarted(1)

        try:
            transport_dispatcher.runDispatcher()
        except:
            transport_dispatcher.closeDispatcher()
            raise
Exemple #10
0
def Send_GetSystemPDUName(reqMsg, hostname, port=161):
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openClientMode())
    transportDispatcher.registerRecvCbFun(cbRecvFun)
    transportDispatcher.registerTimerCbFun(cbTimerFun)
    transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName,
                                    (hostname, 161))
    transportDispatcher.jobStarted(1)
    transportDispatcher.runDispatcher()
    transportDispatcher.closeDispatcher()
Exemple #11
0
 def sendSNMPMessage(self, reqMsg):
     transportDispatcher = AsynsockDispatcher()
     
     transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openClientMode())
     transportDispatcher.registerRecvCbFun(self.cbRecvFun)
     transportDispatcher.registerTimerCbFun(self.cbTimerFun)
     
     transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName, (self.host, self.port))
     
     transportDispatcher.jobStarted(1)
     transportDispatcher.runDispatcher()
     transportDispatcher.closeDispatcher()
Exemple #12
0
    def run(self):
        """Run the sensor on its own thread"""

        # Check for debug mode being activated/deactivated
        self._read_my_msgQ_noWait()

        try:
            self._log_debug("Start processing")

            # Create MIB loader to lookup oids sent in traps
            self._mib_builder()

            # Create an asynchronous dispatcher and register a callback method to handle incoming traps
            transportDispatcher = AsynsockDispatcher()
            transportDispatcher.registerRecvCbFun(self._trap_catcher)

            # UDP/IPv4
            transportDispatcher.registerTransport(
                udp.domainName,
                udp.UdpSocketTransport().openServerMode(
                    (self._bind_ip, self._bind_port)))

            # UDP/IPv6
            transportDispatcher.registerTransport(
                udp6.domainName,
                udp6.Udp6SocketTransport().openServerMode(
                    ('::1', self._bind_port)))

            transportDispatcher.jobStarted(1)

            try:
                # Dispatcher will never finish as job #1 never reaches zero
                transportDispatcher.runDispatcher()
            except Exception as ae:
                self._log_debug("Exception: %r" % ae)
                transportDispatcher.closeDispatcher()

            self._log_debug("Finished processing, restarting SNMP listener")

            # Reset debug mode if persistence is not enabled
            self._disable_debug_if_persist_false()

            # Schedule the next time to run thread
            self._scheduler.enter(10, self._priority, self.run, ())

        # Could not bind to IP:port, log it and exit out module
        except Exception as ae:
            self._log_debug(
                "Unable to process SNMP traps from this node, closing module.")
            self._log_debug(
                f"SNMP Traps sensor attempted to bind to {self._bind_ip}:{self._bind_port}"
            )
Exemple #13
0
    def run(self):
        transport_dispatcher = AsynsockDispatcher()
        transport_dispatcher.registerRecvCbFun(self._callback)
        transport_dispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openServerMode((self.address, self.port)))
        transport_dispatcher.jobStarted(1)

        try:
            transport_dispatcher.runDispatcher()
        except Exception as exc:
            transport_dispatcher.closeDispatcher()
            raise exc
    def run(self):
        # Build PDU
        reqPDU =  pMod.GetRequestPDU()
        pMod.apiPDU.setDefaults(reqPDU)
        pduList = []
        if self._CbLastChange != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,9,self.SNMPIndex), pMod.Null()))
        if self._CbInOctets != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,10,self.SNMPIndex), pMod.Null()))
        if self._CbInUnicastPkts != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,11,self.SNMPIndex), pMod.Null()))
        if self._CbInNUnicastPkts != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,12,self.SNMPIndex), pMod.Null()))
        if self._CbInDiscard != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,13,self.SNMPIndex), pMod.Null()))
        if self._CbInErrors != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,14,self.SNMPIndex), pMod.Null()))
        if self._CbInUnknownProtos != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,15,self.SNMPIndex), pMod.Null()))
        if self._CbOutOctets != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,16,self.SNMPIndex), pMod.Null()))
        if self._CbOutUnicastPkts != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,17,self.SNMPIndex), pMod.Null()))
        if self._CbOutNUnicastPkts != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,18,self.SNMPIndex), pMod.Null()))
        if self._CbOutDiscard != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,19,self.SNMPIndex), pMod.Null()))
        if self._CbOutErrors != None:
            pduList.append(((1,3,6,1,2,1,2,2,1,20,self.SNMPIndex), pMod.Null()))

        pMod.apiPDU.setVarBinds(reqPDU, pduList)
        self._reqPDU = reqPDU
        
        # Build message
        reqMsg = pMod.Message()
        pMod.apiMessage.setDefaults(reqMsg)
        pMod.apiMessage.setCommunity(reqMsg, self._agent)
        pMod.apiMessage.setPDU(reqMsg, reqPDU)

        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openClientMode()
            )
        transportDispatcher.registerRecvCbFun(self._cbRecvFun)

        while not self._IsStopped():
            if not transportDispatcher.transportsAreWorking():
                transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName, (self._host, self._port))
                transportDispatcher.jobStarted(1)
                transportDispatcher.runDispatcher()
            sleep(self._interval)
Exemple #15
0
def snmp_trap_receiver(ifname, port=162):
    if_ip = get_ip_address(ifname)
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRecvCbFun(cbFun)

    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode((if_ip, port)))
    transportDispatcher.jobStarted(1)
    print('SNMP Trap Receiver Started!!!')
    try:
        transportDispatcher.runDispatcher()
    except:
        transportDispatcher.closeDispatcher()
        raise
Exemple #16
0
class SnmpServer(threading.Thread):
	def __init__(self, address):
		threading.Thread.__init__(self)
		self._address = address
		self._transportDispatcher = AsynsockDispatcher()
		self._transportDispatcher.registerRecvCbFun(self.onSnmpMessage)

	def run(self):
		self._transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openServerMode(self._address))
		getLogger().info("Now listening on %s:%s" % self._address)
		self._transportDispatcher.jobStarted(1)
		try:
			self._transportDispatcher.runDispatcher(timeout = 1)
		except Exception, e:
			getLogger().error(u"Error while handling an SNMP message: %s" % unicode(e))
Exemple #17
0
    def run(self):
        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerRecvCbFun(cbFun)
        # UDP/IPv4
        transportDispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162))
        )

        transportDispatcher.jobStarted(1)

        try:
            # Dispatcher will never finish as job#1 never reaches zero
            transportDispatcher.runDispatcher()
        except:
            transportDispatcher.closeDispatcher()
            raise
def sent_snmp_trap(product, level, regionId, instanceName, name):
    # Protocol version to use
    verID = api.protoVersion2c
    pMod = api.protoModules[verID]

    # Build PDU
    trapPDU = pMod.TrapPDU()
    pMod.apiTrapPDU.setDefaults(trapPDU)

    # Traps have quite different semantics among proto versions
    if verID == api.protoVersion2c:

        var = []
        oid = (1, 3, 6, 1, 4, 1, 12149, 1)
        val = pMod.OctetString('product:%s' % product)
        var.append((oid, val))
        oid = (1, 3, 6, 1, 4, 1, 12149, 2)
        val = pMod.OctetString('level:%s' % level)
        var.append((oid, val))
        oid = (1, 3, 6, 1, 4, 1, 12149, 3)
        val = pMod.OctetString('regionId:%s' % regionId)
        var.append((oid, val))
        oid = (1, 3, 6, 1, 4, 1, 12149, 4)
        val = pMod.OctetString('instanceName:%s' % instanceName)
        var.append((oid, val))
        oid = (1, 3, 6, 1, 4, 1, 12149, 5)
        val = pMod.OctetString('name:%s' % name)
        var.append((oid, val))
        pMod.apiTrapPDU.setVarBinds(trapPDU, var)

    print(var)
    save_log(str(var))
    # Build message
    trapMsg = pMod.Message()

    pMod.apiMessage.setDefaults(trapMsg)
    pMod.apiMessage.setCommunity(trapMsg, 'public')
    pMod.apiMessage.setPDU(trapMsg, trapPDU)

    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openClientMode())
    transportDispatcher.sendMessage(encoder.encode(trapMsg), udp.domainName,
                                    ('localhost', 162))
    transportDispatcher.runDispatcher()
    transportDispatcher.closeDispatcher()
def main():
    'main program function'
    if os.path.isfile(CONFIG_FILE):
        filename = CONFIG_FILE
    elif os.path.isfile('/config/{0}'.format(CONFIG_FILE)):
        filename = '/config/{0}'.format(CONFIG_FILE)
    else:
        print 'Error: cannot find configuration file', CONFIG_FILE
        return

    processConfig(filename)

    transportDispatcher = AsynsockDispatcher()

    transportDispatcher.registerRecvCbFun(cbFun)

    # UDP/IPv4
    if gArgs.virtual_router:
        lookupVR(gArgs.virtual_router)

    # During startup, the IP address may not be ready yet. So we try a few times
    for retry in range(30):
        try:
            transportDispatcher.registerTransport(
                udp.domainName,
                udp.UdpSocketTransport().openServerMode(
                    (gArgs.ip_address, 162)))
            break
        except Exception:
            time.sleep(5)


# UDP/IPv6
    transportDispatcher.registerTransport(
        udp6.domainName,
        udp6.Udp6SocketTransport().openServerMode(('::1', 162)))

    transportDispatcher.jobStarted(1)

    try:
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()
    except Exception:
        transportDispatcher.closeDispatcher()
        raise
Exemple #20
0
def snmp_trap_receiver(ifname, port=162):
    if_ip = get_ip_address(ifname)
    transportDispatcher = AsynsockDispatcher()  # 创建实例
    transportDispatcher.registerRecvCbFun(cbFun)  # 调用处理Trap信息的函数

    # UDP/IPv4
    transportDispatcher.registerTransport(
        udp.domainName, udp.UdpSocketTransport().openServerMode((if_ip, port))  # 绑定到本地地址与UDP/162号端口
    )

    transportDispatcher.jobStarted(1)  # 开始工作
    print("SNMP Trap Receiver Started!!!")
    try:
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()  # 运行
    except:
        transportDispatcher.closeDispatcher()
        raise
Exemple #21
0
def notif_Receiver():
    def cbFun(transportDispatcher, transportDomain, transportAddress,
              wholeMsg):
        transportDispatcher.jobFinished(1)
        return

    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRecvCbFun(cbFun)
    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode((raspberry_ip, 1162)))
    transportDispatcher.jobStarted(1)
    try:
        transportDispatcher.runDispatcher()
    except:
        transportDispatcher.closeDispatcher()
        raise
    return
Exemple #22
0
def main():
    'main program function'
    if os.path.isfile(CONFIG_FILE):
        filename = CONFIG_FILE
    elif os.path.isfile('/config/{0}'.format(CONFIG_FILE)):
        filename = '/config/{0}'.format(CONFIG_FILE)
    else:
        print 'Error: cannot find configuration file', CONFIG_FILE
        return

    processConfig(filename)

    transportDispatcher = AsynsockDispatcher()

    transportDispatcher.registerRecvCbFun(cbFun)

# UDP/IPv4
    if gArgs.virtual_router:
        lookupVR(gArgs.virtual_router)

    # During startup, the IP address may not be ready yet. So we try a few times
    for retry in range(30):
        try:
            transportDispatcher.registerTransport(
                udp.domainName, udp.UdpSocketTransport().openServerMode((gArgs.ip_address, 162))
            )
            break
        except Exception:
            time.sleep(5)

# UDP/IPv6
    transportDispatcher.registerTransport(
        udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
    )

    transportDispatcher.jobStarted(1)

    try:
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()
    except Exception:
        transportDispatcher.closeDispatcher()
        raise
def _trap_receiver(trap_filter, host, port, timeout):
    started = time.time()

    def _trap_timer_cb(now):
        if now - started > timeout:
            raise AssertionError('No matching trap received in %s.' %
                                 robot.utils.secs_to_timestr(timeout))

    def _trap_receiver_cb(transport, domain, sock, msg):
        if decodeMessageVersion(msg) != protoVersion2c:
            raise RuntimeError('Only SNMP v2c traps are supported.')

        req, msg = decoder.decode(msg, asn1Spec=v2c.Message())
        pdu = v2c.apiMessage.getPDU(req)

        # ignore any non trap PDUs
        if not pdu.isSameTypeWith(v2c.TrapPDU()):
            return

        if trap_filter(domain, sock, pdu):
            raise StopListener()

        # Stop the receiver if the trap we are looking for was received.
        if False:
            raise StopListener()

    dispatcher = AsynsockDispatcher()
    dispatcher.registerRecvCbFun(_trap_receiver_cb)
    dispatcher.registerTimerCbFun(_trap_timer_cb)

    transport = udp.UdpSocketTransport().openServerMode((host, port))
    dispatcher.registerTransport(udp.domainName, transport)

    # we'll never finish, except through an exception
    dispatcher.jobStarted(1)

    try:
        dispatcher.runDispatcher()
    except StopListener:
        pass
    finally:
        dispatcher.closeDispatcher()
def _trap_receiver(trap_filter, host, port, timeout):
    started = time.time()
    def _trap_timer_cb(now):
        if now - started > timeout:
            raise AssertionError('No matching trap received in %s.' %
                    robot.utils.secs_to_timestr(timeout))
    def _trap_receiver_cb(transport, domain, sock, msg):
        if decodeMessageVersion(msg) != protoVersion2c:
            raise RuntimeError('Only SNMP v2c traps are supported.')

        req, msg = decoder.decode(msg, asn1Spec=v2c.Message())
        pdu = v2c.apiMessage.getPDU(req)

        # ignore any non trap PDUs
        if not pdu.isSameTypeWith(v2c.TrapPDU()):
            return

        if trap_filter(domain, sock, pdu):
            raise StopListener()


        # Stop the receiver if the trap we are looking for was received.
        if False:
            raise StopListener()

    dispatcher = AsynsockDispatcher()
    dispatcher.registerRecvCbFun(_trap_receiver_cb)
    dispatcher.registerTimerCbFun(_trap_timer_cb)

    transport = udp.UdpSocketTransport().openServerMode((host, port))
    dispatcher.registerTransport(udp.domainName, transport)

    # we'll never finish, except through an exception
    dispatcher.jobStarted(1)

    try:
        dispatcher.runDispatcher()
    except StopListener:
        pass
    finally:
        dispatcher.closeDispatcher()
Exemple #25
0
    def start(self):
        '''
        ' 启动监听进程
        ' raise Exception: 异常停止时抛出
        '''
        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerRecvCbFun(self._cbHandler)

        # UDP/IPv4
        transportDispatcher.registerTransport(\
            udp.domainName, udp.UdpSocketTransport().openServerMode(\
                                            (str(self._configdata.Localaddress), \
                                             int(self._configdata.Trapport)))
        )
        transportDispatcher.jobStarted(1)
        try:
            # 分发器后台运行,任务编号1#。获取0值时停止
            transportDispatcher.runDispatcher()
        except Exception:
            transportDispatcher.closeDispatcher()
            raise
Exemple #26
0
    def start_agent(self):
        print 'start_agent'
        try:
            transportDispatcher = AsynsockDispatcher()
            transportDispatcher.registerRecvCbFun(self.cbFun) #obrabotchik
            
            transportDispatcher.registerTransport(
                udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161))
            )
            
            transportDispatcher.jobStarted(1)
        except Exception as error:
            print 'error %s' % error

        try:
            # Dispatcher will never finish as job#1 never reaches zero
            transportDispatcher.runDispatcher()
        except:
            transportDispatcher.closeDispatcher()
            print 'error run disp'
            raise
 def run(self):
     
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRecvCbFun(trapCallback)
    if self.ipv6:
        transport = udp.Udp6SocketTransport()
        domainName = udp6.domainName
    else:
        transport = udp.UdpSocketTransport()  
        domainName = udp.domainName
            
    try:     
        transportDispatcher.registerTransport(domainName, transport.openServerMode((self.host, self.port)))
  
        transportDispatcher.jobStarted(1)
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()     
    except RuntimeError,e:
        transportDispatcher.closeDispatcher()
        logging.error("Looks like an error: %s" % str(e))
        sys.exit(1)
 def run(self):
     
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRecvCbFun(trapCallback)
    if self.ipv6:
        transport = udp.Udp6SocketTransport()
        domainName = udp6.domainName
    else:
        transport = udp.UdpSocketTransport()  
        domainName = udp.domainName
            
    try:     
        transportDispatcher.registerTransport(domainName, transport.openServerMode((self.host, self.port)))
  
        transportDispatcher.jobStarted(1)
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()     
    except: # catch *all* exceptions
        e = sys.exc_info()[1]
        transportDispatcher.closeDispatcher()
        logging.error("Failed to register transport and run dispatcher: %s" % str(e))
        sys.exit(1)
Exemple #29
0
def snmp_msg_send():
    try:
        verID = api.protoVersion2c
        pMod = api.protoModules[verID]

        trapPDU = pMod.TrapPDU()
        pMod.apiTrapPDU.setDefaults(trapPDU)
        now_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        # Traps have quite different semantics among proto versions
        if verID == api.protoVersion2c:
            var = []
            oid = (1, 3, 6, 1, 4, 1, 3902, 2, 2, 4)
            val = pMod.OctetString("2001")
            var.append((oid, val))
            oid = (1, 3, 6, 1, 4, 1, 3902, 2, 2, 5)
            val = pMod.OctetString("60")
            var.append((oid, val))
            oid = (1, 3, 6, 1, 4, 1, 3902, 2, 2, 6)
            val = pMod.OctetString(now_time)
            var.append((oid, val))
            pMod.apiTrapPDU.setVarBinds(trapPDU, var)

        trapMsg = pMod.Message()
        pMod.apiMessage.setDefaults(trapMsg)
        pMod.apiMessage.setCommunity(trapMsg, 'Beijing JiaoTong University')
        pMod.apiMessage.setPDU(trapMsg, trapPDU)

        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openClientMode())
        transportDispatcher.sendMessage(encoder.encode(trapMsg),
                                        udp.domainName,
                                        (ntp_ip2, 162))  # 为对应trapserver的IP地址。
        transportDispatcher.runDispatcher()
        transportDispatcher.closeDispatcher()
    except:
        logging.debug('snmp send fail!')
        print('snmp send fail')
Exemple #30
0
    def start(self):
        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerRecvCbFun(self._event_handle)

        if self.ipv4_addr:
            transportDispatcher.registerTransport(
                udp.domainName,
                udp.UdpSocketTransport().openServerMode(
                    (str(self.ipv4_addr), self.port)))
        if self.ipv6_addr:
            transportDispatcher.registerTransport(
                udp6.domainName,
                udp6.Udp6SocketTransport().openServerMode(
                    (str(self.ipv6_addr), self.port)))

        transportDispatcher.jobStarted(1)
        try:
            # Dispatcher will never finish as job#1 never reaches zero
            transportDispatcher.runDispatcher()
        except:
            transportDispatcher.closeDispatcher()
            raise
Exemple #31
0
 def run(self):
     
    transportDispatcher = AsynsockDispatcher()
    transportDispatcher.registerRecvCbFun(trapCallback)
    if self.ipv6:
        transport = udp.Udp6SocketTransport()
        domainName = udp6.domainName
    else:
        transport = udp.UdpSocketTransport()  
        domainName = udp.domainName
            
    try:     
        transportDispatcher.registerTransport(domainName, transport.openServerMode((self.host, self.port)))
  
        transportDispatcher.jobStarted(1)
        # Dispatcher will never finish as job#1 never reaches zero
        transportDispatcher.runDispatcher()     
    except: # catch *all* exceptions
        e = sys.exc_info()[1]
        transportDispatcher.closeDispatcher()
        logging.error("Failed to register transport and run dispatcher: %s" % str(e))
        sys.exit(1)
Exemple #32
0
def main():
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    # global
    global myamqp, transportDispatcher

    # Connect to amqp bus
    logger.debug("Start AMQP ...")
    myamqp = camqp()

    logger.info("Load all MIBs ...")
    for oid in snmp2amqp_conf.mibs.keys():
        mibs[oid] = mib(snmp2amqp_conf.mibs[oid])

    logger.info("Init SNMP listenner ...")
    transportDispatcher = AsynsockDispatcher()

    transportDispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode(
            (snmp2amqp_conf.interface, snmp2amqp_conf.port)))

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

    ## set euid of process
    os.setuid(getpwnam('canopsis')[2])

    myamqp.start()

    logger.info("Wait SNMP traps ...")
    try:
        transportDispatcher.runDispatcher()
    except Exception, err:
        ## Impossible to stop transportDispatcher properly ...
        logger.error(err)
        pass
Exemple #33
0
def main():
	signal.signal(signal.SIGINT, signal_handler)
	signal.signal(signal.SIGTERM, signal_handler)
	
	# global
	global myamqp, transportDispatcher

	# Connect to amqp bus
	logger.debug("Start AMQP ...")
	myamqp = camqp()

	logger.info("Load all MIBs ...")
	for oid in snmp2amqp_conf.mibs.keys():
		mibs[oid] = mib(snmp2amqp_conf.mibs[oid])
	

	logger.info("Init SNMP listenner ...")
	transportDispatcher = AsynsockDispatcher()

	transportDispatcher.registerTransport(
		udp.domainName, udp.UdpSocketTransport().openServerMode((snmp2amqp_conf.interface, snmp2amqp_conf.port))
		)

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

	## set euid of process
	os.setuid(getpwnam('canopsis')[2])

	myamqp.start()

	logger.info("Wait SNMP traps ...")
	try:
		transportDispatcher.runDispatcher()
	except Exception, err:
		## Impossible to stop transportDispatcher properly ...
		logger.error(err)
		pass
Exemple #34
0
class TrapReceiver():
    def __init__(self, conf={}):
        if conf is None or any(conf) == False:
            self.__conf = OpenClosProperty(appName=moduleName).getProperties()
        else:
            self.__conf = conf

        # default value
        self.target = DEFAULT_HOST
        self.port = DEFAULT_PORT

        # validate required parameter
        if 'snmpTrap' in self.__conf and 'openclos_trap_group' in self.__conf[
                'snmpTrap'] and 'target' in self.__conf['snmpTrap'][
                    'openclos_trap_group']:
            self.target = self.__conf['snmpTrap']['openclos_trap_group'][
                'target']
        else:
            logger.info(
                "snmpTrap:openclos_trap_group:target is missing from configuration. using %s"
                % (self.target))

        if 'snmpTrap' in self.__conf and 'openclos_trap_group' in self.__conf[
                'snmpTrap'] and 'port' in self.__conf['snmpTrap'][
                    'openclos_trap_group']:
            self.port = int(
                self.__conf['snmpTrap']['openclos_trap_group']['port'])
        else:
            logger.info(
                "snmpTrap:openclos_trap_group:port is missing from configuration. using %d"
                % (self.port))

        if 'snmpTrap' in self.__conf and 'threadCount' in self.__conf[
                'snmpTrap']:
            self.executor = concurrent.futures.ThreadPoolExecutor(
                max_workers=self.__conf['snmpTrap']['threadCount'])
        else:
            self.executor = concurrent.futures.ThreadPoolExecutor(
                max_workers=DEFAULT_MAX_THREADS)

        # event to stop from sleep
        self.stopEvent = Event()

        self.twoStageConfigurationCallback = util.getTwoStageConfigurationCallback(
            self.__conf)

    def threadFunction(self):
        self.transportDispatcher = AsynsockDispatcher()

        self.transportDispatcher.registerRecvCbFun(onTrap)

        # UDP/IPv4
        self.transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openServerMode((self.target, self.port)))

        self.transportDispatcher.jobStarted(1)

        try:
            # Dispatcher will never finish as job#1 never reaches zero
            self.transportDispatcher.runDispatcher()
        except Exception as exc:
            logger.error("Encounted error '%s' on trap receiver %s:%d" %
                         (exc, self.target, self.port))
            self.transportDispatcher.closeDispatcher()
            raise TrapDaemonError(
                "Trap receiver %s:%d" % (self.target, self.port), exc)
        else:
            self.transportDispatcher.closeDispatcher()

    def start(self):
        logger.info("Starting trap receiver...")
        self.thread = Thread(target=self.threadFunction, args=())
        self.thread.start()
        logger.info("Trap receiver started on %s:%d" %
                    (self.target, self.port))

    def stop(self):
        logger.info("Stopping trap receiver...")
        self.stopEvent.set()
        self.executor.shutdown()
        self.transportDispatcher.jobFinished(1)
        self.thread.join()
        logger.info("Trap receiver stopped")
Exemple #35
0
                    )
                )
                print('Uptime: %s' % (
                    pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint()
                    )
                )
                varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
            else:
                varBinds = pMod.apiPDU.getVarBindList(reqPDU)
            print('Var-binds:')
            for oid, val in varBinds:
                print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))#打印具体的Trap信息内容
    return wholeMsg

transportDispatcher = AsynsockDispatcher()#创建实例

transportDispatcher.registerRecvCbFun(cbFun)#调用处理Trap信息的函数

# UDP/IPv4
transportDispatcher.registerTransport(
    udp.domainName, udp.UdpSocketTransport().openServerMode(('202.100.1.138', 162))#绑定到本地地址与UDP/162号端口
)

transportDispatcher.jobStarted(1)#开始工作

try:
    # Dispatcher will never finish as job#1 never reaches zero
    transportDispatcher.runDispatcher()#运行
except:
    transportDispatcher.closeDispatcher()
    raise
class TrapReceiver:

    def __init__(self, rcv_ip, box_ip, event_name, port=162, inform=None):
	    
        
        
        self.rcvr_ip = rcv_ip
	   
        self.port = port
        self.box_ip = box_ip
        self.event_name = event_name
        self.gen_trap = GenerateTrap(self.box_ip)
        self.inform = inform


    def cbFun(self, transportDispatcher, transportDomain,
            cbCtx, wholeMsg, ):

        print "cbCtx :", cbCtx

        msgVer = int(api.decodeMessageVersion(wholeMsg))
	    #print "Inisde CB FUN..."
           
        
        print 'Inside CB FUN....'

        if msgVer in api.protoModules:
            pMod = api.protoModules[msgVer]
    	else:
            print('Unsupported SNMP version %s' % msgVer)
            #return
    	
        reqMsg, wholeMsg = decoder.decode(
            wholeMsg, asn1Spec=pMod.Message(),
    	)

        self.req = reqMsg

        print 'Type :', type(self.req)

        print 'Inform :', self.inform

        if self.inform:
            print 'Inside Inform IF........'
            if not 'InformRequestPDU()' in str(self.req):
                print 'Inform Message is not sent....failed...'



        print 'reqMsg : %s' % self.req
        #print 'wholeMsg : %s' % wholeMsg

    	#print('Notification message from %s:%s: ' % (
        #    transportDomain, transportAddress
        #    )
    	#)
    	reqPDU = pMod.apiMessage.getPDU(reqMsg)

        print ',,,,reqPDU : %s' % reqPDU
    	varBinds = pMod.apiPDU.getVarBindList(reqPDU)
    	#transportDispatcher.jobFinished(1)
	    
        self.terminationRequestedFlag = True
        if msgVer == api.protoVersion1:
	        self.varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
	        self.specificTrap = pMod.apiTrapPDU.getSpecificTrap(reqPDU).prettyPrint()
	        self.version = 1 
	    
        if msgVer == api.protoVersion2c:
	        self.varBinds = pMod.apiPDU.getVarBindList(reqPDU)
	        self.specificTrap = None	
	        self.version = 2


    def timerCb(self, timeNow=10):
	    print "Inside Timer CB..."
	    if self.terminationRequestedFlag: 
	        print "Finishing the Job..."
	        self.transportDispatcher.jobFinished(1)
	    else:
	        self.terminationRequestedFlag = True


    def trap_listener(self):
	    #print "RECEIVER IP:", self.rcvr_ip 
    	self.transportDispatcher = AsynsockDispatcher()
        self.terminationRequestedFlag = False
	    #print "TER FLAG:", self.terminationRequestedFlag

    	self.transportDispatcher.registerRecvCbFun(self.cbFun)
        self.transportDispatcher.registerTimerCbFun(self.timerCb)
    	self.transportDispatcher.registerTransport(udp.domainName,
            udp.UdpSocketTransport().openServerMode(("%s" % self.rcvr_ip, 162))
    	)
        #time.sleep(1)


        # Generate the trap for the given Event.
        self.gen_trap.generate_trap(self.event_name)


    	self.transportDispatcher.jobStarted(1)
        print "Run Dispatcher...."
        self.transportDispatcher.runDispatcher()
        print "Close Dispatcher...."
        self.transportDispatcher.closeDispatcher()
        print "\n"

        #print "varBinds : ", self.varBinds
        #print "Version : ", self.version
        #print "specificTrap : ", self.specificTrap 


        return self.varBinds, self.specificTrap, self.version 
Exemple #37
0
class SnmpdThread(threading.Thread):
    """This thread is started at configuration time from the
    `mail:queuedDelivery` directive handler.
    this thread will handle all the incomming snmptraps
    """
    implements(IDataManager)

    database = None
    log = logging.getLogger("SnmpdThread")
    __stopped = False

    def __init__(self):
        self.log.info("started (org)")
        # Use the default thread transaction manager.
        try:
            self.transaction_manager = transaction.manager
            self.interaction = ParanoidSecurityPolicy(SystemSnmpdParticipation())
            self.transportDispatcher = AsynsockDispatcher()
            self.transportDispatcher.registerTransport(
                #    udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 162))
                udp.domainName, udp.UdpSocketTransport().openServerMode(('', 11162))
            )
            self.transportDispatcher.registerRecvCbFun(self.cbFun)
            self.transportDispatcher.jobStarted(1) # this job would never finish
        except:
            # TODO: don't do this
            pass
        threading.Thread.__init__(self)

    def run(self, forever=True):
        """ forever loop which will run the snmptrapd dispatcher """
        atexit.register(self.stop)
        while not self.__stopped:
            if self.transportDispatcher is not None:
                self.transportDispatcher.runDispatcher()
            if forever:
                time.sleep(1)
            else:
                break

    def stop(self):
        """ stop the displatcher """
        self.log.info("stopped (org)")
        self.__stopped = True

    def cbFun(self, transportDispatcher, transportDomain, transportAddress, wholeMsg):
        """ this callback function which will handle the snmptrap message from pysnmp stack """
        while wholeMsg:
            msgVer = int(api.decodeMessageVersion(wholeMsg))
            if api.protoModules.has_key(msgVer):
                pMod = api.protoModules[msgVer]
            else:
                print 'Unsupported SNMP version %s' % msgVer
                return
            reqMsg, wholeMsg = decoder.decode(
                wholeMsg, asn1Spec=pMod.Message(),
                )
            print 'Notification message from %s:%s: ' % (
                transportDomain, transportAddress
                )
            reqPDU = pMod.apiMessage.getPDU(reqMsg)
            if reqPDU.isSameTypeWith(pMod.TrapPDU()):
                if SnmpdThread.database:
                    conn = SnmpdThread.database.open()
                    root = conn.root()
                    root_folder = root['Application']
                    old_site = getSite()
                    setSite(root_folder)
                    my_catalog = zapi.getUtility(ICatalog)
                    search_ip = pMod.apiTrapPDU.getAgentAddr(reqPDU).prettyPrint()
                    search_ip_conv = convertIpV4(search_ip)
                    for result in my_catalog.searchResults(\
                        interface_ip_index=search_ip_conv):
                        parentObj = result.__parent__
                        snmpAdapter = ISnmptrapd(parentObj)
                        snmpAdapter.triggered(reqPDU, msgVer, pMod)
                    setSite(old_site)
                    transaction.commit()
                    conn.close()
        return wholeMsg
Exemple #38
0
class SNMPProcess(threading_tools.process_obj):
    def __init__(self, name, conf_dict, **kwargs):
        self.__snmp_name = name
        self.__log_name, self.__log_destination = (
            conf_dict["LOG_NAME"],
            conf_dict["LOG_DESTINATION"],
        )
        self.__verbose = conf_dict.get("VERBOSE", False)
        self.debug_zmq = conf_dict.get("DEBUG_ZMQ", False)
        threading_tools.process_obj.__init__(self, name, busy_loop=True)
        if kwargs.get("ignore_signals", False):
            signal.signal(signal.SIGTERM, signal.SIG_IGN)

    def process_init(self):
        self.__log_template = logging_tools.get_logger(
            self.__log_name,
            self.__log_destination,
            zmq=True,
            context=self.zmq_context)
        self.__return_proc_name = None
        self.register_func("fetch_snmp", self._fetch_snmp)
        self.register_func("register_return", self._register_return)
        self.register_func("trigger_timeout", self._trigger_timeout)
        self._init_dispatcher()
        self.__job_dict = {}
        self.__envelope_dict = {}
        self.__req_id_lut = {}

    def log(self, what, log_level=logging_tools.LOG_LEVEL_OK):
        self.__log_template.log(log_level, what)

    def _init_dispatcher(self):
        self.log("init snmp_session object")
        self.__disp = AsynsockDispatcher()
        self.__disp.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openClientMode())
        self.__disp.registerRecvCbFun(self._recv_func)
        self.__disp.registerTimerCbFun(self._timer_func)
        self.v1_decoder = api.protoModules[api.protoVersion1]
        self.v2c_decoder = api.protoModules[api.protoVersion2c]

    def register_batch(self, cur_batch):
        if self.__verbose > 3:
            self.log("registered new batch {:d}".format(cur_batch.key))
        self.__job_dict[cur_batch.key] = cur_batch
        self.__disp.jobStarted(cur_batch.key)

    def unregister_batch(self, cur_batch):
        # ids we will no longer handle because of finish
        to_keys = [
            key for key, value in self.__req_id_lut.iteritems()
            if value == cur_batch
        ]
        if to_keys:
            for to_key in to_keys:
                del self.__req_id_lut[to_key]
            if self.__verbose > 3:
                cur_batch.log(
                    "removed {} for batch {}".format(
                        logging_tools.get_plural("request ID", len(to_keys)),
                        cur_batch,
                    ), )
        del self.__job_dict[cur_batch.key]
        del self.__envelope_dict[cur_batch.envelope]
        self.__disp.jobFinished(cur_batch.key)

    def loop(self):
        try:
            while self["run_flag"]:
                self.__disp.runDispatcher()
                self.step(blocking=self["run_flag"])
        except ValueConstraintError:
            self.log("caught ValueConstraintError, terminating process",
                     logging_tools.LOG_LEVEL_CRITICAL)
            _term_cause = "ValueConstraintError"
        except:
            exc_info = process_tools.exception_info()
            self.log("exception in dispatcher, terminating process",
                     logging_tools.LOG_LEVEL_CRITICAL)
            for log_line in exc_info.log_lines:
                self.log(" - {}".format(log_line),
                         logging_tools.LOG_LEVEL_CRITICAL)
            _term_cause = "internal error"
        else:
            self.log("no more jobs running")
            _term_cause = ""
        self.log("jobs pending: {:d}".format(len(self.__job_dict)))
        # close all jobs
        if _term_cause:
            self._terminate_jobs(error="{}, check logs".format(_term_cause))
        else:
            self._terminate_jobs()
        self.__disp.closeDispatcher()

    def _inject(self, cur_batch):
        try:
            next_tuple = cur_batch.iterator.next()
        except StopIteration:
            cur_batch.finish()
        else:
            self.send_next(cur_batch, next_tuple)

    def send_next(self, cur_batch, next_tuple):
        self.__req_id_lut[cur_batch.request_id] = cur_batch
        self.__disp.sendMessage(*next_tuple)

    def _register_return(self, proc_name, **kwargs):
        self.__return_proc_name = proc_name
        self.send_pool_message("hellox",
                               "hello2",
                               "hello3",
                               target=self.__return_proc_name)

    def _fetch_snmp(self, *scheme_data, **kwargs):
        new_batch = SNMPBatch(self,
                              *scheme_data,
                              verbose=self.__verbose,
                              **kwargs)
        self.__envelope_dict[new_batch.envelope] = new_batch
        self._inject(new_batch)

    def _trigger_timeout(self, *args, **kwargs):
        batch_id = args[0]
        if batch_id in self.__envelope_dict:
            self.log("triggering timeout for batch_id {}".format(batch_id),
                     logging_tools.LOG_LEVEL_WARN)
            self.__envelope_dict[batch_id].trigger_timeout()
        else:
            self.log("unknown batch_id {}".format(batch_id),
                     logging_tools.LOG_LEVEL_ERROR)

    def _timer_func(self, act_time):
        timed_out = [
            key for key, cur_job in self.__job_dict.iteritems()
            if cur_job.timer_func(act_time)
        ]
        for to_key in timed_out:
            self.__job_dict[to_key].finish()
        self.step()
        if self["exit_requested"]:
            self._terminate_jobs(error="exit requested")

    def _terminate_jobs(self, **kwargs):
        _stop_keys = set(self.__job_dict.keys())
        for _key in _stop_keys:
            if "error" in kwargs:
                self.__job_dict[_key].add_error(kwargs["error"])
            self.__job_dict[_key].finish()

    def _recv_func(self, disp, domain, address, whole_msg):
        while whole_msg:
            # rsp_msg, whole_msg = decoder.decode(whole_msg, asn1Spec=self.__p_mod.Message())
            try:
                rsp_msg, whole_msg = decoder.decode(
                    whole_msg, asn1Spec=self.v2c_decoder.Message())
            except:
                self.log(
                    "error decoding message from {}: {}".format(
                        address, process_tools.get_except_info()),
                    logging_tools.LOG_LEVEL_CRITICAL)
                # send meaningfull error message to client ? TODO, FIXME
                whole_msg = None
            else:
                # rsp_pdu = self.__p_mod.apiMessage.getPDU(rsp_msg)
                rsp_pdu = self.v2c_decoder.apiMessage.getPDU(rsp_msg)
                cur_id = self.v2c_decoder.apiPDU.getRequestID(rsp_pdu)
                if cur_id in self.__req_id_lut:
                    self.__req_id_lut[cur_id].feed_pdu(disp, domain, address,
                                                       rsp_pdu)
                else:
                    self.log("id {} in response not known".format(cur_id))
                if cur_id in self.__req_id_lut:
                    del self.__req_id_lut[cur_id]
        return whole_msg

    def loop_post(self):
        self.__log_template.close()

    def send_return(self, envelope, error_list, received, snmp):
        self.send_pool_message("snmp_finished",
                               envelope,
                               error_list,
                               received,
                               snmp,
                               target=self.__return_proc_name
                               or DEFAULT_RETURN_NAME)
Exemple #39
0
class SnmpServer(threading.Thread):
    def __init__(self, address):
        threading.Thread.__init__(self)
        self._address = address
        self._transportDispatcher = AsynsockDispatcher()
        self._transportDispatcher.registerRecvCbFun(self.onSnmpMessage)

    def run(self):
        self._transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openServerMode(self._address))
        getLogger().info("Now listening on %s:%s" % self._address)
        self._transportDispatcher.jobStarted(1)
        try:
            self._transportDispatcher.runDispatcher(timeout=1)
        except Exception as e:
            getLogger().error(u"Error while handling an SNMP message: %s" %
                              unicode(e))

    def stop(self):
        self._transportDispatcher.jobFinished(1)
        self._transportDispatcher.closeDispatcher()
        self.join()

    # Main handler, called when receiving an SNMP request
    def onSnmpMessage(self, transportDispatcher, transportDomain,
                      transportAddress, wholeMsg):
        while wholeMsg:
            msgVer = api.decodeMessageVersion(wholeMsg)
            if api.protoModules.has_key(msgVer):
                pMod = api.protoModules[msgVer]
            else:
                getLogger().error('Unsupported SNMP version %s' % msgVer)
                return
            reqMsg, wholeMsg = decoder.decode(
                wholeMsg,
                asn1Spec=pMod.Message(),
            )
            rspMsg = pMod.apiMessage.getResponse(reqMsg)
            rspPDU = pMod.apiMessage.getPDU(rspMsg)
            reqPDU = pMod.apiMessage.getPDU(reqMsg)
            varBinds = []
            errorIndex = -1

            # GET request
            if reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
                getLogger().info("SNMP GET received...")
                for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                    getLogger().debug("Trying to GET %s... " %
                                      oidToString(oid))
                    if mibVariablesByOid.has_key(oid):
                        varBinds.append((oid, mibVariablesByOid[oid](msgVer)))
                    else:
                        # No such instance
                        pMod.apiPDU.setNoSuchInstanceError(rspPDU, errorIndex)
                        varBinds = pMod.apiPDU.getVarBinds(reqPDU)
                        break

            # GET-NEXT request
            elif reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
                getLogger().info("SNMP GET-NEXT received...")
                # Produce response var-binds
                errorIndex = -1
                for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                    getLogger().debug("Trying to GET-NEXT %s... " %
                                      oidToString(oid))
                    errorIndex = errorIndex + 1
                    # Search next OID to report
                    nextIdx = bisect.bisect(mibVariables, oid)
                    if nextIdx == len(mibVariables):
                        # Out of MIB
                        pMod.apiPDU.setEndOfMibError(rspPDU, errorIndex)
                    else:
                        # Report value if OID is found
                        varBinds.append((mibVariables[nextIdx].oid,
                                         mibVariables[nextIdx](msgVer)))

            else:
                getLogger().error("Unsupported SNMP request received...")
                # Report unsupported request type
                pMod.apiPDU.setErrorStatus(
                    rspPDU, -1)  # we should use something different from -1

            pMod.apiPDU.setVarBinds(rspPDU, varBinds)
            transportDispatcher.sendMessage(encoder.encode(rspMsg),
                                            transportDomain, transportAddress)
        return wholeMsg
Exemple #40
0
class Agent(object):
    def __init__(self, host, port):
        self._mibInstr = []
        self._mibInstrIdx = {}
        self._transportDispatcher = AsynsockDispatcher()
        self.host = host
        self.port = port

    def prepare(self):
        address = (self.host, self.port)
        transportDispatcher = self._transportDispatcher
        transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openServerMode(address))
        transportDispatcher.registerRecvCbFun(self.cbFun)
        transportDispatcher.jobStarted(1)

    def start(self):
        try:
            self._transportDispatcher.runDispatcher()
        except select.error:
            pass

    def stop(self):
        self._transportDispatcher.closeDispatcher()

    def registerInstr(self, instr):
        assert callable(instr)
        self._mibInstr.append(instr)
        self._mibInstrIdx[instr.name] = instr

    def cbFun(self, transportDispatcher, transportDomain, transportAddress, wholeMsg):
        mibInstr = self._mibInstr
        mibInstrIdx = self._mibInstrIdx
        while wholeMsg:
            msgVer = api.decodeMessageVersion(wholeMsg)
            if msgVer in api.protoModules:
                pMod = api.protoModules[msgVer]
            else:
                return
            reqMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
            rspMsg = pMod.apiMessage.getResponse(reqMsg)
            rspPDU = pMod.apiMessage.getPDU(rspMsg)
            reqPDU = pMod.apiMessage.getPDU(reqMsg)
            varBinds = []
            errorIndex = -1
            # GETNEXT PDU
            if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
                # Produce response var-binds
                errorIndex = -1
                for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                    errorIndex = errorIndex + 1
                    # Search next OID to report
                    nextIdx = bisect.bisect(mibInstr, oid)
                    if nextIdx == len(mibInstr):
                        # Out of MIB
                        pMod.apiPDU.setEndOfMibError(rspPDU, errorIndex)
                    else:
                        # Report value if OID is found
                        varBinds.append((mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer)))
            elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
                for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                    if oid in mibInstrIdx:
                        varBinds.append((oid, mibInstrIdx[oid](msgVer)))
                    else:
                        # No such instance
                        try:
                            pMod.apiPDU.setNoSuchInstanceError(rspPDU, errorIndex)
                        except IndexError:
                            pass
                        varBinds = pMod.apiPDU.getVarBinds(reqPDU)
                        break
            else:
                # Report unsupported request type
                pMod.apiPDU.setErrorStatus(rspPDU, "genErr")
            pMod.apiPDU.setVarBinds(rspPDU, varBinds)
            transportDispatcher.sendMessage(encoder.encode(rspMsg), transportDomain, transportAddress)
        return wholeMsg
Exemple #41
0
    def update(self):
        """Called by the processing thread to trigger an update of the data"""
        ip = self._ip
        hostname = self._hostname
        
        # Grab the lock
        lock = self.lock
        lock.acquire()
        try:
            # Retrieve locally available information
            self.activeRevision = getActiveRevision(hostname)
            self.generatedRevision = getGeneratedRevision(self._hostname)
            # Check that the host is reachable
            if not isHostUp(ip):
                self.reachable = False
                self.lastCheckedAt = time.time()
                self.attempt+=1
                return
            self.reachable = True
            # Retrieve host status information
            pMod = api.protoModules[api.protoVersion1]
            reqPDU =  pMod.GetRequestPDU()
            pMod.apiPDU.setDefaults(reqPDU)
            pMod.apiPDU.setVarBinds(
                    reqPDU, ((CCS_REVISION_OID, pMod.Null()),
                        (LOAD_AVG1_OID, pMod.Null()),
                        (LOAD_AVG5_OID, pMod.Null()),
                        (LOAD_AVG15_OID, pMod.Null()),
                        (UPTIME_OID, pMod.Null())
                        )
                    )
            # Build message
            reqMsg = pMod.Message()
            pMod.apiMessage.setDefaults(reqMsg)
            pMod.apiMessage.setCommunity(reqMsg, 'public')
            pMod.apiMessage.setPDU(reqMsg, reqPDU)
            # Dispatch Request
            transportDispatcher = AsynsockDispatcher()
            transportDispatcher.registerTransport(
                    udp.domainName, udp.UdpSocketTransport().openClientMode()
            )

            startedAt = time.time()
            def cbTimerFun(timeNow):
                if timeNow - startedAt > 3:
                    transportDispatcher.jobFinished(1)
                    transportDispatcher.closeDispatcher()
                    self.attempt+=1
                    log_warn("Timeout fetching status from %s. Attempt #%s" % 
                        (hostname, self.attempt))

            def cbRecvFun(transportDispatcher, transportDomain, \
                    transportAddress, wholeMsg, reqPDU=reqPDU):
                while wholeMsg:
                    rspMsg, wholeMsg = decoder.decode(wholeMsg, \
                            asn1Spec=pMod.Message())
                    rspPDU = pMod.apiMessage.getPDU(rspMsg)
                    # Match response to request
                    if pMod.apiPDU.getRequestID(reqPDU) == \
                            pMod.apiPDU.getRequestID(rspPDU):
                        # Check for SNMP errors reported
                        errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
                        if errorStatus:
                            transportDispatcher.jobFinished(1)
                            transportDispatcher.closeDispatcher()
                            raise ccs_status_error(errorStatus.prettyPrint())
                        else:
                            la1 = 0
                            la5 = 0
                            la15 = 0
                            for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
                                if oid == CCS_REVISION_OID:
                                    self.operatingRevision = str(val)
                                    self._parseOperatingRevision()
                                elif oid == LOAD_AVG1_OID:
                                    la1 = val
                                elif oid == LOAD_AVG5_OID:
                                    la5 = val
                                elif oid == LOAD_AVG15_OID:
                                    la15 = val
                                elif oid == UPTIME_OID:
                                    self.uptime = val
                            self.currentLoad = (la1, la5, la15)
                        transportDispatcher.jobFinished(1)
                self.attempt = 0
                return wholeMsg

            transportDispatcher.registerRecvCbFun(cbRecvFun)
            transportDispatcher.registerTimerCbFun(cbTimerFun)
            transportDispatcher.sendMessage(
                    encoder.encode(reqMsg), udp.domainName, (ip, 161)
            )
            transportDispatcher.jobStarted(1)
            transportDispatcher.runDispatcher()
            transportDispatcher.closeDispatcher()
            # Record that the details were updated
            self.infoUpdatedAt = time.time()
            self.lastCheckedAt = time.time()
        finally:
            lock.release()
Exemple #42
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
Exemple #43
0
class TrapReceiver():
    def __init__(self, conf = {}):
        global logger
        if conf is None or any(conf) == False:
            self.__conf = util.loadConfig(appName = moduleName)
        else:
            self.__conf = conf

        logger = logging.getLogger(moduleName)
        # default value
        self.target = DEFAULT_HOST
        self.port = DEFAULT_PORT
        
        # validate required parameter
        if 'snmpTrap' in self.__conf and 'openclos_trap_group' in self.__conf['snmpTrap'] and 'target' in self.__conf['snmpTrap']['openclos_trap_group']:
            self.target = self.__conf['snmpTrap']['openclos_trap_group']['target']
        else:
            logger.info("snmpTrap:openclos_trap_group:target is missing from configuration. using %s" % (self.target))                

        if 'snmpTrap' in self.__conf and 'openclos_trap_group' in self.__conf['snmpTrap'] and 'port' in self.__conf['snmpTrap']['openclos_trap_group']:
            self.port = int(self.__conf['snmpTrap']['openclos_trap_group']['port'])
        else:
            logger.info("snmpTrap:openclos_trap_group:port is missing from configuration. using %d" % (self.port))                
            
        if 'snmpTrap' in self.__conf and 'threadCount' in self.__conf['snmpTrap']:
            self.executor = concurrent.futures.ThreadPoolExecutor(max_workers = self.__conf['snmpTrap']['threadCount'])
        else:
            self.executor = concurrent.futures.ThreadPoolExecutor(max_workers = DEFAULT_MAX_THREADS)

        # event to stop from sleep
        self.stopEvent = Event()
        
        self.twoStageConfigurationCallback = util.getTwoStageConfigurationCallback(self.__conf)
       
    def threadFunction(self):
        self.transportDispatcher = AsynsockDispatcher()

        self.transportDispatcher.registerRecvCbFun(onTrap)
        
        # UDP/IPv4
        self.transportDispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openServerMode((self.target, self.port))
        )

        self.transportDispatcher.jobStarted(1)

        try:
            # Dispatcher will never finish as job#1 never reaches zero
            self.transportDispatcher.runDispatcher()
        except:
            self.transportDispatcher.closeDispatcher()
            raise
        else:
            self.transportDispatcher.closeDispatcher()

    def start(self):
        logger.info("Starting trap receiver...")
        self.thread = Thread(target=self.threadFunction, args=())
        self.thread.start()
        logger.info("Trap receiver started on %s:%d" % (self.target, self.port))

    def stop(self):
        logger.info("Stopping trap receiver...")
        self.stopEvent.set()
        self.executor.shutdown()
        self.transportDispatcher.jobFinished(1)  
        self.thread.join()
        logger.info("Trap receiver stopped")
Exemple #44
0
                    )
                )
                print('Uptime: %s' % (
                    pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint()
                    )
                )
                varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
            else:
                varBinds = pMod.apiPDU.getVarBindList(reqPDU)
            print('Var-binds:')
            for oid, val in varBinds:
                print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))#打印具体的Trap信息内容
    return wholeMsg

transportDispatcher = AsynsockDispatcher()#创建实例

transportDispatcher.registerRecvCbFun(cbFun)#调用处理Trap信息的函数

# UDP/IPv4
transportDispatcher.registerTransport(
    udp.domainName, udp.UdpSocketTransport().openServerMode(('202.100.1.138', 162))#绑定到本地地址与UDP/162号端口
)

transportDispatcher.jobStarted(1)#开始工作

try:
    # Dispatcher will never finish as job#1 never reaches zero
    transportDispatcher.runDispatcher()#运行
except:
    transportDispatcher.closeDispatcher()
    raise
def pollFn():
    #Check the heater status
    errorIndication, errorStatus, errorIndex, varBinds = next(
        getCmd(SnmpEngine(),
            CommunityData('public',mpModel=0),
            UdpTransportTarget(('localhost', 1162)),
            ContextData(),
            ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))
    )

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (
                errorStatus.prettyPrint(),
                errorIndex and varBinds[int(errorIndex)-1][0] or '?'
           )
        )
    else:
        for varBind in varBinds:
            print(' = '.join([ x.prettyPrint() for x in varBind ]))

    # Get the temperature
    errorIndication, errorStatus, errorIndex, varBinds = next(
        getCmd(SnmpEngine(),
            CommunityData('public',mpModel=0),
            UdpTransportTarget(('localhost', 1161)),
            ContextData(),
            ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))
    )

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (
                errorStatus.prettyPrint(),
                errorIndex and varBinds[int(errorIndex)-1][0] or '?'
            )
        )
    else:

        #for varBind in varBinds:
        #    print(' = '.join([ x.prettyPrint() for x in varBind ]))
        #SET Command

        #Check if the temperature is less than 10
        for oid, val in varBinds:
            print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
            returnedVal = int(val)
            if (returnedVal < 10):
                print returnedVal
                # Protocol version to use
                #pMod = api.protoModules[api.protoVersion1]
                pMod = api.protoModules[api.protoVersion2c]

                # Build PDU
                reqPDU =  pMod.SetRequestPDU()
                pMod.apiPDU.setDefaults(reqPDU)
                pMod.apiPDU.setVarBinds(
                    reqPDU,
                    # Change the heater status to ON
                    ( ('1.3.6.1.2.1.1.1.0', pMod.OctetString('ON')),
                     # ('1.3.6.1.2.1.1.3.0', pMod.TimeTicks(12))
                    )
                    )

                # Build message
                reqMsg = pMod.Message()
                pMod.apiMessage.setDefaults(reqMsg)
                pMod.apiMessage.setCommunity(reqMsg, 'public')
                pMod.apiMessage.setPDU(reqMsg, reqPDU)

                startedAt = time()

                def cbTimerFun(timeNow):
                    if timeNow - startedAt > 3:
                        raise Exception("Request timed out")

                def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
                              wholeMsg, reqPDU=reqPDU):
                    while wholeMsg:
                        rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
                        rspPDU = pMod.apiMessage.getPDU(rspMsg)
                        # Match response to request
                        if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
                            # Check for SNMP errors reported
                            errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
                            if errorStatus:
                                print(errorStatus.prettyPrint())
                            else:
                                for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
                                    print('%s = %s' (oid.prettyPrint(), val.prettyPrint()))
                            transportDispatcher.jobFinished(1)
                    return wholeMsg

                transportDispatcher = AsynsockDispatcher()

                transportDispatcher.registerRecvCbFun(cbRecvFun)
                transportDispatcher.registerTimerCbFun(cbTimerFun)

                # UDP/IPv4
                transportDispatcher.registerTransport(
                    udp.domainName, udp.UdpSocketTransport().openClientMode()
                )

                # Pass message to dispatcher
                transportDispatcher.sendMessage(
                    encoder.encode(reqMsg), udp.domainName, ('localhost', 1162)
                )
                transportDispatcher.jobStarted(1)

                # Dispatcher will finish as job#1 counter reaches zero
                transportDispatcher.runDispatcher()

                transportDispatcher.closeDispatcher()
            else:
                print "value greater than 10"
Exemple #46
0
'''
Created on 2012-9-9
@author: zongzong
'''
# Notification Originator Application (TRAP)
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder
from pysnmp.proto import api
# Protocol version to use
verID = api.protoVersion1
pMod = api.protoModules[verID]
# Build PDU
trapPDU = pMod.TrapPDU()
pMod.apiTrapPDU.setDefaults(trapPDU)
# Traps have quite different semantics among proto versions
if verID == api.protoVersion1:
    pMod.apiTrapPDU.setEnterprise(trapPDU, (1, 3, 6, 1, 6, 3, 1, 1, 5, 1))
    pMod.apiTrapPDU.setGenericTrap(trapPDU, 'coldStart')
# Build message
trapMsg = pMod.Message()
pMod.apiMessage.setDefaults(trapMsg)
pMod.apiMessage.setCommunity(trapMsg, 'public')
pMod.apiMessage.setPDU(trapMsg, trapPDU)
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerTransport(
    udp.domainName, udp.UdpSocketTransport().openClientMode()
    )
transportDispatcher.sendMessage(
    encoder.encode(trapMsg), udp.domainName, ('10.8.80.108', 162)
Exemple #47
0
'''
Created on 2012-9-9
@author: zongzong
'''
# Notification Originator Application (TRAP)
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder
from pysnmp.proto import api
# Protocol version to use
verID = api.protoVersion1
pMod = api.protoModules[verID]
# Build PDU
trapPDU = pMod.TrapPDU()
pMod.apiTrapPDU.setDefaults(trapPDU)
# Traps have quite different semantics among proto versions
if verID == api.protoVersion1:
    pMod.apiTrapPDU.setEnterprise(trapPDU, (1, 3, 6, 1, 6, 3, 1, 1, 5, 1))
    pMod.apiTrapPDU.setGenericTrap(trapPDU, 'coldStart')
# Build message
trapMsg = pMod.Message()
pMod.apiMessage.setDefaults(trapMsg)
pMod.apiMessage.setCommunity(trapMsg, 'public')
pMod.apiMessage.setPDU(trapMsg, trapPDU)
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerTransport(
    udp.domainName,
    udp.UdpSocketTransport().openClientMode())
transportDispatcher.sendMessage(encoder.encode(trapMsg), udp.domainName,
                                ('10.8.80.108', 162))
Exemple #48
0
    def start_trap(self, pattern_end_trap, time_end_trap,
                   timeout, port, queue):
        """
            :param pattern_end_trap
               **OPTION** the pattern you are looking for in the trap to
               stop trap. If not defined, trap will be stopped after
               timeout value
            :param time_end_trap
               **OPTION** the time for running trap. Default: 30
            :param timeout
               **OPTION** the timeout for snmp trap. Default: 300.
            :param port
               **OPTION** the port of snmp trap.
            :return:
        """
        t.log("DEBUG", "Entering 'start_trap'\n"+__file__)
        import warnings
        warnings.simplefilter("ignore", ResourceWarning)
        startedat = time.time()
        #global results
        global RESPONSE

        RESPONSE = ''

        def cbfun(transportdispatcher, transportdomain, transportaddress,
                  wholemsg):
            t.log("DEBUG", "Entering 'cbfun'\n"+__file__)
            #global results
            global RESPONSE
            while wholemsg:
                msgver = int(api.decodeMessageVersion(wholemsg))
                if msgver in api.protoModules:
                    pmod = api.protoModules[msgver]
                else:
                    RESPONSE += 'Unsupported SNMP version %s' % msgver
                    return
                reqmsg, wholemsg = decoder.decode(
                    wholemsg, asn1Spec=pmod.Message(),
                    )
                RESPONSE += 'Notification message from %s:%s: \n' % (
                    transportdomain, transportaddress
                    )
                reqpdu = pmod.apiMessage.getPDU(reqmsg)
                if msgver == api.protoVersion1:
                    varbinds = pmod.apiTrapPDU.getVarBindList(reqpdu)
                    RESPONSE += 'Var-binds: \n'
                    for oid, val in varbinds:
                        RESPONSE += '%s = %s \n' % (oid.prettyPrint(),
                                                    val.prettyPrint())
                        if pattern_end_trap and re.search(pattern_end_trap,
                                                          RESPONSE, re.I):
                            transportdispatcher.jobFinished(1)
                            RESPONSE += "Stopped trap \n"

                    RESPONSE += 'Enterprise: %s \n' % (
                        pmod.apiTrapPDU.getEnterprise(reqpdu).prettyPrint()
                        )

                    RESPONSE += 'Agent Address: %s \n' % (
                        pmod.apiTrapPDU.getAgentAddr(reqpdu).prettyPrint()
                        )
                    RESPONSE += 'Generic Trap: %s \n' % (
                        pmod.apiTrapPDU.getGenericTrap(
                            reqpdu).prettyPrint())

                    RESPONSE += 'Specific Trap: %s \n' % (
                        pmod.apiTrapPDU.getSpecificTrap(
                            reqpdu).prettyPrint()
                        )

                    RESPONSE += 'Uptime: %s \n' % (
                        pmod.apiTrapPDU.getTimeStamp(
                            reqpdu).prettyPrint()
                        )
                else:
                    varbinds = pmod.apiPDU.getVarBindList(reqpdu)

        def cbtimerfun(timenow):
            t.log("DEBUG", "Entering 'cbtimerfun'\n"+__file__)
            #global results
            global RESPONSE
            if time_end_trap is not None:
                if timenow - startedat >= time_end_trap:
                    transportdispatcher.jobFinished(1)
                    RESPONSE += "Stopped trap \n"

            if timenow - startedat >= timeout:
                t.log(level="DEBUG", message="Request timed out \n")
                raise Exception("Request timed out \n")

        transportdispatcher = AsynsockDispatcher()
        transportdispatcher.registerRecvCbFun(cbfun)
        transportdispatcher.registerTimerCbFun(cbtimerfun)
        # UDP/IPv4
        transportdispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openServerMode(
                (self.trap_server_v4, port))
        )

        # UDP/IPv6
        transportdispatcher.registerTransport(
            udp6.domainName, udp6.Udp6SocketTransport().openServerMode(
                (self.trap_server_v6, port))
        )

        transportdispatcher.jobStarted(1)

        try:
            # Dispatcher will never finish as job#1 never reaches zero
            transportdispatcher.runDispatcher()
        except:
            transportdispatcher.closeDispatcher()

        queue.put(RESPONSE)
        t.log(level="DEBUG", message="Exiting 'start_trap' with return value/code :\n")
        return
transportDispatcher.jobStarted(1)

'''
## UDP/IPv6 (second copy of the same PDU will be sent)
transportDispatcher.registerTransport(
    udp6.domainName, udp6.Udp6SocketTransport().openClientMode()
)

# Pass message to dispatcher
transportDispatcher.sendMessage(
    encoder.encode(reqMsg), udp6.domainName, ('::1', 161)
)
transportDispatcher.jobStarted(1)
'''

## Local domain socket
#transportDispatcher.registerTransport(
#    unix.domainName, unix.UnixSocketTransport().openClientMode()
#)
#
# Pass message to dispatcher
#transportDispatcher.sendMessage(
#    encoder.encode(reqMsg), unix.domainName, '/tmp/snmp-agent'
#)
#transportDispatcher.jobStarted(1)

# Dispatcher will finish as job#1 counter reaches zero
transportDispatcher.runDispatcher()

transportDispatcher.closeDispatcher()
def main():

    parser = argparse.ArgumentParser(description="HEALTH CHECKER.")
    parser.add_argument("-c",
                        "--config",
                        default="/etc/healthchecker.yaml",
                        help="Path to config file.")
    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        default=0,
                        help="Increase logging verbosity.")
    parser.add_argument("-q",
                        "--quiet",
                        action="count",
                        default=0,
                        help="Decrease logging verbosity.")
    parser.add_argument("-V",
                        "--version",
                        action="version",
                        version="%%(prog)s %s" % __version__,
                        help="Display version information.")

    args = parser.parse_args()

    oid_translate.load_mibs()

    config = Config.from_file(args.config)

    db_host, db_port, db_name, db_user, db_passwd = config.get_database_config(
    )
    db_engine = PooledMySQLDatabase(
        db_name, **{
            'host': db_host,
            'port': db_port,
            'password': db_passwd,
            'user': db_user
        })
    models = [Target, FPingMessage, Device, EventMessage, Port]
    db_engine.bind(models)

    community = config["community"]
    if not community:
        community = None
    ipv6_server = config["ipv6"]
    if not ipv6_server:
        ipv6_server = None

    trap_cb = TrapperCallback(db_engine, config, community)

    logging.basicConfig(
        filename=LOGFILE,
        level=10,  #get_loglevel(args),
        format=LOGFORMAT)

    transport_dispatcher = AsynsockDispatcher()
    transport_dispatcher.registerRecvCbFun(trap_cb)
    if ipv6_server:
        transport_dispatcher.registerTransport(
            udp6.domainName,
            udp6.Udp6SocketTransport().openServerMode(
                ("::1", int(config["trap_port"]))))
    transport_dispatcher.registerTransport(
        udp.domainName,
        udp.UdpSocketTransport().openServerMode(
            ("0.0.0.0", int(config["trap_port"]))))
    transport_dispatcher.jobStarted(1)

    process_count = config['process_count']
    if not process_count:
        process_count = (
            multiprocessing.cpu_count() * 2 +
            1) if (multiprocessing.cpu_count() * 2 + 1) < 11 else 10
    logging.info("multiprocess count is : %s" % process_count)

    fping_count = int(config['fping_count'])
    if not fping_count:
        fping_count = 5
    logging.info("fping count is : %d" % fping_count)

    interval_time = int(config['interval_time'])
    if not interval_time:
        interval_time = 1

    fping_cb = FPingCallback(db_engine)
    scheduler = BackgroundScheduler()
    trigger = IntervalTrigger(minutes=interval_time)  # FIX PYINSTALL BUG
    scheduler.add_job(fping_cb,
                      trigger,
                      args=(process_count, fping_count),
                      max_instances=10)
    #scheduler.add_job(fping_cb, trigger='interval', args=(process_count, fping_count),
    #                  max_instances=10, minutes=interval_time)

    ## syslog service
    host = '127.0.0.1'
    port = 8889
    syslog_service = SyslogService(db_engine, host, port)

    TRAP = False
    try:
        scheduler.start()
        if TRAP:  #TODO new thread
            transport_dispatcher.runDispatcher()
        else:
            #redo_start_time = datetime.datetime.now() + datetime.timedelta(seconds=-20)
            redo_start_time = config.get("redo_start_time")
            if redo_start_time is None:
                redo_start_time = False
            syslog_service.start(redo_start_time)
    except KeyboardInterrupt:
        pass
    finally:
        logging.info("Shutdown Scheduler...")
        scheduler.shutdown()

        if TRAP:
            logging.info("Stopping Transport Dispatcher...")
            transport_dispatcher.closeDispatcher()
        else:
            syslog_service.stop()
        logging.info("Bye")