def _recvCb(self, snmpEngine, transportDomain, transportAddress, wholeMsg): try: mpModel = verdec.decodeMessageVersion(wholeMsg) except error.ProtocolError: return null # n.b the whole buffer gets dropped debug.logger & debug.FLAG_DSP and debug.logger('receiveMessage: msgVersion %s, msg decoded' % mpModel) pMod = api.PROTOCOL_MODULES[mpModel] while wholeMsg: rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message()) rspPdu = pMod.apiMessage.getPDU(rspMsg) requestId = pMod.apiPDU.getRequestID(rspPdu) try: stateInfo = self._pendingReqs.pop(requestId) except KeyError: continue self.transportDispatcher.jobFinished(id(self)) cbFun = stateInfo['cbFun'] cbCtx = stateInfo['cbCtx'] if cbFun: cbFun(self, requestId, None, rspPdu, cbCtx) return wholeMsg
def receiveMessage(self, snmpEngine, transportDomain, transportAddress, wholeMsg): """Message dispatcher -- de-serialize message into PDU""" # 4.2.1.1 snmpInPkts, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts') snmpInPkts.syntax = snmpInPkts.syntax + 1 # 4.2.1.2 try: restOfWholeMsg = '' # XXX fix decoder non-recursive return msgVersion = verdec.decodeMessageVersion(wholeMsg) except PySnmpError: snmpInAsn1ParseErrs, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInAsn1ParseErrs') snmpInAsn1ParseErrs.syntax = snmpInAsn1ParseErrs.syntax + 1 return '' # n.b the whole buffer gets dropped debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion mpHandler = snmpEngine.messageProcessingSubsystems.get( int(messageProcessingModel)) if mpHandler is None: snmpInBadVersions, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax = snmpInBadVersions.syntax + 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: (messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg) debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: MP succeded') except error.StatusInformation, statusInformation: if statusInformation.has_key('sendPduHandle'): # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: MP failed, statusInformation %s' % statusInformation) self.__expireRequest( snmpEngine, self.__cachePop(statusInformation['sendPduHandle']), statusInformation) return restOfWholeMsg
def log(self, msg, address, direction): #TODO: log snmp request/response at the same time. if direction == 'in': direction = 'request from' log_key = 'request' else: direction = 'reply to' log_key = 'response' #0 = v1, 1 = v2, 3 = v3 version = verdec.decodeMessageVersion(msg) if version == 0 or version == 1: pMod = api.protoModules[version] rspMsg, wholeMsg = decoder.decode(msg, asn1Spec=pMod.Message()) community_name = rspMsg.getComponentByPosition(1) request_pdu = pMod.apiMessage.getPDU(rspMsg) request_type = request_pdu.__class__.__name__ session_id = request_pdu.getComponentByPosition(0) #will there ever be more than one item? for oid, val in pMod.apiPDU.getVarBinds(request_pdu): logger.debug('SNMPv{0} {1} {2}, Type: {3}, Community: {4}, ' 'Oid: {5}, Value: {6}'.format(version + 1, direction, address, request_type, community_name, oid, val)) elif version == 3: logger.debug('SNMPv3 {0}: {1}. (Decoding not supported yet.)'.format(log_key, msg.encode('hex'))) else: logger.debug('Unknown SNMP {0}: {1}'.format(log_key, msg.encode('hex'))) #raw data (all snmp version) self.log_queue.put( {'remote': address, 'timestamp': datetime.utcnow(), 'data_type': 'snmp', 'data': { 0: {log_key: msg.encode('hex')} }} )
def log(self, msg, address, direction): # TODO: log snmp request/response at the same time. if direction == "in": direction = "request from" log_key = "request" else: direction = "reply to" log_key = "response" # 0 = v1, 1 = v2, 3 = v3 version = verdec.decodeMessageVersion(msg) if version == 0 or version == 1: pMod = api.protoModules[version] rspMsg, wholeMsg = decoder.decode(msg, asn1Spec=pMod.Message()) community_name = rspMsg.getComponentByPosition(1) request_pdu = pMod.apiMessage.getPDU(rspMsg) request_type = request_pdu.__class__.__name__ session_id = request_pdu.getComponentByPosition(0) # will there ever be more than one item? for oid, val in pMod.apiPDU.getVarBinds(request_pdu): logger.debug( "SNMPv{0} {1} {2}, Type: {3}, Community: {4}, " "Oid: {5}, Value: {6}".format( version + 1, direction, address, request_type, community_name, oid, val ) ) # raw data (all snmp version) self.log_queue.put( { "remote": address, "timestamp": datetime.utcnow(), "data_type": "snmp", "data": {0: {log_key: msg.encode("hex")}}, } )
def receiveMessage( self, snmpEngine, transportDomain, transportAddress, wholeMsg ): """Message dispatcher -- de-serialize message into PDU""" # 4.2.1.1 snmpInPkts, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts' ) snmpInPkts.syntax = snmpInPkts.syntax + 1 # 4.2.1.2 try: restOfWholeMsg = null # XXX fix decoder non-recursive return msgVersion = verdec.decodeMessageVersion(wholeMsg) except PySnmpError: snmpInAsn1ParseErrs, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInAsn1ParseErrs') snmpInAsn1ParseErrs.syntax = snmpInAsn1ParseErrs.syntax + 1 return null # n.b the whole buffer gets dropped debug.logger & debug.flagDsp and debug.logger('receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion k = int(messageProcessingModel) if k in snmpEngine.messageProcessingSubsystems: mpHandler = snmpEngine.messageProcessingSubsystems[k] else: snmpInBadVersions, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax = snmpInBadVersions.syntax + 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: ( messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference ) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg ) debug.logger & debug.flagDsp and debug.logger('receiveMessage: MP succeded') except error.StatusInformation: statusInformation = sys.exc_info()[1] if 'sendPduHandle' in statusInformation: # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.flagDsp and debug.logger('receiveMessage: MP failed, statusInformation %s' % statusInformation) self.__expireRequest( statusInformation['sendPduHandle'], self.__cache.pop(statusInformation['sendPduHandle']), snmpEngine, statusInformation ) return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger('receiveMessage: PDU %s' % PDU.prettyPrint()) # 4.2.2 if sendPduHandle is None: # 4.2.2.1 (request or notification) debug.logger & debug.flagDsp and debug.logger('receiveMessage: pduType %s' % pduType) # 4.2.2.1.1 processPdu = self.getRegisteredApp(contextEngineId, pduType) # 4.2.2.1.2 if processPdu is None: # 4.2.2.1.2.a snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols('__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax = snmpUnknownPDUHandlers.syntax+1 # 4.2.2.1.2.b statusInformation = { 'errorIndication': errind.unknownPDUHandler, 'oid': snmpUnknownPDUHandlers.name, 'val': snmpUnknownPDUHandlers.syntax } debug.logger & debug.flagDsp and debug.logger('receiveMessage: unhandled PDU type') # XXX fails on unknown PDU try: ( destTransportDomain, destTransportAddress, outgoingMessage ) = mpHandler.prepareResponseMessage( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference, statusInformation ) except error.StatusInformation: debug.logger & debug.flagDsp and debug.logger('receiveMessage: report failed, statusInformation %s' % sys.exc_info()[1]) return restOfWholeMsg # 4.2.2.1.2.c try: snmpEngine.transportDispatcher.sendMessage( outgoingMessage, destTransportDomain, destTransportAddress ) except PySnmpError: # XXX pass debug.logger & debug.flagDsp and debug.logger('receiveMessage: reporting succeeded') # 4.2.2.1.2.d return restOfWholeMsg else: # Pass transport info to app if stateReference is not None: self.__transportInfo[stateReference] = ( transportDomain, transportAddress ) # 4.2.2.1.3 processPdu( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference ) if stateReference is not None: del self.__transportInfo[stateReference] debug.logger & debug.flagDsp and debug.logger('receiveMessage: processPdu succeeded') return restOfWholeMsg else: # 4.2.2.2 (response) # 4.2.2.2.1 cachedParams = self.__cache.pop(sendPduHandle) # 4.2.2.2.2 if cachedParams is None: snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols('__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax = snmpUnknownPDUHandlers.syntax+1 return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger('receiveMessage: cache read by sendPduHandle %s' % sendPduHandle) # 4.2.2.2.3 # no-op ? XXX # 4.2.2.2.4 processResponsePdu = cachedParams['cbFun'] processResponsePdu( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, cachedParams['sendPduHandle'], cachedParams['cbCtx'] ) debug.logger & debug.flagDsp and debug.logger('receiveMessage: processResponsePdu succeeded') return restOfWholeMsg
def receiveMessage(self, snmpEngine, transportDomain, transportAddress, wholeMsg): """Message dispatcher -- de-serialize message into PDU""" # 4.2.1.1 snmpInPkts, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts' ) snmpInPkts.syntax += 1 # 4.2.1.2 try: restOfWholeMsg = null # XXX fix decoder non-recursive return msgVersion = verdec.decodeMessageVersion(wholeMsg) except error.ProtocolError: snmpInASNParseErrs, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInASNParseErrs') snmpInASNParseErrs.syntax += 1 return null # n.b the whole buffer gets dropped debug.logger & debug.flagDsp and debug.logger('receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion k = int(messageProcessingModel) if k in snmpEngine.messageProcessingSubsystems: mpHandler = snmpEngine.messageProcessingSubsystems[k] else: snmpInBadVersions, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax += 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: (messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg ) debug.logger & debug.flagDsp and debug.logger('receiveMessage: MP succeded') except error.StatusInformation: statusInformation = sys.exc_info()[1] if 'sendPduHandle' in statusInformation: # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: MP failed, statusInformation %s, forcing a retry' % statusInformation) self.__expireRequest( statusInformation['sendPduHandle'], self.__cache.pop(statusInformation['sendPduHandle']), snmpEngine, statusInformation ) return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger('receiveMessage: PDU %s' % PDU.prettyPrint()) # 4.2.2 if sendPduHandle is None: # 4.2.2.1 (request or notification) debug.logger & debug.flagDsp and debug.logger('receiveMessage: pduType %s' % pduType) # 4.2.2.1.1 processPdu = self.getRegisteredApp(contextEngineId, pduType) # 4.2.2.1.2 if processPdu is None: # 4.2.2.1.2.a snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols('__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax += 1 # 4.2.2.1.2.b statusInformation = { 'errorIndication': errind.unknownPDUHandler, 'oid': snmpUnknownPDUHandlers.name, 'val': snmpUnknownPDUHandlers.syntax } debug.logger & debug.flagDsp and debug.logger('receiveMessage: unhandled PDU type') # 4.2.2.1.2.c try: (destTransportDomain, destTransportAddress, outgoingMessage) = mpHandler.prepareResponseMessage( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference, statusInformation ) snmpEngine.transportDispatcher.sendMessage( outgoingMessage, destTransportDomain, destTransportAddress ) except PySnmpError: debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: report failed, statusInformation %s' % sys.exc_info()[1]) else: debug.logger & debug.flagDsp and debug.logger('receiveMessage: reporting succeeded') # 4.2.2.1.2.d return restOfWholeMsg else: snmpEngine.observer.storeExecutionContext( snmpEngine, 'rfc3412.receiveMessage:request', dict(transportDomain=transportDomain, transportAddress=transportAddress, wholeMsg=wholeMsg, messageProcessingModel=messageProcessingModel, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, contextEngineId=contextEngineId, contextName=contextName, pdu=PDU) ) # pass transport info to app (legacy) if stateReference is not None: self.__transportInfo[stateReference] = ( transportDomain, transportAddress ) # 4.2.2.1.3 processPdu(snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference) snmpEngine.observer.clearExecutionContext( snmpEngine, 'rfc3412.receiveMessage:request' ) # legacy if stateReference is not None: del self.__transportInfo[stateReference] debug.logger & debug.flagDsp and debug.logger('receiveMessage: processPdu succeeded') return restOfWholeMsg else: # 4.2.2.2 (response) # 4.2.2.2.1 cachedParams = self.__cache.pop(sendPduHandle) # 4.2.2.2.2 if cachedParams is None: snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols('__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax += 1 return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: cache read by sendPduHandle %s' % sendPduHandle) # 4.2.2.2.3 # no-op ? XXX snmpEngine.observer.storeExecutionContext( snmpEngine, 'rfc3412.receiveMessage:response', dict(transportDomain=transportDomain, transportAddress=transportAddress, wholeMsg=wholeMsg, messageProcessingModel=messageProcessingModel, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, contextEngineId=contextEngineId, contextName=contextName, pdu=PDU) ) # 4.2.2.2.4 processResponsePdu = cachedParams['cbFun'] processResponsePdu(snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, cachedParams['sendPduHandle'], cachedParams['cbCtx']) snmpEngine.observer.clearExecutionContext( snmpEngine, 'rfc3412.receiveMessage:response' ) debug.logger & debug.flagDsp and debug.logger('receiveMessage: processResponsePdu succeeded') return restOfWholeMsg
def receiveMessage( self, snmpEngine, transportDomain, transportAddress, wholeMsg ): """Message dispatcher -- de-serialize message into PDU""" # 4.2.1.1 snmpInPkts, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts' ) snmpInPkts.syntax = snmpInPkts.syntax + 1 # 4.2.1.2 try: restOfWholeMsg = '' # XXX fix decoder non-recursive return msgVersion = verdec.decodeMessageVersion(wholeMsg) except PySnmpError: snmpInAsn1ParseErrs, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInAsn1ParseErrs') snmpInAsn1ParseErrs.syntax = snmpInAsn1ParseErrs.syntax + 1 return '' # n.b the whole buffer gets dropped debug.logger & debug.flagDsp and debug.logger('receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion mpHandler = snmpEngine.messageProcessingSubsystems.get( int(messageProcessingModel) ) if mpHandler is None: snmpInBadVersions, = self.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax = snmpInBadVersions.syntax + 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: ( messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference ) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg ) debug.logger & debug.flagDsp and debug.logger('receiveMessage: MP succeded') except error.StatusInformation, statusInformation: if statusInformation.has_key('sendPduHandle'): # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.flagDsp and debug.logger('receiveMessage: MP failed, statusInformation %s' % statusInformation) self.__expireRequest( snmpEngine, self.__cachePop(statusInformation['sendPduHandle']), statusInformation ) return restOfWholeMsg
def receiveMessage(self, snmpEngine, transportDomain, transportAddress, wholeMsg): """Message dispatcher -- de-serialize message into PDU""" # 4.2.1.1 snmpInPkts, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts') snmpInPkts.syntax = snmpInPkts.syntax + 1 # 4.2.1.2 try: restOfWholeMsg = '' # XXX fix decoder non-recursive return msgVersion = verdec.decodeMessageVersion(wholeMsg) except PySnmpError: snmpInAsn1ParseErrs, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInAsn1ParseErrs') snmpInAsn1ParseErrs.syntax = snmpInAsn1ParseErrs.syntax + 1 return '' # n.b the whole buffer gets dropped debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion mpHandler = snmpEngine.messageProcessingSubsystems.get( int(messageProcessingModel)) if mpHandler is None: snmpInBadVersions, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax = snmpInBadVersions.syntax + 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: (messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg) debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: MP succeded') except error.StatusInformation as statusInformation: if statusInformation.has_key('sendPduHandle'): # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: MP failed, statusInformation %s' % statusInformation) self.__expireRequest( snmpEngine, self.__cachePop(statusInformation['sendPduHandle']), statusInformation) return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: PDU %s' % PDU.prettyPrint()) # 4.2.2 if sendPduHandle is None: # 4.2.2.1 (request or notification) debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: pduType %s' % pduType) # 4.2.2.1.1 processPdu = self.getRegisteredApp(contextEngineId, pduType) # 4.2.2.1.2 if processPdu is None: # 4.2.2.1.2.a snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax = snmpUnknownPDUHandlers.syntax + 1 # 4.2.2.1.2.b statusInformation = { 'errorIndication': 'unknownPDUHandler', 'oid': snmpUnknownPDUHandlers.name, 'val': snmpUnknownPDUHandlers.syntax } debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: unhandled PDU type') # XXX fails on unknown PDU try: (destTransportDomain, destTransportAddress, outgoingMessage) = mpHandler.prepareResponseMessage( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference, statusInformation) except error.StatusInformation as statusInformation: debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: report failed, statusInformation %s' % statusInformation) return restOfWholeMsg # 4.2.2.1.2.c try: snmpEngine.transportDispatcher.sendMessage( outgoingMessage, destTransportDomain, destTransportAddress) except PySnmpError: # XXX pass debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: reporting succeeded') # 4.2.2.1.2.d return restOfWholeMsg else: # Pass transport info to app if stateReference is not None: self.__transportInfo[stateReference] = (transportDomain, transportAddress) # 4.2.2.1.3 processPdu(snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference) if stateReference is not None: del self.__transportInfo[stateReference] debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: processPdu succeeded') return restOfWholeMsg else: # 4.2.2.2 (response) # 4.2.2.2.1 cachedParams = self.__cachePop(sendPduHandle) # 4.2.2.2.2 if cachedParams is None: snmpUnknownPDUHandlers, = self.mibInstrumController.mibBuilder.importSymbols( '__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax = snmpUnknownPDUHandlers.syntax + 1 return restOfWholeMsg debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: cache read by sendPduHandle %s' % sendPduHandle) # 4.2.2.2.3 # no-op ? XXX # 4.2.2.2.4 processResponsePdu, timeoutAt, cbCtx = cachedParams[ 'expectResponse'] processResponsePdu(snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, cachedParams['sendPduHandle'], cbCtx) debug.logger & debug.flagDsp and debug.logger( 'receiveMessage: processResponsePdu succeeded') return restOfWholeMsg
def receiveMessage(self, snmpEngine, transportDomain, transportAddress, wholeMsg): """Message dispatcher -- de-serialize message into PDU""" mibBuilder = self.mibInstrumController.mibBuilder # 4.2.1.1 snmpInPkts, = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInPkts') snmpInPkts.syntax += 1 restOfWholeMsg = null # XXX fix decoder non-recursive return # 4.2.1.2 try: msgVersion = verdec.decodeMessageVersion(wholeMsg) except error.ProtocolError: snmpInASNParseErrs, = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInASNParseErrs') snmpInASNParseErrs.syntax += 1 return null # n.b the whole buffer gets dropped debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: msgVersion %s, msg decoded' % msgVersion) messageProcessingModel = msgVersion try: mpHandler = snmpEngine.messageProcessingSubsystems[ int(messageProcessingModel)] except KeyError: snmpInBadVersions, = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInBadVersions') snmpInBadVersions.syntax += 1 return restOfWholeMsg # 4.2.1.3 -- no-op # 4.2.1.4 try: (messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference) = mpHandler.prepareDataElements( snmpEngine, transportDomain, transportAddress, wholeMsg) debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: MP succeded') except error.StatusInformation as exc: statusInformation = exc if 'sendPduHandle' in statusInformation: # Dropped REPORT -- re-run pending reqs queue as some # of them may be waiting for this REPORT debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: MP failed, statusInformation %s, ' 'forcing retry' % statusInformation) self.__expireRequest( statusInformation['sendPduHandle'], self._cache.pop(statusInformation['sendPduHandle']), snmpEngine, statusInformation) return restOfWholeMsg except PyAsn1Error as exc: debug.logger & debug.FLAG_MP and debug.logger( 'receiveMessage: %s' % exc) snmpInASNParseErrs, = mibBuilder.importSymbols( '__SNMPv2-MIB', 'snmpInASNParseErrs') snmpInASNParseErrs.syntax += 1 return restOfWholeMsg debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: PDU %s' % PDU.prettyPrint()) # 4.2.2 if sendPduHandle is None: # 4.2.2.1 (request or notification) debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: pduType %s' % pduType) # 4.2.2.1.1 processPdu = self.getRegisteredApp(contextEngineId, pduType) # 4.2.2.1.2 if processPdu is None: # 4.2.2.1.2.a snmpUnknownPDUHandlers, = importSymbols( '__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax += 1 # 4.2.2.1.2.b statusInformation = { 'errorIndication': errind.unknownPDUHandler, 'oid': snmpUnknownPDUHandlers.name, 'val': snmpUnknownPDUHandlers.syntax } debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: unhandled PDU type') # 4.2.2.1.2.c try: (destTransportDomain, destTransportAddress, outgoingMessage) = mpHandler.prepareResponseMessage( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference, statusInformation) snmpEngine.transportDispatcher.sendMessage( outgoingMessage, destTransportDomain, destTransportAddress) except PySnmpError as exc: debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: report failed, statusInformation %s' % exc) else: debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: reporting succeeded') # 4.2.2.1.2.d return restOfWholeMsg else: snmpEngine.observer.storeExecutionContext( snmpEngine, 'rfc3412.receiveMessage:request', dict(transportDomain=transportDomain, transportAddress=transportAddress, wholeMsg=wholeMsg, messageProcessingModel=messageProcessingModel, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, contextEngineId=contextEngineId, contextName=contextName, pdu=PDU)) # pass transport info to app (legacy) if stateReference is not None: self._transportInfo[stateReference] = ( transportDomain, transportAddress) # 4.2.2.1.3 (asynchronous function) processPdu( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, maxSizeResponseScopedPDU, stateReference) snmpEngine.observer.clearExecutionContext( snmpEngine, 'rfc3412.receiveMessage:request') # legacy if stateReference is not None: del self._transportInfo[stateReference] debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: processPdu initiated') return restOfWholeMsg else: # 4.2.2.2 (response) # 4.2.2.2.1 cachedParams = self._cache.pop(sendPduHandle) # 4.2.2.2.2 if cachedParams is None: snmpUnknownPDUHandlers, = mibBuilder.importSymbols( '__SNMP-MPD-MIB', 'snmpUnknownPDUHandlers') snmpUnknownPDUHandlers.syntax += 1 return restOfWholeMsg debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: cache read by sendPduHandle %s' % sendPduHandle) # 4.2.2.2.3 # no-op ? XXX snmpEngine.observer.storeExecutionContext( snmpEngine, 'rfc3412.receiveMessage:response', dict(transportDomain=transportDomain, transportAddress=transportAddress, wholeMsg=wholeMsg, messageProcessingModel=messageProcessingModel, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, contextEngineId=contextEngineId, contextName=contextName, pdu=PDU)) # 4.2.2.2.4 processResponsePdu = cachedParams['cbFun'] processResponsePdu( snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, cachedParams['sendPduHandle'], cachedParams['cbCtx']) snmpEngine.observer.clearExecutionContext( snmpEngine, 'rfc3412.receiveMessage:response') debug.logger & debug.FLAG_DSP and debug.logger( 'receiveMessage: processResponsePdu succeeded') return restOfWholeMsg