def sendVarBinds(self, snmpEngine, notificationTarget, contextEngineId, contextName, varBinds=(), cbFun=None, cbCtx=None): debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationTarget %s, contextEngineId %s, ' 'contextName "%s", varBinds %s' % (notificationTarget, contextEngineId or '<default>', contextName, varBinds)) mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if contextName: __SnmpAdminString, = mibBuilder.importSymbols( 'SNMP-FRAMEWORK-MIB', 'SnmpAdminString') contextName = __SnmpAdminString(contextName) # 3.3 notifyTag, notifyType = config.getNotificationInfo( snmpEngine, notificationTarget) notificationHandle = getNextHandle() debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, notifyTag %s, ' 'notifyType %s' % (notificationHandle, notifyTag, notifyType)) varBinds = [(v2c.ObjectIdentifier(x), y) for x, y in varBinds] # 3.3.2 & 3.3.3 snmpTrapOID, sysUpTime = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID', 'sysUpTime') snmpTrapOID = snmpTrapOID.getName() sysUpTime, uptime = sysUpTime.getName(), sysUpTime.getSyntax() # Add sysUpTime if not present already if not varBinds or varBinds[0][0] != sysUpTime: varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime), uptime.clone())) # Search for and reposition sysUpTime if it's elsewhere for idx, varBind in enumerate(varBinds[1:]): if varBind[0] == sysUpTime: varBinds[0] = varBind del varBinds[idx + 1] break if len(varBinds) < 2: raise error.PySnmpError('SNMP notification PDU requires ' 'SNMPv2-MIB::snmpTrapOID.0 to be present') # Search for and reposition snmpTrapOID if it's elsewhere for idx, varBind in enumerate(varBinds[2:]): if varBind[0] == snmpTrapOID: del varBinds[idx + 2] if varBinds[1][0] == snmpTrapOID: varBinds[1] = varBind else: varBinds.insert(1, varBind) break if varBinds[1][0] != snmpTrapOID: raise error.PySnmpError('SNMP notification PDU requires ' 'SNMPv2-MIB::snmpTrapOID.0 to be present') sendRequestHandle = -1 debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: final varBinds %s' % (varBinds, )) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): (transportDomain, transportAddress, timeout, retryCount, params) = config.getTargetAddr(snmpEngine, targetAddrName) (messageProcessingModel, securityModel, securityName, securityLevel) = config.getTargetParams(snmpEngine, params) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # (filterSubtree, filterMask, # filterType) = config.getNotifyFilter(filterProfileName) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, notifyTag %s yields: ' 'transportDomain %s, transportAddress %r, securityModel %s, ' 'securityName %s, securityLevel %s' % (notificationHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) for varName, varVal in varBinds: if varName in (sysUpTime, snmpTrapOID): continue try: snmpEngine.accessControlModel[self.ACM_ID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: ACL succeeded for OID %s securityName %s' % (varName, securityName)) except error.StatusInformation: debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: ACL denied access for OID %s securityName %s,' 'dropping notification' % (varName, securityName)) return # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise error.ProtocolError('Unknown notify-type %r', notifyType) v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # 3.3.5 try: sendRequestHandle = self.sendPdu( snmpEngine, targetAddrName, contextEngineId, contextName, pdu, self.processResponseVarBinds, (notificationHandle, cbFun, cbCtx)) except error.StatusInformation as exc: statusInformation = exc debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: sendRequestHandle %s: sendPdu() failed ' 'with %r' % (sendRequestHandle, statusInformation)) if (notificationHandle not in self.__pendingNotifications or not self.__pendingNotifications[notificationHandle]): if notificationHandle in self.__pendingNotifications: del self.__pendingNotifications[notificationHandle] if cbFun: cbFun(snmpEngine, notificationHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx) return notificationHandle debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, sendRequestHandle %s, ' 'timeout %d' % (notificationHandle, sendRequestHandle, timeout)) if notifyType == 2: if notificationHandle not in self.__pendingNotifications: self.__pendingNotifications[notificationHandle] = set() self.__pendingNotifications[notificationHandle].add( sendRequestHandle) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, sendRequestHandle %s, ' 'notification(s) sent' % (notificationHandle, sendRequestHandle)) return notificationHandle
def sendVarBinds(self, snmpEngine, notificationTarget, contextEngineId, contextName, varBinds=(), cbFun=None, cbCtx=None): debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationTarget %s, contextEngineId %s, contextName "%s", varBinds %s' % (notificationTarget, contextEngineId or '<default>', contextName, varBinds)) if contextName: __SnmpAdminString, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMP-FRAMEWORK-MIB', 'SnmpAdminString') contextName = __SnmpAdminString(contextName) # 3.3 ( notifyTag, notifyType ) = config.getNotificationInfo( snmpEngine, notificationTarget ) notificationHandle = getNextHandle() debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, notifyTag %s, notifyType %s' % (notificationHandle, notifyTag, notifyType)) varBinds = [ (v2c.ObjectIdentifier(x),y) for x,y in varBinds ] # 3.3.2 & 3.3.3 snmpTrapOID, sysUpTime = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpTrapOID', 'sysUpTime') for idx in range(len(varBinds)): if idx and varBinds[idx][0] == sysUpTime.getName(): if varBinds[0][0] == sysUpTime.getName(): varBinds[0] = varBinds[idx] else: varBinds.insert(0, varBinds[idx]) del varBinds[idx] if varBinds[0][0] != sysUpTime.getName(): varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime.getName()), sysUpTime.getSyntax().clone())) if len(varBinds) < 2 or varBinds[1][0] != snmpTrapOID.getName(): varBinds.insert(1, (v2c.ObjectIdentifier(snmpTrapOID.getName()), snmpTrapOID.getSyntax())) debug.logger & debug.flagApp and debug.logger('sendVarBinds: final varBinds %s' % (varBinds,)) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): ( transportDomain, transportAddress, timeout, retryCount, params ) = config.getTargetAddr(snmpEngine, targetAddrName) ( messageProcessingModel, securityModel, securityName, securityLevel ) = config.getTargetParams(snmpEngine, params) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (notificationHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) for varName, varVal in varBinds: if varName in (sysUpTime.name, snmpTrapOID.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL succeeded for OID %s securityName %s' % (varName, securityName)) except error.StatusInformation: debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL denied access for OID %s securityName %s, droppping notification' % (varName, securityName)) return # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise error.ProtocolError('Unknown notify-type %r', notifyType) v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # 3.3.5 try: sendRequestHandle = self.sendPdu(snmpEngine, targetAddrName, contextEngineId, contextName, pdu, self.processResponseVarBinds, (notificationHandle, cbFun, cbCtx)) except error.StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s: sendPdu() failed with %r' % (sendRequestHandle, statusInformation)) if notificationHandle not in self.__pendingNotifications or \ not self.__pendingNotifications[notificationHandle]: if notificationHandle in self.__pendingNotifications: del self.__pendingNotifications[notificationHandle] cbFun(snmpEngine, notificationHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx) return notificationHandle debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, sendRequestHandle %s, timeout %d' % (notificationHandle, sendRequestHandle, timeout)) if notifyType == 2: if notificationHandle not in self.__pendingNotifications: self.__pendingNotifications[notificationHandle] = set() self.__pendingNotifications[notificationHandle].add(sendRequestHandle) debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationHandle %s, sendRequestHandle %s, notification(s) sent' % (notificationHandle, sendRequestHandle)) return notificationHandle
def sendNotification(self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=None, cbFun=None, cbCtx=None, contextName=null): # 3.3 (notifyTag, notifyType) = config.getNotificationInfo(snmpEngine, notificationTarget) metaSendPduHandle = getNextHandle() debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notifyTag %s, notifyType %s' % (metaSendPduHandle, notifyTag, notifyType)) contextMibInstrumCtl = self.__context.getMibInstrum(contextName) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): (transportDomain, transportAddress, timeout, retryCount, params) = config.getTargetAddr(snmpEngine, targetAddrName) (messageProcessingModel, securityModel, securityName, securityLevel) = config.getTargetParams(snmpEngine, params) debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (metaSendPduHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'sysUpTime') if additionalVarBinds: for varName, varVal in additionalVarBinds: if varName == sysUpTime.name: varBinds.append((varName, varVal)) break if not varBinds: varBinds.append((sysUpTime.name, sysUpTime.syntax.clone())) # for actual value snmpTrapOid, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID') if notificationName: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName))) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) # XXX it's still not clear how to instantiate OBJECTS clause # # Get notification objects names # for notificationObject in snmpTrapVal.getObjects(): # mibNode, = contextMibInstrumCtl.mibBuilder.importSymbols( # *notificationObject # ) # try: # objectInstance = mibNode.getNode(mibNode.name + (0,)) # except error.SmiError: # return # varBinds.append((objectInstance.name, objectInstance.syntax)) for varName, varVal in additionalVarBinds: if varName in (sysUpTime.name, snmpTrapOid.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName) except error.SmiError: debug.logger & debug.flagApp and debug.logger( 'sendNotification: OID %s not allowed for %s, droppping notification' % (varName, securityName)) return else: varBinds.append((varName, varVal)) # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: pdu = rfc2576.v2ToV1(pdu) pduVersion = 0 else: pduVersion = 1 # 3.3.5 if notifyType == 1: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, None) else: # Convert timeout in seconds into timeout in timer ticks timeoutInTicks = float( timeout ) / 100 / snmpEngine.transportDispatcher.getTimerResolution() # 3.3.6a sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, 1, # expectResponse timeoutInTicks, self.processResponsePdu, (cbFun, cbCtx)) debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, sendPduHandle %s, timeout %d' % (metaSendPduHandle, sendPduHandle, timeout)) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, timeout, retryCount, 1, metaSendPduHandle) if metaSendPduHandle not in self.__pendingNotifications: self.__pendingNotifications[metaSendPduHandle] = 0 self.__pendingNotifications[metaSendPduHandle] += 1 snmpEngine.transportDispatcher.jobStarted(id(self)) debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notification(s) sent' % metaSendPduHandle) return metaSendPduHandle
def sendNotification( self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=None, cbFun=None, cbCtx=None, contextName='' ): # 3.3 ( notifyTag, notifyType ) = config.getNotificationInfo( snmpEngine, notificationTarget ) contextMibInstrumCtl = self.__context.getMibInstrum( contextName ) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): ( transportDomain, transportAddress, timeout, retryCount, params ) = config.getTargetAddr(snmpEngine, targetAddrName) ( messageProcessingModel, securityModel, securityName, securityLevel ) = config.getTargetParams(snmpEngine, params) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'sysUpTime' ) varBinds.append( (sysUpTime.name, sysUpTime.syntax.clone()) # for actual value ) snmpTrapOid, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID' ) if notificationName: varBinds.append( (snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName)) ) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) # XXX it's still not clear how to instantiate OBJECTS clause # # Get notification objects names # for notificationObject in snmpTrapVal.getObjects(): # mibNode, = apply( # contextMibInstrumCtl.mibBuilder.importSymbols, # notificationObject # ) # try: # objectInstance = mibNode.getNode(mibNode.name + (0,)) # except error.SmiError: # return # varBinds.append((objectInstance.name, objectInstance.syntax)) if additionalVarBinds: if version_info < (1, 6): additionalVarBinds = list(additionalVarBinds) varBinds.extend(additionalVarBinds) for varName, varVal in varBinds: try: snmpEngine.accessControlModel[vacmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) except error.SmiError: return # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: pdu = rfc2576.v2ToV1(pdu) pduVersion = 0 else: pduVersion = 1 # 3.3.5 if notifyType == 1: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, None ) else: # 3.3.6a sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, (self.processResponsePdu, float(timeout)/100 + time.time(), (cbFun, cbCtx)) ) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, timeout, retryCount, 1, getNextHandle() ) snmpEngine.transportDispatcher.jobStarted(id(self))
def sendNotification( self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=(), cbFun=None, cbCtx=None, contextName=null, instanceIndex=None ): debug.logger & debug.flagApp and debug.logger('sendNotification: notificationTarget %s, notificationName %s, additionalVarBinds %s, contextName "%s", instanceIndex %s' % (notificationTarget, notificationName, additionalVarBinds, contextName, instanceIndex)) if contextName: __SnmpAdminString, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMP-FRAMEWORK-MIB', 'SnmpAdminString') contextName = __SnmpAdminString(contextName) # 3.3 ( notifyTag, notifyType ) = config.getNotificationInfo( snmpEngine, notificationTarget ) metaSendPduHandle = getNextHandle() debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notifyTag %s, notifyType %s' % (metaSendPduHandle, notifyTag, notifyType)) contextMibInstrumCtl = self.snmpContext.getMibInstrum(contextName) additionalVarBinds = [ (v2c.ObjectIdentifier(x),y) for x,y in additionalVarBinds ] for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): ( transportDomain, transportAddress, timeout, retryCount, params ) = config.getTargetAddr(snmpEngine, targetAddrName) ( messageProcessingModel, securityModel, securityName, securityLevel ) = config.getTargetParams(snmpEngine, params) debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (metaSendPduHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'sysUpTime') for varName, varVal in additionalVarBinds: if varName == sysUpTime.name: varBinds.append((varName, varVal)) break if not varBinds: varBinds.append((sysUpTime.name, sysUpTime.syntax.clone())) # for actual value snmpTrapOid, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpTrapOID') if len(notificationName) == 2: # ('MIB', 'symbol') notificationTypeObject, = contextMibInstrumCtl.mibBuilder.importSymbols(*notificationName) varBinds.append((snmpTrapOid.name, v2c.ObjectIdentifier(notificationTypeObject.name))) debug.logger & debug.flagApp and debug.logger('sendNotification: notification type object is %s' % notificationTypeObject) for notificationObject in notificationTypeObject.getObjects(): mibNode, = contextMibInstrumCtl.mibBuilder.importSymbols(*notificationObject) if instanceIndex: mibNode = mibNode.getNode(mibNode.name + instanceIndex) else: mibNode = mibNode.getNextNode(mibNode.name) varBinds.append((mibNode.name, mibNode.syntax)) debug.logger & debug.flagApp and debug.logger('sendNotification: processed notification object %s, instance index %s, var-bind %s' % (notificationObject, instanceIndex is None and "<first>" or instanceIndex, mibNode)) elif notificationName: # numeric OID varBinds.append( (snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName)) ) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) for varName, varVal in additionalVarBinds: if varName in (sysUpTime.name, snmpTrapOid.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) except error.StatusInformation: debug.logger & debug.flagApp and debug.logger('sendNotification: OID %s not allowed for %s, droppping notification' % (varName, securityName)) return else: varBinds.append((varName, varVal)) # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: reqPDU = rfc2576.v2ToV1(pdu) pduVersion = 0 else: reqPDU = pdu pduVersion = 1 # 3.3.5 if notifyType == 1: try: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pduVersion, reqPDU, None ) except error.StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger('sendReq: metaSendPduHandle %s: sendPdu() failed with %r' % (metaSendPduHandle, statusInformation)) if not self.__pendingNotifications[metaSendPduHandle]: del self.__pendingNotifications[metaSendPduHandle] self._handleResponse( metaSendPduHandle, statusInformation['errorIndication'], 0, 0, (), cbFun, cbCtx ) return metaSendPduHandle else: # Convert timeout in seconds into timeout in timer ticks timeoutInTicks = float(timeout)/100/snmpEngine.transportDispatcher.getTimerResolution() # 3.3.6a try: sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pduVersion, reqPDU, 1, # expectResponse timeoutInTicks, self.processResponsePdu, (cbFun, cbCtx) ) except error.StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger('sendReq: metaSendPduHandle %s: sendPdu() failed with %r' % (metaSendPduHandle, statusInformation)) if not self.__pendingNotifications[metaSendPduHandle]: del self.__pendingNotifications[metaSendPduHandle] self._handleResponse( metaSendPduHandle, statusInformation['errorIndication'], 0, 0, (), cbFun, cbCtx ) return metaSendPduHandle debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, sendPduHandle %s, timeout %d' % (metaSendPduHandle, sendPduHandle, timeout)) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pdu, timeout, retryCount, 1, metaSendPduHandle ) if metaSendPduHandle not in self.__pendingNotifications: self.__pendingNotifications[metaSendPduHandle] = 0 self.__pendingNotifications[metaSendPduHandle] += 1 snmpEngine.transportDispatcher.jobStarted(id(self)) debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notification(s) sent' % metaSendPduHandle) return metaSendPduHandle
def sendVarBinds(self, snmpEngine, notificationTarget, contextEngineId, contextName, varBinds=(), cbFun=None, cbCtx=None): debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationTarget %s, contextEngineId %s, ' 'contextName "%s", varBinds %s' % ( notificationTarget, contextEngineId or '<default>', contextName, varBinds)) mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if contextName: __SnmpAdminString, = mibBuilder.importSymbols( 'SNMP-FRAMEWORK-MIB', 'SnmpAdminString') contextName = __SnmpAdminString(contextName) # 3.3 notifyTag, notifyType = config.getNotificationInfo( snmpEngine, notificationTarget) notificationHandle = getNextHandle() debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, notifyTag %s, ' 'notifyType %s' % (notificationHandle, notifyTag, notifyType)) varBinds = [(v2c.ObjectIdentifier(x), y) for x, y in varBinds] # 3.3.2 & 3.3.3 snmpTrapOID, sysUpTime = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID', 'sysUpTime') snmpTrapOID = snmpTrapOID.getName() sysUpTime, uptime = sysUpTime.getName(), sysUpTime.getSyntax() # Add sysUpTime if not present already if not varBinds or varBinds[0][0] != sysUpTime: varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime), uptime.clone())) # Search for and reposition sysUpTime if it's elsewhere for idx, varBind in enumerate(varBinds[1:]): if varBind[0] == sysUpTime: varBinds[0] = varBind del varBinds[idx + 1] break if len(varBinds) < 2: raise error.PySnmpError('SNMP notification PDU requires ' 'SNMPv2-MIB::snmpTrapOID.0 to be present') # Search for and reposition snmpTrapOID if it's elsewhere for idx, varBind in enumerate(varBinds[2:]): if varBind[0] == snmpTrapOID: del varBinds[idx + 2] if varBinds[1][0] == snmpTrapOID: varBinds[1] = varBind else: varBinds.insert(1, varBind) break if varBinds[1][0] != snmpTrapOID: raise error.PySnmpError('SNMP notification PDU requires ' 'SNMPv2-MIB::snmpTrapOID.0 to be present') sendRequestHandle = -1 debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: final varBinds %s' % (varBinds,)) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): (transportDomain, transportAddress, timeout, retryCount, params) = config.getTargetAddr(snmpEngine, targetAddrName) (messageProcessingModel, securityModel, securityName, securityLevel) = config.getTargetParams(snmpEngine, params) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # (filterSubtree, filterMask, # filterType) = config.getNotifyFilter(filterProfileName) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, notifyTag %s yields: ' 'transportDomain %s, transportAddress %r, securityModel %s, ' 'securityName %s, securityLevel %s' % ( notificationHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) for varName, varVal in varBinds: if varName in (sysUpTime, snmpTrapOID): continue try: snmpEngine.accessControlModel[self.ACM_ID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: ACL succeeded for OID %s securityName %s' % ( varName, securityName)) except error.StatusInformation: debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: ACL denied access for OID %s securityName %s,' 'dropping notification' % (varName, securityName)) return # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise error.ProtocolError('Unknown notify-type %r', notifyType) v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # 3.3.5 try: sendRequestHandle = self.sendPdu( snmpEngine, targetAddrName, contextEngineId, contextName, pdu, self.processResponseVarBinds, (notificationHandle, cbFun, cbCtx) ) except error.StatusInformation as exc: statusInformation = exc debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: sendRequestHandle %s: sendPdu() failed ' 'with %r' % (sendRequestHandle, statusInformation)) if (notificationHandle not in self.__pendingNotifications or not self.__pendingNotifications[notificationHandle]): if notificationHandle in self.__pendingNotifications: del self.__pendingNotifications[notificationHandle] if cbFun: cbFun(snmpEngine, notificationHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx) return notificationHandle debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, sendRequestHandle %s, ' 'timeout %d' % (notificationHandle, sendRequestHandle, timeout)) if notifyType == 2: if notificationHandle not in self.__pendingNotifications: self.__pendingNotifications[notificationHandle] = set() self.__pendingNotifications[notificationHandle].add(sendRequestHandle) debug.logger & debug.FLAG_APP and debug.logger( 'sendVarBinds: notificationHandle %s, sendRequestHandle %s, ' 'notification(s) sent' % (notificationHandle, sendRequestHandle)) return notificationHandle
def sendNotification(self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=(), cbFun=None, cbCtx=None, contextName=null, instanceIndex=None): debug.logger & debug.flagApp and debug.logger( 'sendNotification: notificationTarget %s, notificationName %s, additionalVarBinds %s, contextName "%s", instanceIndex %s' % (notificationTarget, notificationName, additionalVarBinds, contextName, instanceIndex)) if contextName: __SnmpAdminString, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( 'SNMP-FRAMEWORK-MIB', 'SnmpAdminString') contextName = __SnmpAdminString(contextName) # 3.3 (notifyTag, notifyType) = config.getNotificationInfo(snmpEngine, notificationTarget) metaSendPduHandle = getNextHandle() debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notifyTag %s, notifyType %s' % (metaSendPduHandle, notifyTag, notifyType)) contextMibInstrumCtl = self.snmpContext.getMibInstrum(contextName) additionalVarBinds = [(v2c.ObjectIdentifier(x), y) for x, y in additionalVarBinds] for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): (transportDomain, transportAddress, timeout, retryCount, params) = config.getTargetAddr(snmpEngine, targetAddrName) (messageProcessingModel, securityModel, securityName, securityLevel) = config.getTargetParams(snmpEngine, params) debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (metaSendPduHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'sysUpTime') for varName, varVal in additionalVarBinds: if varName == sysUpTime.name: varBinds.append((varName, varVal)) break if not varBinds: varBinds.append((sysUpTime.name, sysUpTime.syntax.clone())) # for actual value snmpTrapOid, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID') if len(notificationName) == 2: # ('MIB', 'symbol') notificationTypeObject, = contextMibInstrumCtl.mibBuilder.importSymbols( *notificationName) varBinds.append( (snmpTrapOid.name, v2c.ObjectIdentifier(notificationTypeObject.name))) debug.logger & debug.flagApp and debug.logger( 'sendNotification: notification type object is %s' % notificationTypeObject) for notificationObject in notificationTypeObject.getObjects(): mibNode, = contextMibInstrumCtl.mibBuilder.importSymbols( *notificationObject) if instanceIndex: mibNode = mibNode.getNode(mibNode.name + instanceIndex) else: mibNode = mibNode.getNextNode(mibNode.name) varBinds.append((mibNode.name, mibNode.syntax)) debug.logger & debug.flagApp and debug.logger( 'sendNotification: processed notification object %s, instance index %s, var-bind %s' % (notificationObject, instanceIndex is None and "<first>" or instanceIndex, mibNode)) elif notificationName: # numeric OID varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName))) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) for varName, varVal in additionalVarBinds: if varName in (sysUpTime.name, snmpTrapOid.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName) except error.StatusInformation: debug.logger & debug.flagApp and debug.logger( 'sendNotification: OID %s not allowed for %s, droppping notification' % (varName, securityName)) return else: varBinds.append((varName, varVal)) # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: reqPDU = rfc2576.v2ToV1(pdu) pduVersion = 0 else: reqPDU = pdu pduVersion = 1 # 3.3.5 if notifyType == 1: try: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pduVersion, reqPDU, None) except error.StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger( 'sendReq: metaSendPduHandle %s: sendPdu() failed with %r' % (metaSendPduHandle, statusInformation)) if metaSendPduHandle not in self.__pendingNotifications or \ not self.__pendingNotifications[metaSendPduHandle]: if metaSendPduHandle in self.__pendingNotifications: del self.__pendingNotifications[metaSendPduHandle] self._handleResponse( metaSendPduHandle, statusInformation['errorIndication'], 0, 0, (), cbFun, cbCtx) return metaSendPduHandle else: # Convert timeout in seconds into timeout in timer ticks timeoutInTicks = float( timeout ) / 100 / snmpEngine.transportDispatcher.getTimerResolution() # 3.3.6a try: sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pduVersion, reqPDU, 1, # expectResponse timeoutInTicks, self.processResponsePdu, (cbFun, cbCtx)) except error.StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger( 'sendReq: metaSendPduHandle %s: sendPdu() failed with %r' % (metaSendPduHandle, statusInformation)) if metaSendPduHandle not in self.__pendingNotifications or \ not self.__pendingNotifications[metaSendPduHandle]: if metaSendPduHandle in self.__pendingNotifications: del self.__pendingNotifications[metaSendPduHandle] self._handleResponse( metaSendPduHandle, statusInformation['errorIndication'], 0, 0, (), cbFun, cbCtx) return metaSendPduHandle debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, sendPduHandle %s, timeout %d' % (metaSendPduHandle, sendPduHandle, timeout)) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.snmpContext.contextEngineId, contextName, pdu, timeout, retryCount, 1, metaSendPduHandle) if metaSendPduHandle not in self.__pendingNotifications: self.__pendingNotifications[metaSendPduHandle] = 0 self.__pendingNotifications[metaSendPduHandle] += 1 snmpEngine.transportDispatcher.jobStarted(id(self)) debug.logger & debug.flagApp and debug.logger( 'sendNotification: metaSendPduHandle %s, notification(s) sent' % metaSendPduHandle) return metaSendPduHandle
def sendNotification(self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=None, cbFun=None, cbCtx=None, contextName=''): # 3.3 (notifyTag, notifyType) = config.getNotificationInfo(snmpEngine, notificationTarget) contextMibInstrumCtl = self.__context.getMibInstrum(contextName) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): (transportDomain, transportAddress, timeout, retryCount, params) = config.getTargetAddr(snmpEngine, targetAddrName) (messageProcessingModel, securityModel, securityName, securityLevel) = config.getTargetParams(snmpEngine, params) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'sysUpTime') varBinds.append( (sysUpTime.name, sysUpTime.syntax.clone()) # for actual value ) snmpTrapOid, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID') if notificationName: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName))) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) # XXX it's still not clear how to instantiate OBJECTS clause # # Get notification objects names # for notificationObject in snmpTrapVal.getObjects(): # mibNode, = apply( # contextMibInstrumCtl.mibBuilder.importSymbols, # notificationObject # ) # try: # objectInstance = mibNode.getNode(mibNode.name + (0,)) # except error.SmiError: # return # varBinds.append((objectInstance.name, objectInstance.syntax)) if additionalVarBinds: if version_info < (1, 6): additionalVarBinds = list(additionalVarBinds) varBinds.extend(additionalVarBinds) for varName, varVal in varBinds: try: snmpEngine.accessControlModel[vacmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName) except error.SmiError: return # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: pdu = rfc2576.v2ToV1(pdu) pduVersion = 0 else: pduVersion = 1 # 3.3.5 if notifyType == 1: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, None) else: # 3.3.6a sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, (self.processResponsePdu, float(timeout) / 100 + time.time(), (cbFun, cbCtx))) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, timeout, retryCount, 1, getNextHandle()) snmpEngine.transportDispatcher.jobStarted(id(self)) return sendPduHandle
def sendNotification( self, snmpEngine, notificationTarget, notificationName, additionalVarBinds=None, cbFun=None, cbCtx=None, contextName=null ): # 3.3 ( notifyTag, notifyType ) = config.getNotificationInfo( snmpEngine, notificationTarget ) metaSendPduHandle = getNextHandle() debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notifyTag %s, notifyType %s' % (metaSendPduHandle, notifyTag, notifyType)) contextMibInstrumCtl = self.__context.getMibInstrum( contextName ) for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): ( transportDomain, transportAddress, timeout, retryCount, params ) = config.getTargetAddr(snmpEngine, targetAddrName) ( messageProcessingModel, securityModel, securityName, securityLevel ) = config.getTargetParams(snmpEngine, params) debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (metaSendPduHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) # ( filterSubtree, # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) varBinds = [] # 3.3.2 & 3.3.3 sysUpTime, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'sysUpTime' ) if additionalVarBinds: for varName, varVal in additionalVarBinds: if varName == sysUpTime.name: varBinds.append((varName, varVal)) break if not varBinds: varBinds.append((sysUpTime.name, sysUpTime.syntax.clone())) # for actual value snmpTrapOid, = contextMibInstrumCtl.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpTrapOID' ) if notificationName: varBinds.append( (snmpTrapOid.name, snmpTrapOid.syntax.clone(notificationName)) ) else: varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) # XXX it's still not clear how to instantiate OBJECTS clause # # Get notification objects names # for notificationObject in snmpTrapVal.getObjects(): # mibNode, = contextMibInstrumCtl.mibBuilder.importSymbols( # *notificationObject # ) # try: # objectInstance = mibNode.getNode(mibNode.name + (0,)) # except error.SmiError: # return # varBinds.append((objectInstance.name, objectInstance.syntax)) for varName, varVal in additionalVarBinds: if varName in (sysUpTime.name, snmpTrapOid.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) except error.SmiError: debug.logger & debug.flagApp and debug.logger('sendNotification: OID %s not allowed for %s, droppping notification' % (varName, securityName)) return else: varBinds.append((varName, varVal)) # 3.3.4 if notifyType == 1: pdu = v2c.SNMPv2TrapPDU() elif notifyType == 2: pdu = v2c.InformRequestPDU() else: raise RuntimeError() v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) # User-side API assumes SMIv2 if messageProcessingModel == 0: pdu = rfc2576.v2ToV1(pdu) pduVersion = 0 else: pduVersion = 1 # 3.3.5 if notifyType == 1: snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, None ) else: # Convert timeout in seconds into timeout in timer ticks timeoutInTicks = float(timeout)/100/snmpEngine.transportDispatcher.getTimerResolution() # 3.3.6a sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, 1, # expectResponse timeoutInTicks, self.processResponsePdu, (cbFun, cbCtx) ) debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, sendPduHandle %s, timeout %d' % (metaSendPduHandle, sendPduHandle, timeout)) # 3.3.6b self.__pendingReqs[sendPduHandle] = ( transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, self.__context.contextEngineId, contextName, pduVersion, pdu, timeout, retryCount, 1, metaSendPduHandle ) if metaSendPduHandle not in self.__pendingNotifications: self.__pendingNotifications[metaSendPduHandle] = 0 self.__pendingNotifications[metaSendPduHandle] += 1 snmpEngine.transportDispatcher.jobStarted(id(self)) debug.logger & debug.flagApp and debug.logger('sendNotification: metaSendPduHandle %s, notification(s) sent' % metaSendPduHandle) return metaSendPduHandle