def processResponseVarBinds(self, snmpEngine, sendRequestHandle, errorIndication, PDU, cbCtx): targetName, contextEngineId, contextName, reqPDU, cbFun, cbCtx = cbCtx if errorIndication: cbFun(snmpEngine, sendRequestHandle, errorIndication, 0, 0, (), cbCtx) return varBindTable = v2c.apiPDU.getVarBindTable(reqPDU, PDU) if v2c.apiPDU.getErrorStatus(PDU): errorIndication, varBinds = None, () elif not varBindTable: errorIndication, varBinds = errind.emptyResponse, () else: errorIndication, varBinds = getNextVarBinds( varBindTable[-1], v2c.apiPDU.getVarBinds(reqPDU) ) if not cbFun(snmpEngine, sendRequestHandle, errorIndication, v2c.apiPDU.getErrorStatus(PDU), v2c.apiPDU.getErrorIndex(PDU, muteErrors=True), varBindTable, cbCtx): debug.logger & debug.flagApp and debug.logger('processResponseVarBinds: sendRequestHandle %s, app says to stop walking' % sendRequestHandle) return # app says enough if not varBinds: return # no more objects available v2c.apiPDU.setRequestID(reqPDU, v2c.getNextRequestID()) v2c.apiPDU.setVarBinds(reqPDU, varBinds) try: self.sendPdu(snmpEngine, targetName, contextEngineId, contextName, reqPDU, self.processResponseVarBinds, (targetName, contextEngineId, contextName, reqPDU, cbFun, cbCtx)) except StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendPduHandle %s: sendPdu() failed with %r' % (sendRequestHandle, statusInformation)) cbFun(snmpEngine, sendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx)
def _cbFun(snmpDispatcher, stateHandle, errorIndication, rspPdu, _cbCtx): if not cbFun: return if errorIndication: cbFun(errorIndication, v2c.Integer(0), v2c.Integer(0), None, cbCtx=cbCtx, snmpDispatcher=snmpDispatcher, stateHandle=stateHandle) return errorStatus = v2c.apiTrapPDU.getErrorStatus(rspPdu) errorIndex = v2c.apiTrapPDU.getErrorIndex(rspPdu) varBinds = v2c.apiTrapPDU.getVarBinds(rspPdu) if lookupMib: varBinds = VB_PROCESSOR.unmakeVarBinds(snmpDispatcher.cache, varBinds) nextStateHandle = v2c.getNextRequestID() nextVarBinds = cbFun(errorIndication, errorStatus, errorIndex, varBinds, cbCtx=cbCtx, snmpDispatcher=snmpDispatcher, stateHandle=stateHandle, nextStateHandle=nextStateHandle) if not nextVarBinds: return v2c.apiTrapPDU.setRequestID(reqPdu, nextStateHandle) v2c.apiTrapPDU.setVarBinds(reqPdu, _ensureVarBinds(nextVarBinds)) return snmpDispatcher.sendPdu(authData, transportTarget, reqPdu, cbFun=_cbFun)
def _handleResponse(self, snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, PDU, timeout, retryCount, rspPDU, sendRequestHandle, cbInfo): (cbFun, cbCtx) = cbInfo varBindTable = v2c.apiBulkPDU.getVarBindTable(PDU, rspPDU) if v2c.apiBulkPDU.getErrorStatus(rspPDU): errorIndication, varBinds = None, () elif not varBindTable: errorIndication, varBinds = errind.emptyResponse, () else: errorIndication, varBinds = getNextVarBinds( v2c.apiBulkPDU.getVarBinds(PDU), varBindTable[-1]) nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(PDU) if nonRepeaters: varBinds = v2c.apiBulkPDU.getVarBinds(PDU)[:nonRepeaters] + \ varBinds[nonRepeaters:] if not cbFun(sendRequestHandle, errorIndication, v2c.apiBulkPDU.getErrorStatus(rspPDU), v2c.apiBulkPDU.getErrorIndex(rspPDU, muteErrors=True), varBindTable, cbCtx): debug.logger & debug.flagApp and debug.logger( '_handleResponse: sendRequestHandle %s, app says to stop walking' % sendRequestHandle) return # app says enough if not varBinds: return # no more objects available v2c.apiBulkPDU.setRequestID(PDU, v2c.getNextRequestID()) v2c.apiBulkPDU.setVarBinds(PDU, varBinds) try: self._sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, PDU, timeout, retryCount, 0, # retries sendRequestHandle, (self.processResponsePdu, (cbFun, cbCtx))) except StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger( 'sendReq: sendPduHandle %s: _sendPdu() failed with %r' % (sendRequestHandle, statusInformation)) cbFun(sendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx)
def processResponseVarBinds(self, snmpEngine, sendRequestHandle, errorIndication, PDU, cbCtx): (targetName, nonRepeaters, maxRepetitions, contextEngineId, contextName, reqPDU, cbFun, cbCtx) = cbCtx if errorIndication: cbFun(snmpEngine, sendRequestHandle, errorIndication, 0, 0, (), cbCtx) return varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, PDU) if v2c.apiBulkPDU.getErrorStatus(PDU): errorIndication, varBinds = None, () elif not varBindTable: errorIndication, varBinds = errind.emptyResponse, () else: errorIndication, varBinds = v2c.apiBulkPDU.getNextVarBinds( varBindTable[-1]) nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(reqPDU) if nonRepeaters: varBinds = v2c.apiBulkPDU.getVarBinds( reqPDU)[:int(nonRepeaters)] + varBinds[int(nonRepeaters):] if not cbFun(snmpEngine, sendRequestHandle, errorIndication, v2c.apiBulkPDU.getErrorStatus(PDU), v2c.apiBulkPDU.getErrorIndex(PDU, muteErrors=True), varBindTable, cbCtx): debug.logger & debug.FLAG_APP and debug.logger( 'processResponseVarBinds: sendRequestHandle %s, app says to stop walking' % sendRequestHandle) return # app says it's enough if not varBinds: return # no more objects available v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID()) v2c.apiBulkPDU.setVarBinds(reqPDU, varBinds) try: self.sendPdu(snmpEngine, targetName, contextEngineId, contextName, reqPDU, self.processResponseVarBinds, (targetName, nonRepeaters, maxRepetitions, contextEngineId, contextName, reqPDU, cbFun, cbCtx)) except StatusInformation as exc: statusInformation = exc debug.logger & debug.FLAG_APP and debug.logger( 'processResponseVarBinds: sendPduHandle %s: _sendPdu() failed ' 'with %r' % (sendRequestHandle, statusInformation)) cbFun(snmpEngine, sendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx)
def cbRecvFun( transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU=reqPDU, headVars=headVars, ): while wholeMsg: rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message()) rspPDU = v2c.apiMessage.getPDU(rspMsg) # Match response to request if v2c.apiBulkPDU.getRequestID( reqPDU) == v2c.apiBulkPDU.getRequestID(rspPDU): # Format var-binds table varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU) # Check for SNMP errors reported errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU) if errorStatus and errorStatus != 2: errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU) print("%s at %s" % ( errorStatus.prettyPrint(), errorIndex and varBindTable[int(errorIndex) - 1] or "?", )) transportDispatcher.jobFinished(1) break # Report SNMP table for tableRow in varBindTable: for name, val in tableRow: # print mib data print("from: %s, %s = %s" % (transportAddress, name.prettyPrint(), val.prettyPrint())) output_list.append( "from: %s, %s = %s\n" % (transportAddress, name.prettyPrint(), val.prettyPrint())) # Stop on EOM for _oid, val in varBindTable[-1]: if not isinstance(val, v2c.Null): break else: transportDispatcher.jobFinished(1) # Generate request for next row v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x, y in varBindTable[-1]]) v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage(encoder.encode(reqMsg), transportDomain, transportAddress) return wholeMsg
def processResponseVarBinds(self, snmpEngine, sendRequestHandle, errorIndication, PDU, cbCtx): (targetName, nonRepeaters, maxRepetitions, contextEngineId, contextName, reqPDU, cbFun, cbCtx) = cbCtx if errorIndication: cbFun(snmpEngine, sendRequestHandle, errorIndication, 0, 0, (), cbCtx) return varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, PDU) if v2c.apiBulkPDU.getErrorStatus(PDU): errorIndication, varBinds = None, () elif not varBindTable: errorIndication, varBinds = errind.emptyResponse, () else: errorIndication, varBinds = v2c.apiBulkPDU.getNextVarBinds(varBindTable[-1]) nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(reqPDU) if nonRepeaters: varBinds = v2c.apiBulkPDU.getVarBinds(reqPDU)[:int(nonRepeaters)] + varBinds[int(nonRepeaters):] if not cbFun( snmpEngine, sendRequestHandle, errorIndication, v2c.apiBulkPDU.getErrorStatus(PDU), v2c.apiBulkPDU.getErrorIndex(PDU, muteErrors=True), varBindTable, cbCtx): debug.logger & debug.FLAG_APP and debug.logger( 'processResponseVarBinds: sendRequestHandle %s, app says to stop walking' % sendRequestHandle) return # app says it's enough if not varBinds: return # no more objects available v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID()) v2c.apiBulkPDU.setVarBinds(reqPDU, varBinds) try: self.sendPdu( snmpEngine, targetName, contextEngineId, contextName, reqPDU, self.processResponseVarBinds, (targetName, nonRepeaters, maxRepetitions, contextEngineId, contextName, reqPDU, cbFun, cbCtx)) except StatusInformation as exc: statusInformation = exc debug.logger & debug.FLAG_APP and debug.logger( 'processResponseVarBinds: sendPduHandle %s: _sendPdu() failed ' 'with %r' % (sendRequestHandle, statusInformation)) cbFun(snmpEngine, sendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx)
def cbRecvFun(transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU=reqPDU, headVars=headVars): while wholeMsg: rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message()) rspPDU = v2c.apiMessage.getPDU(rspMsg) # Match response to request if v2c.apiBulkPDU.getRequestID(reqPDU) == v2c.apiBulkPDU.getRequestID(rspPDU): # Format var-binds table varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU) # Check for SNMP errors reported errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU) if errorStatus and errorStatus != 2: errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU) print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBindTable[int(errorIndex) - 1] or '?')) transportDispatcher.jobFinished(1) break # Report SNMP table for tableRow in varBindTable: for name, val in tableRow: print('from: %s, %s = %s' % (transportAddress, name.prettyPrint(), val.prettyPrint())) # Stop on EOM for oid, val in varBindTable[-1]: if not isinstance(val, v2c.Null): break else: transportDispatcher.jobFinished(1) continue # Generate request for next row v2c.apiBulkPDU.setVarBinds( reqPDU, [(x, v2c.null) for x, y in varBindTable[-1]] ) v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage( encoder.encode(reqMsg), transportDomain, transportAddress ) global startedAt if time() - startedAt > 3: raise Exception('Request timed out') startedAt = time() return wholeMsg
def cbRecvFun(transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU=reqPDU, headVars=headVars): while wholeMsg: rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message()) rspPDU = v2c.apiMessage.getPDU(rspMsg) # Match response to request if v2c.apiBulkPDU.getRequestID(reqPDU) == v2c.apiBulkPDU.getRequestID( rspPDU): # Format var-binds table varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU) # Check for SNMP errors reported errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU) if errorStatus and errorStatus != 2: errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU) print( '%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBindTable[int(errorIndex) - 1] or '?')) transportDispatcher.jobFinished(1) break # Report SNMP table for tableRow in varBindTable: for name, val in tableRow: print('from: %s, %s = %s' % (transportAddress, name.prettyPrint(), val.prettyPrint())) # Stop on EOM for oid, val in varBindTable[-1]: if not isinstance(val, v2c.Null): break else: transportDispatcher.jobFinished(1) continue # Generate request for next row v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x, y in varBindTable[-1]]) v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage(encoder.encode(reqMsg), transportDomain, transportAddress) global startedAt if time() - startedAt > 3: raise Exception('Request timed out') startedAt = time() return wholeMsg
def _handleResponse( self, snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, PDU, timeout, retryCount, rspPDU, sendRequestHandle, cbInfo ): (cbFun, cbCtx) = cbInfo varBindTable = v2c.apiBulkPDU.getVarBindTable(PDU, rspPDU) if v2c.apiBulkPDU.getErrorStatus(rspPDU): errorIndication, varBinds = None, () elif not varBindTable: errorIndication, varBinds = errind.emptyResponse, () else: errorIndication, varBinds = getNextVarBinds( v2c.apiBulkPDU.getVarBinds(PDU), varBindTable[-1] ) if not cbFun(sendRequestHandle, errorIndication, v2c.apiBulkPDU.getErrorStatus(rspPDU), v2c.apiBulkPDU.getErrorIndex(rspPDU, muteErrors=True), varBindTable, cbCtx): debug.logger & debug.flagApp and debug.logger('_handleResponse: sendRequestHandle %s, app says to stop walking' % sendRequestHandle) return # app says enough if not varBinds: return # no more objects available v2c.apiBulkPDU.setRequestID(PDU, v2c.getNextRequestID()) v2c.apiBulkPDU.setVarBinds(PDU, varBinds) sendRequestHandle = getNextHandle() try: self._sendPdu( snmpEngine, transportDomain, transportAddress, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, PDU, timeout, retryCount, 0, # retries sendRequestHandle, (self.processResponsePdu, (cbFun, cbCtx)) ) except StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger('sendReq: sendPduHandle %s: _sendPdu() failed with %r' % (sendRequestHandle, statusInformation)) cbFun(sendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx)
def callback(self, transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU=None, headVars=None): """ Callback function called when SNMP answer arrives """ aBP = v2c.apiBulkPDU # Get PDU if reqPDU: self.reqPDU = reqPDU # Get headVars (OID list) if headVars: self.headVars = headVars while wholeMsg: # Do some stuff to read SNMP anser self.rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message()) self.rspPDU = v2c.apiMessage.getPDU(self.rspMsg) if aBP.getRequestID(self.reqPDU) == aBP.getRequestID(self.rspPDU): # Check for SNMP errors reported errorStatus = aBP.getErrorStatus(self.rspPDU) if errorStatus and errorStatus != 2: logger.error('[SnmpBooster] SNMP Request error 2: %s' % str(errorStatus)) self.set_exit("SNMP Request error 2: " + str(errorStatus), rc=3) return wholeMsg # Format var-binds table varBindTable = aBP.getVarBindTable(self.reqPDU, self.rspPDU) # Initialize mapping_instance dict mapping_instance = {} # Read datas from the anser for tableRow in varBindTable: # TODO: MAYBE: Check if the current 'tableRow' is in the list of the # need tables. If NOT, maybe we can jump the current 'tableRow' ?? (continue) # Read all oid in the 'tableRow' for oid, val in tableRow: # Clean the oid oid = "." + oid.prettyPrint() # Check what kind of datas we have if oid in self.oids_waiting_values: # Standard datas # Get value and save it in the result dict self.results_oid_dict[oid] = str(val) elif any([oid.startswith(m_oid + ".") for m_oid in self.mapping_oids]): # Mapping datas # TODO: Need more detail for m_oid in self.mapping_oids: if oid.startswith(m_oid + "."): instance = oid.replace(m_oid + ".", "") val = re.sub("[,:/ ]", "_", str(val)) mapping_instance[val] = instance elif oid in self.limit_oids: # get limits => What is a limit ???????????? try: self.results_limits_dict[oid] = float(val) except ValueError: logger.error('[SnmpBooster] Bad limit for ' 'oid: %s - Skipping' % str(oid)) else: # The current oid is not needed pass # IF the mapping is done, we can look for OID values if self.mapping_done: # Get all OIDS that we want datas oids = set(self.oids_waiting_values.keys() + self.limit_oids.keys()) # Get all OIDS that we have datas results_oids = set(self.results_oid_dict.keys() + self.results_limits_dict.keys()) # Get all OIDS which have not datas YET self.remaining_oids = oids - results_oids # We have to determinate which OIDs we need to ask, # to get the datas for our wanted OIDs... tableRow = [] for oid in self.remaining_oids: # For all current OIDs, we need to get the previous OID # But if in the current OID is last number is 0 # We get the parent table if int(oid.rsplit(".", 1)[1]) - 1 >= 0: # Get previous oid here tableRow.append(oid[1:].rsplit(".", 1)[0] + "." + str(int(oid[1:].rsplit(".", 1)[1]) - 1)) else: # Get parent table here tableRow.append(oid[1:].rsplit(".", 1)[0]) # We need to get more OIDs (the request ask more than 100 oids) # - From the __init__ function # => We didn't query all needed oids YET # - From "oids != results_oids" # => Some OIDs doesn't have value, so probably the table # that we queried is long (more than 100 children) if len(self.remaining_tablerow) > 0: # SNMP BULK is limited to 100 OIDs in same request if len(self.remaining_tablerow) >= 100: oids_to_check = [self.remaining_tablerow.pop() for x in xrange(99)] else: oids_to_check = self.remaining_tablerow self.remaining_tablerow = set() # Prepare request to get nest OIDs aBP.setVarBinds(self.reqPDU, [(x, v2c.null) for x in oids_to_check]) aBP.setRequestID(self.reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage(encoder.encode(self.reqMsg), transportDomain, transportAddress) # Count the number of requests done for one host/frequency couple self.nb_next_requests = self.nb_next_requests + 1 return wholeMsg # Some oids doesn't have any value (oids != results_oids) # We make a new request to get this values if oids != results_oids and self.nb_next_requests < 5: # SNMP BULK is limited to 100 OIDs in same request if len(tableRow) >= 100: # Add missing oid to self.remaining_tablerow # This oids will be checked in a few requests # Here : "if len(self.remaining_tablerow) > 0:" self.remaining_tablerow.update(set(tableRow[99:])) tableRow = tableRow[:99] aBP.setVarBinds(self.reqPDU, [(v2c.ObjectIdentifier(x), v2c.null) for x in tableRow]) aBP.setRequestID(self.reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage(encoder.encode(self.reqMsg), transportDomain, transportAddress) self.nb_next_requests = self.nb_next_requests + 1 return wholeMsg # LOCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK try: # Get OID from memcache self.obj = self.memcached.get(self.obj_key) except ValueError, e: logger.error('[SnmpBooster] Memcached error while getting: `%s' % self.obj_key) self.set_exit("Memcached error: `%s'" % self.memcached.get(self.obj_key), 3, transportDispatcher) return wholeMsg self.obj.frequences[self.check_interval].old_check_time = copy.copy(self.obj.frequences[self.check_interval].check_time) self.obj.frequences[self.check_interval].check_time = self.start_time # We have to do the mapping instance if not self.mapping_done: # TODO: need more documentation self.obj.instances = mapping_instance self.obj.map_instances(self.check_interval) s = self.obj.frequences[self.check_interval].services[self.serv_key] self.obj.frequences[self.check_interval].checking = False self.memcached.set(self.obj_key, self.obj, time=604800) if s.instance.startswith("map("): result_oids_mapping = set([".%s" % str(o).rsplit(".", 1)[0] for t in varBindTable for o, _ in t]) if not result_oids_mapping.intersection(set(self.mapping_oids.keys())): s.instance = "NOTFOUND" self.obj.frequences[self.check_interval].checking = False self.memcached.set(self.obj_key, self.obj, time=604800) logger.info("[SnmpBooster] - Instance mapping not found. " "Please check your config") self.set_exit("%s: Instance mapping not found. " "Please check your config" % s.instance_name, 3, transportDispatcher) # Stop if oid not in mappping oidS return # Mapping not finished aBP.setVarBinds(self.reqPDU, [(x, v2c.null) for x, y in varBindTable[-1]]) aBP.setRequestID(self.reqPDU, v2c.getNextRequestID()) transportDispatcher.sendMessage(encoder.encode(self.reqMsg), transportDomain, transportAddress) return wholeMsg logger.info("[SnmpBooster] - Instance mapping completed. " "Expect results at next check") self.set_exit("Instance mapping completed. " "Expect results at next check", 3, transportDispatcher) return # set Limits if not self.limits_done: self.obj.set_limits(self.check_interval, self.results_limits_dict) self.memcached.set(self.obj_key, self.obj, time=604800) # Save values self.oids_to_check = self.obj.get_oids_by_frequence(self.check_interval) for oid, value in self.results_oid_dict.items(): if value != None: self.oids_to_check[oid].raw_value = str(value) else: self.oids_to_check[oid].raw_value = None # save data self.obj.frequences[self.check_interval].checking = False self.memcached.set(self.obj_key, self.obj, time=604800) # UNLOCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK if time.time() - self.snmp_request_start_time > self.timeout: self.set_exit("SNMP Request timed out", 3, transportDispatcher) #return wholeMsg self.snmp_request_start_time = time.time()