def n_TrapV2cParams_exit(self, cbCtx, node): snmpEngine, ctx = cbCtx if 'informMode' in ctx: pdu = v2c.InformRequestPDU() v2c.apiPDU.setDefaults(pdu) else: pdu = v2c.TrapPDU() v2c.apiTrapPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, [(v2c.ObjectIdentifier('1.3.6.1.2.1.1.3.0'), v2c.TimeTicks(ctx['Uptime'])), (v2c.ObjectIdentifier('1.3.6.1.6.3.1.1.4.1.0'), v2c.ObjectIdentifier(ctx['TrapOid']))]) ctx['pdu'] = pdu
def _ensureVarBinds(varBinds): # Add sysUpTime if not present already if not varBinds or varBinds[0][0] != sysUpTime: varBinds.insert( 0, (v2c.ObjectIdentifier(sysUpTime), v2c.TimeTicks(0))) # 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 # Fail on missing snmpTrapOID if varBinds[1][0] != snmpTrapOID: raise error.PySnmpError('SNMP notification PDU requires ' 'SNMPv2-MIB::snmpTrapOID.0 to be present') return varBinds
def _generic_trap_filter(domain, sock, pdu, **kwargs): snmpTrapOID = (1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0) if 'host' in kwargs and kwargs['host']: if sock[0] != kwargs['host']: return False for oid, val in v2c.apiPDU.getVarBindList(pdu): if 'oid' in kwargs and kwargs['oid']: if oid == snmpTrapOID: if val[0][0][2] != v2c.ObjectIdentifier(kwargs['oid']): return False return True
def getNextVarBinds(varBinds, origVarBinds=None): errorIndication = None idx = nonNulls = len(varBinds) rspVarBinds = [] while idx: idx -= 1 if varBinds[idx][1].tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet): nonNulls -= 1 elif origVarBinds is not None: if v2c.ObjectIdentifier(origVarBinds[idx][0]).asTuple() >= varBinds[idx][0].asTuple(): errorIndication = errind.oidNotIncreasing rspVarBinds.insert(0, (varBinds[idx][0], __null)) if not nonNulls: rspVarBinds = [] return errorIndication, rspVarBinds
def processCommandRequest(pluginId, snmpEngine, pdu, trunkMsg, reqCtx): reqOids = [] reqCtx['req-oids'] = reqOids reqCtx['req-pdu'] = pdu if pdu.tagSet in (v2c.GetRequestPDU.tagSet, v2c.SetRequestPDU.tagSet): allDenied = True deniedOids = [] for varBindIdx, varBind in enumerate(v2c.apiPDU.getVarBindList(pdu)): oid, val = v2c.apiVarBind.getOIDVal(varBind) oid = tuple(oid) skip, aclIdx = findAcl(oid) # skipped to the next OID if skip != oid: aclIdx = None # OID went out of range if aclIdx is None: # report OIDs we are sending errors for if logDenials: deniedOids.append(str(varBind[0])) else: allDenied = False reqOids.append((oid, varBindIdx, aclIdx)) if logDenials and deniedOids: denialMsg = formatDenialMsg(pdu, trunkMsg) denialMsg += ' OIDs ' + ', '.join(deniedOids) denialMsg += ' denied' error(denialMsg) reqVarBinds = v2c.VarBindList() if allDenied: pdu = v2c.apiPDU.getResponse(pdu) for oid, _, _ in reqOids: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, noSuchInstance)) reqVarBinds.append(varBind) nextAction = status.RESPOND else: for oid, _, aclIdx in reqOids: if aclIdx is None: continue varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, null)) reqVarBinds.append(varBind) nextAction = status.NEXT v2c.apiPDU.setVarBindList(pdu, reqVarBinds) return nextAction, pdu elif pdu.tagSet == v2c.GetNextRequestPDU.tagSet: allDenied = True skippedOids = [] for varBindIdx, varBind in enumerate(v2c.apiPDU.getVarBindList(pdu)): oid, val = v2c.apiVarBind.getOIDVal(varBind) oid = tuple(oid) skip, aclIdx = findAcl(oid, nextOid=True) if logDenials and oid != skip: skippedOids.append((oid, skip)) oid = skip # OID went out of range if aclIdx is not None: allDenied = False reqOids.append((oid, varBindIdx, aclIdx)) if logDenials and skippedOids: denialMsg = formatDenialMsg(pdu, trunkMsg) denialMsg += ' ' + ', '.join([ '%s not in range skipping to %s' % (v2c.ObjectIdentifier(x[0]), v2c.ObjectIdentifier(x[1])) for x in skippedOids ]) info(denialMsg) reqVarBinds = v2c.VarBindList() if allDenied: pdu = v2c.apiPDU.getResponse(pdu) for oid, _, _ in reqOids: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, endOfMibView)) reqVarBinds.append(varBind) nextAction = status.RESPOND else: for oid, _, aclIdx in reqOids: if aclIdx is None: continue varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, null)) reqVarBinds.append(varBind) nextAction = status.NEXT v2c.apiPDU.setVarBindList(pdu, reqVarBinds) return nextAction, pdu elif pdu.tagSet == v2c.GetBulkRequestPDU.tagSet: nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(pdu) maxRepeaters = v2c.apiBulkPDU.getMaxRepetitions(pdu) nonRepOids = [] linearizedOids = [] repOids = [] linearizedOidsMap = {} repeatersOidMap = {} reqCtx['linearized-oids-map'] = linearizedOidsMap reqCtx['repeaters-oids-map'] = repeatersOidMap reqCtx['non-repeaters'] = nonRepeaters allDenied = True skippedOids = [] for varBindIdx, varBind in enumerate( v2c.apiBulkPDU.getVarBindList(pdu)): oid, val = v2c.apiVarBind.getOIDVal(varBind) oid = tuple(oid) skip, aclIdx = findAcl(oid, nextOid=True) if logDenials and oid != skip: skippedOids.append((oid, skip)) oid = skip # original request var-binds reqOids.append((oid, varBindIdx, aclIdx)) # OID went beyond all ranges if aclIdx is None: continue allDenied = False # original request non-repeaters if varBindIdx < nonRepeaters: nonRepOids.append((oid, varBindIdx, aclIdx)) continue # original request repeaters skip, begin, end = oidsList[aclIdx] # move single-OID ranges from repeaters into non-repeaters startIdx = len(nonRepOids) + len(linearizedOids) endIdx = startIdx if begin == end: while endIdx - startIdx < maxRepeaters: linearizedOids.append((oid, varBindIdx, aclIdx)) endIdx += 1 aclIdx += 1 if aclIdx >= len(endOids): break oid, begin, end = oidsList[aclIdx] if begin != end: break linearizedOidsMap[varBindIdx] = startIdx, endIdx debug( '%s: repeating OID #%d (%s) converted into non-repeaters #%d..%d' % (PLUGIN_NAME, varBindIdx, varBind[0], startIdx, endIdx - 1)) continue # proceed with original repeaters repeatersOidMap[varBindIdx] = len(repOids) repOids.append((oid, varBindIdx, aclIdx)) if logDenials and skippedOids: denialMsg = formatDenialMsg(pdu, trunkMsg) denialMsg += ' ' + ', '.join([ '%s not in range skipping to %s' % (v2c.ObjectIdentifier(x[0]), v2c.ObjectIdentifier(x[1])) for x in skippedOids ]) info(denialMsg) # assemble new var-binds reqVarBinds = v2c.VarBindList() if allDenied: pdu = v2c.apiBulkPDU.getResponse(pdu) for oid, _, _ in reqOids: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, endOfMibView)) reqVarBinds.append(varBind) nextAction = status.RESPOND else: for varBindIdx in repeatersOidMap: repeatersOidMap[varBindIdx] += len(nonRepOids) + len( linearizedOids) for oid, varBindIdx, aclIdx in nonRepOids + linearizedOids + repOids: if aclIdx is None: continue varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, null)) reqVarBinds.append(varBind) v2c.apiBulkPDU.setNonRepeaters(pdu, nonRepeaters + len(linearizedOids)) nextAction = status.NEXT v2c.apiPDU.setVarBindList(pdu, reqVarBinds) return nextAction, pdu else: return status.NEXT, pdu
# PDU v1/v2c two-way proxy from pysnmp.proto import rfc1905, rfc3411, error from pysnmp.proto.api import v1, v2c from pysnmp import debug # 2.1.1 __v1ToV2ValueMap = { v1.Integer.tagSet: v2c.Integer32(), v1.OctetString.tagSet: v2c.OctetString(), v1.Null.tagSet: v2c.Null(), v1.ObjectIdentifier.tagSet: v2c.ObjectIdentifier(), v1.IpAddress.tagSet: v2c.IpAddress(), v1.Counter.tagSet: v2c.Counter32(), v1.Gauge.tagSet: v2c.Gauge32(), v1.TimeTicks.tagSet: v2c.TimeTicks(), v1.Opaque.tagSet: v2c.Opaque() } __v2ToV1ValueMap = { # XXX do not re-create same-type items? v2c.Integer32.tagSet: v1.Integer(), v2c.OctetString.tagSet: v1.OctetString(), v2c.Null.tagSet: v1.Null(), v2c.ObjectIdentifier.tagSet: v1.ObjectIdentifier(), v2c.IpAddress.tagSet: v1.IpAddress(), v2c.Counter32.tagSet: v1.Counter(), v2c.Gauge32.tagSet: v1.Gauge(), v2c.TimeTicks.tagSet: v1.TimeTicks(), v2c.Opaque.tagSet: v1.Opaque() }
def v1ToV2(v1Pdu, origV2Pdu=None): pduType = v1Pdu.tagSet v2Pdu = __v1ToV2PduMap[pduType].clone() debug.logger & debug.flagPrx and debug.logger( 'v1ToV2: v1Pdu %s' % v1Pdu.prettyPrint()) v2VarBinds = [] # 3.1 if pduType in rfc3411.notificationClassPDUs: # 3.1.1 sysUpTime = v1.apiTrapPDU.getTimeStamp(v1Pdu) # 3.1.2 genericTrap = v1.apiTrapPDU.getGenericTrap(v1Pdu) if genericTrap == 6: snmpTrapOIDParam = v1.apiTrapPDU.getEnterprise(v1Pdu) + (0,) + \ (int(v1.apiTrapPDU.getSpecificTrap(v1Pdu)),) # 3.1.3 else: snmpTrapOIDParam = v2c.ObjectIdentifier( __v1ToV2TrapMap[genericTrap]) # 3.1.4 (XXX snmpTrapCommunity.0 is missing here) v2VarBinds.append((v2c.apiTrapPDU.sysUpTime, sysUpTime)) v2VarBinds.append((v2c.apiTrapPDU.snmpTrapOID, snmpTrapOIDParam)) v2VarBinds.append((v2c.apiTrapPDU.snmpTrapAddress, v1.apiTrapPDU.getAgentAddr(v1Pdu))) v2VarBinds.append( (v2c.apiTrapPDU.snmpTrapCommunity, v2c.OctetString(""))) v2VarBinds.append((v2c.apiTrapPDU.snmpTrapEnterprise, v1.apiTrapPDU.getEnterprise(v1Pdu))) varBinds = v1.apiTrapPDU.getVarBinds(v1Pdu) else: varBinds = v1.apiPDU.getVarBinds(v1Pdu) # Translate Var-Binds for oid, v1Val in varBinds: # 2.1.1.11 if v1Val.tagSet == v1.NetworkAddress.tagSet: v1Val = v1Val.getComponent() v2VarBinds.append((oid, __v1ToV2ValueMap[v1Val.tagSet].clone(v1Val))) if pduType in rfc3411.responseClassPDUs: # 4.1.2.2.1&2 errorStatus = int(v1.apiPDU.getErrorStatus(v1Pdu)) errorIndex = int(v1.apiPDU.getErrorIndex(v1Pdu)) if errorStatus == 2: # noSuchName if origV2Pdu.tagSet == v2c.GetNextRequestPDU.tagSet: v2VarBinds[errorIndex - 1] = (v2VarBinds[errorIndex - 1][0], rfc1905.endOfMibView) else: v2VarBinds[errorIndex - 1] = (v2VarBinds[errorIndex - 1][0], rfc1905.noSuchObject) # one-to-one mapping v2c.apiPDU.setErrorStatus(v2Pdu, errorStatus) v2c.apiPDU.setErrorIndex(v2Pdu, errorIndex) # 4.1.2.1 --> no-op if pduType not in rfc3411.notificationClassPDUs: v2c.apiPDU.setRequestID(v2Pdu, int(v1.apiPDU.getRequestID(v1Pdu))) v2c.apiPDU.setVarBinds(v2Pdu, v2VarBinds) debug.logger & debug.flagPrx and debug.logger( 'v1ToV2: v2Pdu %s' % v2Pdu.prettyPrint()) return v2Pdu
# *** SNMP engine configuration is complete by this line *** # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets 'my-notification', # notification targets None, '', # contextEngineId, contextName # var-binds [ # Uptime value with 12345 (v2c.ObjectIdentifier('1.3.6.1.2.1.1.3.0'), v2c.TimeTicks(12345)), # trap OID: Generic Trap #6 (enterpriseSpecific) # and Specific Trap 432 (v2c.ObjectIdentifier('1.3.6.1.6.3.1.1.4.1.0'), v2c.ObjectIdentifier('1.3.6.1.4.1.20408.4.1.1.2.0.432')), # Agent Address with '127.0.0.1' (v2c.ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'), v2c.IpAddress('127.0.0.1')), # Enterprise OID with 1.3.6.1.4.1.20408.4.1.1.2 (v2c.ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'), v2c.ObjectIdentifier('1.3.6.1.4.1.20408.4.1.1.2')), # managed object '1.3.6.1.2.1.1.1.0' = 'my system' (v2c.ObjectIdentifier('1.3.6.1.2.1.1.1.0'), v2c.OctetString('my system')) ])
def SnmpwalkAsync(target_IP=None, oid=None, community='public', walk_timeout=10, mode='ipv4'): """Script to run in the remote device for snmp mib walk. This script can be copied to the remote device eg:wan and can be executed directly using python for snmp mib walk The walk can done for both ipv6 and ipv4 :param target_IP: device IP for mib query :type target_IP: string :param oid: mib query OID :type oid: string :param community: community string for mib query, defaults to public :type community: string, optional :param walk_timeout: snmp walk timeout, defaults to 10 :type walk_timeout: integer, optional :param mode: mib query mode, defaults to ipv4 :type mode: string, optional :return: mib query output :rtype: string """ # SNMP table header headVars = [v2c.ObjectIdentifier((oid))] # Build PDU reqPDU = v2c.GetBulkRequestPDU() v2c.apiBulkPDU.setDefaults(reqPDU) v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0) v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25) v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x in headVars]) # Build message reqMsg = v2c.Message() v2c.apiMessage.setDefaults(reqMsg) v2c.apiMessage.setCommunity(reqMsg, community) v2c.apiMessage.setPDU(reqMsg, reqPDU) startedAt = time.time() output_list = [] def cbTimerFun(timeNow): # Duration if timeNow - startedAt > walk_timeout: if walk_timeout != 0: raise Exception("Request timed out") else: if timeNow - startedAt > 30: transportDispatcher.jobFinished(1) # noinspection PyUnusedLocal 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 transportDispatcher = AsyncoreDispatcher() transportDispatcher.registerRecvCbFun(cbRecvFun) transportDispatcher.registerTimerCbFun(cbTimerFun) if mode == 'ipv4': transportDispatcher.registerTransport( udp.domainName, udp.UdpSocketTransport().openClientMode()) transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName, (target_IP, 161)) else: transportDispatcher.registerTransport( udp6.domainName, udp6.Udp6SocketTransport().openClientMode()) transportDispatcher.sendMessage(encoder.encode(reqMsg), udp6.domainName, (target_IP, 161)) transportDispatcher.jobStarted(1) # Dispatcher will finish as job#1 counter reaches zero transportDispatcher.runDispatcher() transportDispatcher.closeDispatcher() if output_list != []: return output_list else: return
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
# Delete duplication self.headVars = list(set(self.headVars)) # Build PDU self.reqPDU = v2c.GetBulkRequestPDU() v2c.apiBulkPDU.setDefaults(self.reqPDU) v2c.apiBulkPDU.setNonRepeaters(self.reqPDU, 0) v2c.apiBulkPDU.setMaxRepetitions(self.reqPDU, self.max_repetitions) # Cut SNMP request if it is too long if len(self.headVars) >= 100: self.remaining_tablerow = set(self.headVars[99:]) self.headVars = self.headVars[:99] v2c.apiBulkPDU.setVarBinds(self.reqPDU, [(v2c.ObjectIdentifier(tuple(int(i) for i in x.split("."))), v2c.null) for x in sorted(self.headVars)]) # Build message self.reqMsg = v2c.Message() v2c.apiMessage.setDefaults(self.reqMsg) v2c.apiMessage.setCommunity(self.reqMsg, self.community) v2c.apiMessage.setPDU(self.reqMsg, self.reqPDU) # Save the time when snmp request start self.snmp_request_start_time = time.time() # Prepare SNMP Request transportDispatcher = AsynsockDispatcher() transportDispatcher.registerTransport(udp.domainName, udp.UdpSocketTransport().openClientMode())
for line in open(configFile).readlines(): line = line.strip() if not line or line.startswith('#'): continue try: skip, begin, end = line.split() except ValueError: raise SnmpfwdError('%s: bad configuration syntax: "%s"' % (PLUGIN_NAME, line)) try: skip = v2c.ObjectIdentifier(skip) begin = v2c.ObjectIdentifier(begin) end = v2c.ObjectIdentifier(end) except Exception: raise SnmpfwdError('%s: malformed OID %s/%s/%s' % (PLUGIN_NAME, skip, begin, end)) oidsList.append((skip, begin, end)) oidsList.sort(key=lambda x: x[0]) idx = 0 while idx < len(oidsList): skip, begin, end = oidsList[idx] if skip >= begin:
# Error/confirmation receiver # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal,PyUnusedLocal,PyUnusedLocal def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): print('Notification %s, status - %s' % (sendRequestHandle, errorIndication and errorIndication or 'delivered')) # Build and submit notification message to dispatcher sendRequestHandle = ntfOrg.sendVarBinds( snmpEngine, 'my-notification', # notification targets None, '', # contextEngineId, contextName # var-binds [ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart ((1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0), v2c.ObjectIdentifier((1, 3, 6, 1, 6, 3, 1, 1, 5, 1))), # additional var-binds: ( (oid, value), ... ) ((1, 3, 6, 1, 2, 1, 1, 1, 0), v2c.OctetString('Example Notificator')), ((1, 3, 6, 1, 2, 1, 1, 5, 0), v2c.OctetString('Notificator Example')) ], cbFun) print('Notification %s scheduled to be sent' % sendRequestHandle) # Run I/O dispatcher which would send pending message and process response snmpEngine.transportDispatcher.runDispatcher()
snmpEngine, 'my-nms', udp.domainName, ('195.218.195.228', 162), 'my-creds' ) # *** SNMP engine configuration is complete by this line *** # Create SNMP v2c TRAP PDU with defaults trapPDU = v2c.TrapPDU() v2c.apiTrapPDU.setDefaults(trapPDU) # Set custom var-binds to TRAP PDU v2c.apiTrapPDU.setVarBinds( trapPDU, [ # sysUpTime (v2c.ObjectIdentifier('1.3.6.1.2.1.1.3.0'), v2c.TimeTicks(123)), # snmpTrapPDU ((1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0), v2c.ObjectIdentifier((1, 3, 6, 1, 6, 3, 1, 1, 5, 1))) ] ) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() # Error/confirmation receiver # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal,PyUnusedLocal,PyUnusedLocal def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): print('Notification %s, status - %s' % ( sendRequestHandle, errorIndication and errorIndication or 'delivered'
def v1ToV2(v1Pdu, origV2Pdu=None, snmpTrapCommunity=''): pduType = v1Pdu.tagSet v2Pdu = V1_TO_V2_PDU_MAP[pduType].clone() debug.logger & debug.FLAG_PRX and debug.logger( 'v1ToV2: v1Pdu %s' % v1Pdu.prettyPrint()) v2VarBinds = [] # 3.1 if pduType in rfc3411.NOTIFICATION_CLASS_PDUS: # 3.1.1 sysUpTime = v1.apiTrapPDU.getTimeStamp(v1Pdu) # 3.1.2 genericTrap = v1.apiTrapPDU.getGenericTrap(v1Pdu) if genericTrap == 6: snmpTrapOIDParam = (v1.apiTrapPDU.getEnterprise(v1Pdu) + (0, int(v1.apiTrapPDU.getSpecificTrap(v1Pdu)))) # 3.1.3 else: snmpTrapOIDParam = v2c.ObjectIdentifier(V1_TO_V2_TRAP_MAP[genericTrap]) # 3.1.4 v2VarBinds.append( (v2c.apiTrapPDU.sysUpTime, sysUpTime)) v2VarBinds.append( (v2c.apiTrapPDU.snmpTrapOID, snmpTrapOIDParam)) v2VarBinds.append( (v2c.apiTrapPDU.snmpTrapAddress, v1.apiTrapPDU.getAgentAddr(v1Pdu))) v2VarBinds.append( (v2c.apiTrapPDU.snmpTrapCommunity, v2c.OctetString(snmpTrapCommunity))) v2VarBinds.append( (v2c.apiTrapPDU.snmpTrapEnterprise, v1.apiTrapPDU.getEnterprise(v1Pdu))) varBinds = v1.apiTrapPDU.getVarBinds(v1Pdu) else: varBinds = v1.apiPDU.getVarBinds(v1Pdu) # Translate Var-Binds for oid, v1Val in varBinds: # 2.1.1.11 if v1Val.tagSet == v1.NetworkAddress.tagSet: v1Val = v1Val.getComponent() v2VarBinds.append( (oid, V1_TO_V2_VALUE_MAP[v1Val.tagSet].clone(v1Val))) if pduType in rfc3411.RESPONSE_CLASS_PDUS: # 4.1.2.2.1&2 errorStatus = int(v1.apiPDU.getErrorStatus(v1Pdu)) errorIndex = int(v1.apiPDU.getErrorIndex(v1Pdu, muteErrors=True)) if errorStatus == 2: # noSuchName if origV2Pdu.tagSet == v2c.GetNextRequestPDU.tagSet: v2VarBinds = [(o, rfc1905.endOfMibView) for o, v in v2VarBinds] else: v2VarBinds = [(o, rfc1905.noSuchObject) for o, v in v2VarBinds] # partial one-to-one mapping - 4.2.1 v2c.apiPDU.setErrorStatus(v2Pdu, errorStatus) v2c.apiPDU.setErrorIndex(v2Pdu, errorIndex) # 4.1.2.1 --> no-op elif pduType in rfc3411.CONFIRMED_CLASS_PDUS: v2c.apiPDU.setErrorStatus(v2Pdu, 0) v2c.apiPDU.setErrorIndex(v2Pdu, 0) if pduType not in rfc3411.NOTIFICATION_CLASS_PDUS: v2c.apiPDU.setRequestID(v2Pdu, int(v1.apiPDU.getRequestID(v1Pdu))) v2c.apiPDU.setVarBinds(v2Pdu, v2VarBinds) debug.logger & debug.FLAG_PRX and debug.logger( 'v1ToV2: v2Pdu %s' % v2Pdu.prettyPrint()) return v2Pdu
def sendTheTrap(): uptime = getUptime() # Create SNMP engine instance with specific (and locally unique) # SnmpEngineId -- it must also be known to the receiving party # and configured at its VACM users table. snmpEngine = engine.SnmpEngine(snmpEngineID=v2c.OctetString( hexValue='0102030405060708')) # Add USM user config.addV3User(snmpEngine, userConfig['DEFAULT']['SNMPUSER'], config.usmHMAC128SHA224AuthProtocol, userConfig['DEFAULT']['SNMPAUTH'], config.usmAesCfb192Protocol, userConfig['DEFAULT']['SNMPPRIV']) config.addTargetParams(snmpEngine, userConfig['DEFAULT']['SNMPAUTH'], userConfig['DEFAULT']['SNMPUSER'], 'authPriv') # Setup transport endpoint and bind it with security settings yielding # a target name config.addTransport(snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'my-nms', udp.domainName, (userConfig['DEFAULT']['SNMPMANAGERIP'], int(userConfig['DEFAULT']['SNMPMANAGERPORT'])), userConfig['DEFAULT']['SNMPAUTH'], tagList='all-my-managers') # Specify what kind of notification should be sent (TRAP or INFORM), # to what targets (chosen by tag) and what filter should apply to # the set of targets (selected by tag) config.addNotificationTarget(snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap') # Allow NOTIFY access to Agent's MIB by this SNMP model (3), securityLevel # and SecurityName config.addContext(snmpEngine, '') config.addVacmUser(snmpEngine, 3, userConfig['DEFAULT']['SNMPUSER'], 'authPriv', (), (), (1, 3, 6), 'aContextName') # *** SNMP engine configuration is complete by this line *** # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets 'my-notification', # notification targets None, 'aContextName', # contextEngineId, contextName # var-binds [((1, 3, 6, 1, 2, 1, 1, 3, 0), v2c.OctetString(uptime)), ((1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0), v2c.ObjectIdentifier((1, 3, 6, 1, 6, 3, 1, 1, 5, 1))), ((1, 3, 6, 1, 2, 1, 1, 5, 0), v2c.OctetString(socket.getfqdn())), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 10, 0), v2c.OctetString('Application')), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 11, 0), v2c.OctetString('Performance')), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 12, 0), v2c.OctetString('critical')), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 19, 0), v2c.OctetString('health')), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 20, 0), v2c.OctetString('vROpsExternalMonitorService.py')), ((1, 3, 6, 1, 4, 1, 6876, 4, 50, 1, 2, 50, 0), v2c.OctetString( 'vROps services are having issues, please check nodes'))]) print('Notification is scheduled to be sent') # Run I/O dispatcher which would send pending message and process response snmpEngine.transportDispatcher.runDispatcher()
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 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()
def _setup(self, q): """Setup a new agent in a separate process. The port the agent is listening too will be returned using the provided queue. """ port = random.randrange(22000, 22989) snmpEngine = engine.SnmpEngine() if self.ipv6: config.addSocketTransport( snmpEngine, udp6.domainName, udp6.Udp6Transport().openServerMode(('::1', port))) else: config.addSocketTransport( snmpEngine, udp.domainName, udp.UdpTransport().openServerMode(('127.0.0.1', port))) # Community is public and MIB is writable config.addV1System(snmpEngine, 'read-write', 'public') config.addVacmUser(snmpEngine, 1, 'read-write', 'noAuthNoPriv', (1, 3, 6), (1, 3, 6)) config.addVacmUser(snmpEngine, 2, 'read-write', 'noAuthNoPriv', (1, 3, 6), (1, 3, 6)) config.addV3User(snmpEngine, 'read-write', config.usmHMACMD5AuthProtocol, 'authpass', config.usmAesCfb128Protocol, 'privpass') config.addVacmUser(snmpEngine, 3, 'read-write', 'authPriv', (1, 3, 6), (1, 3, 6)) # Build MIB def stringToOid(string): return [ord(x) for x in string] def flatten(*args): result = [] for el in args: if isinstance(el, (list, tuple)): for sub in el: result.append(sub) else: result.append(el) return tuple(result) snmpContext = context.SnmpContext(snmpEngine) mibBuilder = snmpContext.getMibInstrum().getMibBuilder() (MibTable, MibTableRow, MibTableColumn, MibScalar, MibScalarInstance) = mibBuilder.importSymbols( 'SNMPv2-SMI', 'MibTable', 'MibTableRow', 'MibTableColumn', 'MibScalar', 'MibScalarInstance') mibBuilder.exportSymbols( '__MY_SNMPv2_MIB', # SNMPv2-MIB::sysDescr MibScalar((1, 3, 6, 1, 2, 1, 1, 1), v2c.OctetString()), MibScalarInstance((1, 3, 6, 1, 2, 1, 1, 1), (0, ), v2c.OctetString("Snimpy Test Agent"))) mibBuilder.exportSymbols( '__MY_IF_MIB', # IF-MIB::ifNumber MibScalar((1, 3, 6, 1, 2, 1, 2, 1), v2c.Integer()), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 1), (0, ), v2c.Integer(3)), # IF-MIB::ifTable MibTable((1, 3, 6, 1, 2, 1, 2, 2)), MibTableRow((1, 3, 6, 1, 2, 1, 2, 2, 1)).setIndexNames( (0, '__MY_IF_MIB', 'ifIndex')), # IF-MIB::ifIndex MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (1, ), v2c.Integer(1)), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (2, ), v2c.Integer(2)), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), (3, ), v2c.Integer(3)), # IF-MIB::ifDescr MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), v2c.OctetString()), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (1, ), v2c.OctetString("lo")), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (2, ), v2c.OctetString("eth0")), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), (3, ), v2c.OctetString("eth1")), # IF-MIB::ifType MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), v2c.Integer()), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (1, ), v2c.Integer(24)), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (2, ), v2c.Integer(6)), MibScalarInstance((1, 3, 6, 1, 2, 1, 2, 2, 1, 3), (3, ), v2c.Integer(6)), # IF-MIB::ifIndex ifIndex=MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 1), v2c.Integer())) mibBuilder.exportSymbols( '__MY_SNIMPY-MIB', # SNIMPY-MIB::snimpyIpAddress MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 1), v2c.OctetString()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 1), (0, ), v2c.OctetString("AAAA")), # SNIMPY-MIB::snimpyString MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 2), v2c.OctetString()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 2), (0, ), v2c.OctetString("bye")), # SNIMPY-MIB::snimpyInteger MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 3), v2c.Integer()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 3), (0, ), v2c.Integer(19)), # SNIMPY-MIB::snimpyEnum MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 4), v2c.Integer()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 4), (0, ), v2c.Integer(2)), # SNIMPY-MIB::snimpyObjectId MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 5), v2c.ObjectIdentifier()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 5), (0, ), v2c.ObjectIdentifier((1, 3, 6, 4454, 0, 0))), # SNIMPY-MIB::snimpyBoolean MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 6), v2c.Integer()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 6), (0, ), v2c.Integer(1)), # SNIMPY-MIB::snimpyCounter MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 7), v2c.Counter32()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 7), (0, ), v2c.Counter32(47)), # SNIMPY-MIB::snimpyGauge MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 8), v2c.Gauge32()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 8), (0, ), v2c.Gauge32(18)), # SNIMPY-MIB::snimpyTimeticks MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 9), v2c.TimeTicks()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 9), (0, ), v2c.TimeTicks(12111100)), # SNIMPY-MIB::snimpyCounter64 MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 10), v2c.Counter64()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 10), (0, ), v2c.Counter64(2**48 + 3)), # SNIMPY-MIB::snimpyBits MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 11), v2c.OctetString()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 11), (0, ), v2c.OctetString(b"\xa0")), # SNIMPY-MIB::snimpyMacAddress MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 15), v2c.OctetString()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 15), (0, ), v2c.OctetString(b"\x11\x12\x13\x14\x15\x16")), # SNIMPY-MIB::snimpyMacAddressInvalid MibScalar((1, 3, 6, 1, 2, 1, 45121, 1, 16), v2c.OctetString()).setMaxAccess("readwrite"), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 1, 16), (0, ), v2c.OctetString(b"\xf1\x12\x13\x14\x15\x16")), # SNIMPY-MIB::snimpyIndexTable MibTable((1, 3, 6, 1, 2, 1, 45121, 2, 3)), MibTableRow((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1)).setIndexNames( (0, "__MY_SNIMPY-MIB", "snimpyIndexVarLen"), (0, "__MY_SNIMPY-MIB", "snimpyIndexOidVarLen"), (0, "__MY_SNIMPY-MIB", "snimpyIndexFixedLen"), (1, "__MY_SNIMPY-MIB", "snimpyIndexImplied")), # SNIMPY-MIB::snimpyIndexInt MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6), flatten(4, stringToOid('row1'), 3, 1, 2, 3, stringToOid('alpha5'), stringToOid('end of row1')), v2c.Integer(4571)), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6), flatten(4, stringToOid('row2'), 4, 1, 0, 2, 3, stringToOid('beta32'), stringToOid('end of row2')), v2c.Integer(78741)), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6), flatten(4, stringToOid('row3'), 4, 120, 1, 2, 3, stringToOid('gamma7'), stringToOid('end of row3')), v2c.Integer(4110)), # SNIMPY-MIB::snimpyInvalidTable MibTable((1, 3, 6, 1, 2, 1, 45121, 2, 5)), MibTableRow((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1)).setIndexNames( (0, "__MY_SNIMPY-MIB", "snimpyInvalidIndex")), # SNIMPY-MIB::snimpyInvalidDescr MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2), (1, ), v2c.OctetString(b"Hello")), MibScalarInstance((1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2), (2, ), v2c.OctetString(b"\xf1\x12\x13\x14\x15\x16")), # Indexes snimpyIndexVarLen=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 1), v2c.OctetString()).setMaxAccess("noaccess"), snimpyIndexIntIndex=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 2), v2c.Integer()).setMaxAccess("noaccess"), snimpyIndexOidVarLen=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 3), v2c.ObjectIdentifier()).setMaxAccess("noaccess"), snimpyIndexFixedLen=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 4), v2c.OctetString().setFixedLength(6)).setMaxAccess("noaccess"), snimpyIndexImplied=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 5), v2c.OctetString()).setMaxAccess("noaccess"), snimpyIndexInt=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 3, 1, 6), v2c.Integer()).setMaxAccess("readwrite"), snimpyInvalidIndex=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 1), v2c.Integer()).setMaxAccess("noaccess"), snimpyInvalidDescr=MibTableColumn( (1, 3, 6, 1, 2, 1, 45121, 2, 5, 1, 2), v2c.OctetString()).setMaxAccess("readwrite")) # Start agent cmdrsp.GetCommandResponder(snmpEngine, snmpContext) cmdrsp.SetCommandResponder(snmpEngine, snmpContext) cmdrsp.NextCommandResponder(snmpEngine, snmpContext) cmdrsp.BulkCommandResponder(snmpEngine, snmpContext) q.put(port) snmpEngine.transportDispatcher.jobStarted(1) snmpEngine.transportDispatcher.runDispatcher()
def processCommandResponse(pluginId, snmpEngine, pdu, trunkMsg, reqCtx): if pdu.tagSet != v2c.GetResponsePDU.tagSet: return status.NEXT, pdu try: reqPdu = reqCtx['req-pdu'] reqOids = reqCtx['req-oids'] except KeyError: return status.NEXT, pdu if reqPdu.tagSet in (v2c.GetRequestPDU.tagSet, v2c.SetRequestPDU.tagSet, v2c.GetNextRequestPDU.tagSet): nextCmd = reqPdu.tagSet == v2c.GetNextRequestPDU.tagSet rspVarBinds = v2c.apiPDU.getVarBindList(pdu) terminatedOids = [] mutedOids = [] rspVarBindIdx = 0 varBinds = v2c.VarBindList() for oid, reqVarBindIdx, aclIdx in reqOids: if aclIdx is None: varBind = v2c.VarBind() if nextCmd: v2c.apiVarBind.setOIDVal(varBind, (oid, endOfMibView)) else: v2c.apiVarBind.setOIDVal(varBind, (oid, noSuchInstance)) else: try: varBind = rspVarBinds[rspVarBindIdx] except IndexError: error('%s: missing response OID #%s' % (PLUGIN_NAME, rspVarBindIdx)) return status.DROP, pdu rspVarBindIdx += 1 overrideLeakingOid(varBind, aclIdx, mutedOids, terminatedOids) varBinds.append(varBind) if logDenials and (terminatedOids or mutedOids): denialMsg = formatDenialMsg(pdu, trunkMsg) if terminatedOids: denialMsg += ' ' + 'OID(s) %s replaced with %s and reported as <end-of-mib>' % ( ','.join([ str(v2c.ObjectIdentifier(x[0])) for x in terminatedOids ]), ','.join([ str(v2c.ObjectIdentifier(x[1])) for x in terminatedOids ])) if mutedOids: denialMsg += ' ' + 'OID(s) %s replaced with %s and reported as <nil>' % ( ','.join( [str(v2c.ObjectIdentifier(x[0])) for x in mutedOids]), ','. join([str(v2c.ObjectIdentifier(x[1])) for x in mutedOids])) info(denialMsg) v2c.apiPDU.setVarBindList(pdu, varBinds) return status.NEXT, pdu elif reqPdu.tagSet == v2c.GetBulkRequestPDU.tagSet: linearizedOidsMap = reqCtx['linearized-oids-map'] if linearizedOidsMap: linearizedColumnDepth = max( [x[1] - x[0] for x in linearizedOidsMap.values()]) else: linearizedColumnDepth = 0 repeatersOidsMap = reqCtx['repeaters-oids-map'] origNonRepeaters = int(reqCtx['non-repeaters']) nonRepeaters = int(v2c.apiBulkPDU.getNonRepeaters(reqPdu)) reqVarBinds = v2c.apiBulkPDU.getVarBindList(reqPdu) rspVarBinds = v2c.apiBulkPDU.getVarBindList(pdu) maxColumns = len(reqVarBinds) - nonRepeaters if maxColumns: columnDepth = (len(rspVarBinds) - nonRepeaters) // maxColumns else: columnDepth = 0 if columnDepth < 0: error('%s: malformed GETBULK response table' % PLUGIN_NAME) return status.DROP, pdu maxColumnDepth = max(columnDepth, linearizedColumnDepth) nonRepVarBinds = [] repVarBindTable = [] terminatedOids = [] mutedOids = [] try: # Walk over original request var-binds for oid, reqVarBindIdx, aclIdx in reqOids: # copy over original non-repeaters if reqVarBindIdx < origNonRepeaters: # locally terminated var-binds if aclIdx is None: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (oid, endOfMibView)) else: varBind = rspVarBinds[reqVarBindIdx] overrideLeakingOid(varBind, aclIdx, mutedOids, terminatedOids) nonRepVarBinds.append(varBind) continue # process linearized OIDs elif reqVarBindIdx in linearizedOidsMap: startIdx, endIdx = linearizedOidsMap[reqVarBindIdx] override = oid repVarBindTable.append([]) # move non-repeaters into repeaters as individual columns for rspVarBindIdx in range(startIdx, endIdx): if rspVarBindIdx - startIdx < maxColumnDepth: varBind = rspVarBinds[rspVarBindIdx] override = overrideLeakingOid( varBind, aclIdx, mutedOids, terminatedOids) repVarBindTable[-1].append(varBind) # this assumes that aclIdx grows with endIdx aclIdx += 1 else: break # pad insufficient rows insufficientRows = maxColumnDepth - (endIdx - startIdx) while insufficientRows: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (override, null)) repVarBindTable[-1].append(varBind) insufficientRows -= 1 # copy over original repeaters into individual columns elif reqVarBindIdx in repeatersOidsMap: override = oid repVarBindTable.append([]) startIdx = repeatersOidsMap[reqVarBindIdx] for row in range(maxColumnDepth): if aclIdx is not None and row < columnDepth: rspVarBindIdx = startIdx + maxColumns * row varBind = rspVarBinds[rspVarBindIdx] override = overrideLeakingOid( varBind, aclIdx, mutedOids, terminatedOids) else: varBind = v2c.VarBind() v2c.apiVarBind.setOIDVal(varBind, (override, null)) repVarBindTable[-1].append(varBind) else: error('%s: malformed GETBULK state information!' % PLUGIN_NAME) return status.DROP, pdu except IndexError: error('%s: short GETBULK response PDU' % PLUGIN_NAME) return status.DROP, pdu if logDenials and (terminatedOids or mutedOids): denialMsg = formatDenialMsg(pdu, trunkMsg) if terminatedOids: denialMsg += ' ' + 'OID(s) %s replaced with %s and reported as <end-of-mib>' % ( ','.join([ str(v2c.ObjectIdentifier(x[0])) for x in terminatedOids ]), ','.join([ str(v2c.ObjectIdentifier(x[1])) for x in terminatedOids ])) if mutedOids: denialMsg += ' ' + 'OID(s) %s replaced with %s and reported as <nil>' % ( ','.join( [str(v2c.ObjectIdentifier(x[0])) for x in mutedOids]), ','. join([str(v2c.ObjectIdentifier(x[1])) for x in mutedOids])) info(denialMsg) varBinds = v2c.VarBindList() for varBind in nonRepVarBinds: varBinds.append(varBind) for row in range(maxColumnDepth): for repVarBinds in repVarBindTable: varBinds.append(repVarBinds[row]) v2c.apiBulkPDU.setVarBindList(pdu, varBinds) return status.NEXT, pdu else: return status.NEXT, pdu
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
* for OID in tuple form * with non-repeaters=0 and max-repeaters=25 This script performs similar to the following Net-SNMP command: | $ snmpbulkwalk -v2c -c public -ObentU -Cn0 -Cr25 demo.snmplabs.com 1.3.6 """# from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher from pysnmp.carrier.asyncore.dgram import udp from pyasn1.codec.ber import encoder, decoder from pysnmp.proto.api import v2c from time import time # SNMP table header headVars = [v2c.ObjectIdentifier((1, 3, 6))] # Build PDU reqPDU = v2c.GetBulkRequestPDU() v2c.apiBulkPDU.setDefaults(reqPDU) v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0) v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25) v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x in headVars]) # Build message reqMsg = v2c.Message() v2c.apiMessage.setDefaults(reqMsg) v2c.apiMessage.setCommunity(reqMsg, 'public') v2c.apiMessage.setPDU(reqMsg, reqPDU) startedAt = time()