def __coerce_value(initial_value, new_value): """Coerce the new_value to the same type as the initial_value. :param initial_value: initial value from the device :param new_value: new value to set, coerced into the right type :return: new value, coerced into the right type """ # pylint: disable=redefined-variable-type # In order to return the right type the return value has to be # redefined. # Types from RFC-1902 if isinstance(initial_value, rfc1902.Counter32): set_value = rfc1902.Counter32(str(new_value)) elif isinstance(initial_value, rfc1902.Counter64): set_value = rfc1902.Counter64(str(new_value)) elif isinstance(initial_value, rfc1902.Gauge32): set_value = rfc1902.Gauge32(str(new_value)) elif isinstance(initial_value, rfc1902.Integer): set_value = rfc1902.Integer(str(new_value)) elif isinstance(initial_value, rfc1902.Integer32): set_value = rfc1902.Integer32(str(new_value)) elif isinstance(initial_value, rfc1902.IpAddress): set_value = rfc1902.IpAddress(str(new_value)) elif isinstance(initial_value, rfc1902.OctetString): set_value = rfc1902.OctetString(str(new_value)) elif isinstance(initial_value, rfc1902.TimeTicks): set_value = rfc1902.TimeTicks(str(new_value)) elif isinstance(initial_value, rfc1902.Unsigned32): set_value = rfc1902.Unsigned32(str(new_value)) else: raise RuntimeError("Unknown type %s" % type(initial_value)) return set_value
def Snmp(action=None, target_IP=None, community='public', oid=None, stype=None, value=None, walk_timeout=120): """ Name:Snmp Purpose: Do snmp set,get and walk function for DUT control. Input:1.action 2.target_IP 3.community 4.oid 5.stype 6.value 7.walk_timeout Output:Snmp get or walk result """ # Create command generator cmdGen = cmdgen.CommandGenerator() if action == "get": errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.CommunityData(community), cmdgen.UdpTransportTarget((target_IP, 161), timeout=1, retries=3), oid) for name, val in varBinds: if val.prettyPrint() != "": return val.prettyPrint() else: return "null" elif action == "set": for case in switch(stype): if case('i'): value = rfc1902.Integer(value) break elif case('s'): value = rfc1902.OctetString(value) break elif case('x'): value = rfc1902.OctetString(hexValue=value) break elif case('p'): value = rfc1902.IpAddress(value) elif case('u'): value = rfc1902.Unsigned32(value) break elif case(): # default value = "" cmdGen.setCmd( cmdgen.CommunityData(community), cmdgen.UdpTransportTarget((target_IP, 161), timeout=1, retries=3), (oid, value))
def snmpset(self,*args): '''This api is used for oid snmpset operation''' self.snmp_target = (self.host,self.snmp_port) cg = cmdgen.CommandGenerator() comm_data = cmdgen.CommunityData('my-manager', self.community_string) transport = cmdgen.UdpTransportTarget(self.snmp_target) snmpset_data = [] for i in range(len(args[0])): print("\nSNMP COMMAND : " + "snmpset -v2c -c " + self.community_string + ' ' + self.snmp_target[0] + ' ' + args[0][i][0] +' '+ args[0][i][2] +' '+args[0][i][1]+"\n") snmpset_data.append("\nSNMP COMMAND : " + "snmpset -v2c -c " + self.community_string + ' ' + self.snmp_target[0] + ' ' + args[0][i][0] +' '+ args[0][i][2] +' '+args[0][i][1]+"\n") print("<<<<<<<<OUTPUT>>>>>>>>>") snmpset_data.append("<<<<<<<<OUTPUT>>>>>>>>>") if args[0][i][2] == "s": variables = (args[0][i][0], rfc1902.OctetString(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "i": variables = (args[0][i][0], rfc1902.Integer(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "o": variables = (args[0][i][0], rfc1902.Bits(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "t": variables = (args[0][i][0], rfc1902.TimeTicks(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "u": variables = (args[0][i][0], rfc1902.Unsigned32(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "ip": variables = (args[0][i][0], rfc1902.IpAddress(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) elif args[0][i][2] == "U": variables = (args[0][i][0], rfc1902.Gauge32(args[0][i][1])) errIndication, errStatus, errIndex, result = cg.setCmd(comm_data, transport,variables) snmpset_data.append(result) else: pass # Check for errors and print out results if errIndication: print(errIndication) snmpset_data.append(errIndication) elif errStatus: print("REASON :" + '%s at %s' % (errStatus.prettyPrint(),errIndex and result[int(errIndex) - 1][0] or '?')) snmpset_data.append("REASON : "+ '%s at %s' % (errStatus.prettyPrint(),errIndex and result[int(errIndex) - 1][0] or '?')) else: for name, val in result: print('%s = %s' % (name.prettyPrint(), val.prettyPrint())) snmpset_data.append(name.prettyPrint() +" = "+ val.prettyPrint()) return snmpset_data
def _parse_response(self, oid, value): if (self._stop_oid and oid >= self._stop_oid) or value.tagSet in self.TAGS_TO_SKIP: return True elif value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) elif value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) elif value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) response = SnmpResponse(oid, value, snmp_engine=self._snmp_engine, logger=self._logger) self.result.add(response) return False
def pack(self): if self._value >= (1 << 32): raise OverflowError("too large to be packed") if self._value < 0: raise OverflowError("too small to be packed") return rfc1902.Unsigned32(self._value)
def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): if errorIndication and not cbCtx['retries']: cbCtx['errors'] += 1 log.error('SNMP Engine error: %s' % errorIndication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if errorStatus and errorStatus != 2 or errorIndication: log.error('Remote SNMP error %s' % (errorIndication or errorStatus.prettyPrint())) if cbCtx['retries']: try: nextOID = varBindTable[-1][0][0] except IndexError: nextOID = cbCtx['lastOID'] else: log.error('Failed OID: %s' % nextOID) # fuzzy logic of walking a broken OID if len(nextOID) < 4: pass elif (continueOnErrors - cbCtx['retries']) * 10 / continueOnErrors > 5: nextOID = nextOID[:-2] + (nextOID[-2] + 1, ) elif nextOID[-1]: nextOID = nextOID[:-1] + (nextOID[-1] + 1, ) else: nextOID = nextOID[:-2] + (nextOID[-2] + 1, 0) cbCtx['retries'] -= 1 cbCtx['lastOID'] = nextOID log.info('Retrying with OID %s (%s retries left)...' % (nextOID, cbCtx['retries'])) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(nextOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(nextOID, None)], cbFun, cbCtx) cbCtx['errors'] += 1 return if continueOnErrors != cbCtx['retries']: cbCtx['retries'] += 1 if varBindTable and varBindTable[-1] and varBindTable[-1][0]: cbCtx['lastOID'] = varBindTable[-1][0][0] stopFlag = False # Walk var-binds for varBindRow in varBindTable: for oid, value in varBindRow: # EOM if stopOID and oid >= stopOID: stopFlag = True # stop on out of range condition elif (value is None or value.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet)): stopFlag = True # remove value enumeration if value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) if value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) if value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) # Build .snmprec record context = { 'origOid': oid, 'origValue': value, 'count': cbCtx['count'], 'total': cbCtx['total'], 'iteration': cbCtx['iteration'], 'reqTime': cbCtx['reqTime'], 'startOID': startOID, 'stopOID': stopOID, 'stopFlag': stopFlag, 'variationModule': variationModule } try: line = dataFileHandler.format(oid, value, **context) except error.MoreDataNotification: cbCtx['count'] = 0 cbCtx['iteration'] += 1 moreDataNotification = sys.exc_info()[1] if 'period' in moreDataNotification: log.info('%s OIDs dumped, waiting %.2f sec(s)...' % (cbCtx['total'], moreDataNotification['period'])) time.sleep(moreDataNotification['period']) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(startOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(startOID, None)], cbFun, cbCtx) stopFlag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.error((sys.exc_info()[1], )) continue else: outputFile.write(line) cbCtx['count'] += 1 cbCtx['total'] += 1 if cbCtx['count'] % 100 == 0: log.error('OIDs dumped: %s/%s' % (cbCtx['iteration'], cbCtx['count'])) # Next request time cbCtx['reqTime'] = time.time() # Continue walking return not stopFlag
def getValue(syntax, hint='', automaticValues=automaticValues): makeGuess = automaticValues val = None while True: if makeGuess: if isinstance(syntax, rfc1902.IpAddress): val = '.'.join([str(random.randrange(1, 256)) for x in range(4)]) elif isinstance(syntax, rfc1902.TimeTicks): val = random.randrange(timeticksRange[0], timeticksRange[1]) elif isinstance(syntax, rfc1902.Gauge32): val = random.randrange(gaugeRange[0], gaugeRange[1]) elif isinstance(syntax, rfc1902.Counter32): val = random.randrange(counterRange[0], counterRange[1]) elif isinstance(syntax, rfc1902.Integer32): val = random.randrange(int32Range[0], int32Range[1]) elif isinstance(syntax, rfc1902.Unsigned32): val = random.randrange(unsignedRange[0], unsignedRange[1]) elif isinstance(syntax, rfc1902.Counter64): val = random.randrange(counter64Range[0], counter64Range[1]) elif isinstance(syntax, univ.OctetString): maxWords = 10 val = ' '.join([stringPool[random.randrange(0, len(stringPool))] for i in range(random.randrange(1, maxWords))]) elif isinstance(syntax, univ.ObjectIdentifier): val = '.'.join(['1', '3', '6', '1', '3'] + [ '%d' % random.randrange(0, 255) for x in range(random.randrange(0, 10))]) elif isinstance(syntax, rfc1902.Bits): val = [random.randrange(0, 256) for x in range(random.randrange(0, 9))] else: val = '?' # remove value enumeration try: if syntax.tagSet == rfc1902.Integer32.tagSet: return rfc1902.Integer32(syntax.clone(val)) if syntax.tagSet == rfc1902.Unsigned32.tagSet: return rfc1902.Unsigned32(syntax.clone(val)) if syntax.tagSet == rfc1902.Bits.tagSet: return rfc1902.OctetString(syntax.clone(val)) return syntax.clone(val) except PyAsn1Error: if makeGuess == 1: sys.stderr.write( '*** Inconsistent value: %s\r\n*** See constraints and ' 'suggest a better one for:\r\n' % sys.exc_info()[1]) if makeGuess: makeGuess -= 1 continue sys.stderr.write('%s# Value [\'%s\'] ? ' % ( hint, (val is None and '<none>' or val),)) sys.stderr.flush() line = sys.stdin.readline().strip() if line: if line[:2] == '0x': if line[:4] == '0x0x': line = line[2:] elif isinstance(syntax, univ.OctetString): val = syntax.clone(hexValue=line[2:]) else: val = int(line[2:], 16) else: val = line
def convert_to_unsigned32(self, value): """Converts a value to a SNMP Unsigned32 object.""" return rfc1902.Unsigned32(value)
def cbFun(snmp_engine, send_request_handle, error_indication, error_status, error_index, var_bind_table, cb_ctx): if error_indication and not cb_ctx['retries']: cb_ctx['errors'] += 1 log.error('SNMP Engine error: %s' % error_indication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if error_status and error_status != 2 or error_indication: log.error( 'Remote SNMP error %s' % ( error_indication or error_status.prettyPrint())) if cb_ctx['retries']: try: next_oid = var_bind_table[-1][0][0] except IndexError: next_oid = cb_ctx['lastOID'] else: log.error('Failed OID: %s' % next_oid) # fuzzy logic of walking a broken OID if len(next_oid) < 4: pass elif (args.continue_on_errors - cb_ctx['retries']) * 10 / args.continue_on_errors > 5: next_oid = next_oid[:-2] + (next_oid[-2] + 1,) elif next_oid[-1]: next_oid = next_oid[:-1] + (next_oid[-1] + 1,) else: next_oid = next_oid[:-2] + (next_oid[-2] + 1, 0) cb_ctx['retries'] -= 1 cb_ctx['lastOID'] = next_oid log.info( 'Retrying with OID %s (%s retries left)' '...' % (next_oid, cb_ctx['retries'])) # initiate another SNMP walk iteration if args.use_getbulk: cmd_gen.sendVarBinds( snmp_engine, 'tgt', args.v3_context_engine_id, args.v3_context_name, 0, args.getbulk_repetitions, [(next_oid, None)], cbFun, cb_ctx) else: cmd_gen.sendVarBinds( snmp_engine, 'tgt', args.v3_context_engine_id, args.v3_context_name, [(next_oid, None)], cbFun, cb_ctx) cb_ctx['errors'] += 1 return if args.continue_on_errors != cb_ctx['retries']: cb_ctx['retries'] += 1 if var_bind_table and var_bind_table[-1] and var_bind_table[-1][0]: cb_ctx['lastOID'] = var_bind_table[-1][0][0] stop_flag = False # Walk var-binds for var_bind_row in var_bind_table: for oid, value in var_bind_row: # EOM if args.stop_object and oid >= args.stop_object: stop_flag = True # stop on out of range condition elif (value is None or value.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet)): stop_flag = True # remove value enumeration if value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) if value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) if value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) # Build .snmprec record context = { 'origOid': oid, 'origValue': value, 'count': cb_ctx['count'], 'total': cb_ctx['total'], 'iteration': cb_ctx['iteration'], 'reqTime': cb_ctx['reqTime'], 'args.start_object': args.start_object, 'stopOID': args.stop_object, 'stopFlag': stop_flag, 'variationModule': variation_module } try: line = data_file_handler.format(oid, value, **context) except error.MoreDataNotification as exc: cb_ctx['count'] = 0 cb_ctx['iteration'] += 1 more_data_notification = exc if 'period' in more_data_notification: log.info( '%s OIDs dumped, waiting %.2f sec(s)' '...' % (cb_ctx['total'], more_data_notification['period'])) time.sleep(more_data_notification['period']) # initiate another SNMP walk iteration if args.use_getbulk: cmd_gen.sendVarBinds( snmp_engine, 'tgt', args.v3_context_engine_id, args.v3_context_name, 0, args.getbulk_repetitions, [(args.start_object, None)], cbFun, cb_ctx) else: cmd_gen.sendVarBinds( snmp_engine, 'tgt', args.v3_context_engine_id, args.v3_context_name, [(args.start_object, None)], cbFun, cb_ctx) stop_flag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError as exc: log.error(exc) continue else: args.output_file.write(line) cb_ctx['count'] += 1 cb_ctx['total'] += 1 if cb_ctx['count'] % 100 == 0: log.info('OIDs dumped: %s/%s' % ( cb_ctx['iteration'], cb_ctx['count'])) # Next request time cb_ctx['reqTime'] = time.time() # Continue walking return not stop_flag
def cb_fun(self, snmp_engine, send_request_handle, error_indication, error_status, error_index, var_bind_table, cb_ctx): if cb_ctx['is_snmp_timeout'] and self.snmp_parameters.get_bulk_flag: self._get_bulk_flag = True cb_ctx['is_snmp_timeout'] = False if isinstance(error_indication, RequestTimedOut): cb_ctx['is_snmp_timeout'] = True self._get_bulk_flag = False if error_indication and not cb_ctx['retries']: cb_ctx['errors'] += 1 # log.msg('SNMP Engine error: %s' % error_indication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if error_status and error_status != 2 or error_indication: log.msg('Remote SNMP error %s' % (error_indication or error_status.prettyPrint())) if cb_ctx['retries']: try: next_oid = var_bind_table[-1][0][0] except IndexError: next_oid = cb_ctx['lastOID'] else: log.msg('Failed OID: %s' % next_oid) # fuzzy logic of walking a broken OID if len(next_oid) < 4: pass elif (self.snmp_parameters.retry_count - cb_ctx[ 'retries']) * 10 / self.snmp_parameters.retry_count > 5: next_oid = next_oid[:-2] + (next_oid[-2] + 1,) elif next_oid[-1]: next_oid = next_oid[:-1] + (next_oid[-1] + 1,) else: next_oid = next_oid[:-2] + (next_oid[-2] + 1, 0) cb_ctx['retries'] -= 1 cb_ctx['lastOID'] = next_oid log.msg('Retrying with OID %s (%s retries left)...' % (next_oid, cb_ctx['retries'])) # initiate another SNMP walk iteration if self._get_bulk_flag: self.send_bulk_var_binds(next_oid, cb_ctx) else: self.send_walk_var_binds(next_oid, cb_ctx) cb_ctx['errors'] += 1 return if self.snmp_parameters.retry_count != cb_ctx['retries']: cb_ctx['retries'] += 1 if var_bind_table and var_bind_table[-1] and var_bind_table[-1][0]: cb_ctx['lastOID'] = var_bind_table[-1][0][0] stop_flag = False time.sleep(0.2) # Walk var-binds for varBindRow in var_bind_table: for oid, value in varBindRow: # EOM _add_line = True if self._stop_oid and oid >= self._stop_oid: stop_flag = True _add_line = False if (value is None or value.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet)): stop_flag = True # remove value enumeration if value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) if value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) if value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) # Build .snmprec record context = { 'origOid': oid, 'origValue': value, 'count': cb_ctx['count'], 'total': cb_ctx['total'], 'iteration': cb_ctx['iteration'], 'reqTime': cb_ctx['reqTime'], 'startOID': self._oid, 'stop_flag': stop_flag, } try: line = "" if _add_line: line = self.data_file_handler.format(oid, value, **context).replace("|", ", ") except error.MoreDataNotification: cb_ctx['count'] = 0 cb_ctx['iteration'] += 1 more_data_notification = sys.exc_info()[1] if 'period' in more_data_notification: log.msg( '%s OIDs dumped, waiting %.2f sec(s)...' % ( cb_ctx['total'], more_data_notification['period'])) time.sleep(more_data_notification['period']) # initiate another SNMP walk iteration if self._get_bulk_flag: self.send_bulk_var_binds(self._oid, cb_ctx) else: self.send_walk_var_binds(self._oid, cb_ctx) stop_flag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.msg('ERROR: %s' % (sys.exc_info()[1],)) continue else: if _add_line and line and line not in self._output_list: self._output_list.append(line) cb_ctx['count'] += 1 cb_ctx['total'] += 1 if cb_ctx['count'] % 100 == 0: log.msg('OIDs dumped: %s/%s' % ( cb_ctx['iteration'], cb_ctx['count'])) # Next request time cb_ctx['reqTime'] = time.time() # Continue walking return not stop_flag
def set(self, name, value, instance=0, context=None, type='i'): ''' snmpojb.set('swDetailsVersion', 1, '05.00.96') ''' oid = '' if self.isDotNotation(name): oid = name # TODO do we try and guess what our value is if we are given dot notation #rfcValue=rfc1902.OctetString(value) # type can be: i INTEGER, u UNSIGNED, s STRING, x HEX STRING, d DECIMAL STRING # n NULLOBJ, o OBJID, t TIMETICKS, a IPADDRESS, b BITS assert (type in 'iusxdnotab' ), "ERROR: Value type {0} not supported".format(type) try: if type == 'i': rfcValue = rfc1902.Integer32(value) elif type == 'u': rfcValue = rfc1902.Unsigned32(value) elif type == 't': rfcValue = rfc1902.TimeTicks(value) elif type == 'a': rfcValue = rfc1902.IpAddress(value) elif type == 'b': rfcValue = rfc1902.Bits(value) elif type == 's': rfcValue = rfc1902.OctetString(value) elif type == 'o': rfcValue = univ.ObjectIdentifier(value) elif type in 'xdn': print 'WARNING: Type ' + type + ' not fully supported (hope default will do)' rfcValue = rfc1902.OctetString(value) else: print "unknown type" except: print("Error in SNMPClient, could not convert {} to type {}" ).format(value, type) else: oid = self.mibs[name].get('oid') # TODO: incode the type type = self.mibs[name].get('type') # TODO: do something similar as if a couple of lines up rfcValue = self.mibs.encode(type, value) #if instance!=0: oid += '.' + str(instance) if context == None: context = self.context if SNMPClient.DEBUG: print "Setting %s (%s) = %s" % (name, oid, str(value)) cmdGen = MyCmdGen() errorIndication, errorStatus, _, varBinds = cmdGen.setCmd( self.agent, context, self.host, self.port, (rfc1902.ObjectName(oid), rfcValue)) if SNMPClient.DEBUG: print 'agent', self.agent print 'context', context print 'host', self.host print 'port', self.port print 'type', type if errorIndication: raise IOError(errorIndication) if errorStatus: raise SNMPError('set on ' + oid + '(' + name + ')', errorStatus) return varBinds[-1][1].prettyPrint()