我想模拟一个SNMP设备,我没有设备的MIB文件。 我只需要模拟一个函数,一个可写的OctectString值。
这是我的代码:
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
import time, bisect
from pysnmp import debug
debug.setLogger(debug.Debug('all'))
class SysDescr:
name = (1, 3, 6, 1, 2, 1, 1, 1, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'PySNMP responder'
)
class Domabox:
name = (1, 3, 6, 1, 2, 1, 1, 2, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'Domabox responder'
)
class Uptime:
name = (1, 3, 6, 1, 2, 1, 1, 3, 0)
birthday = time.time()
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].TimeTicks(
(time.time()-self.birthday)*100
)
class Remote:
name = (1, 3, 6, 1, 2, 1, 1, 4, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'Remote'
)
mibInstr = (
SysDescr(), Domabox(), Uptime(), Remote(), # sorted by object name
)
mibInstrIdx = {}
for mibVar in mibInstr:
mibInstrIdx[mibVar.name] = mibVar
def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
while wholeMsg:
msgVer = api.decodeMessageVersion(wholeMsg)
pMod = api.protoModules[api.protoVersion1]
reqMsg, wholeMsg = decoder.decode(
wholeMsg, asn1Spec=pMod.Message(),
)
rspMsg = pMod.apiMessage.getResponse(reqMsg)
rspPDU = pMod.apiMessage.getPDU(rspMsg)
reqPDU = pMod.apiMessage.getPDU(reqMsg)
print "reqPDU", reqPDU
varBinds = []; pendingErrors = []
errorIndex = 0
# GETNEXT PDU
if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
# Produce response var-binds
for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
errorIndex = errorIndex + 1
# Search next OID to report
nextIdx = bisect.bisect(mibInstr, oid)
if nextIdx == len(mibInstr):
# Out of MIB
varBinds.append((oid, val))
pendingErrors.append(
(pMod.apiPDU.setEndOfMibError, errorIndex)
)
else:
# Report value if OID is found
varBinds.append(
(mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer))
)
elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
if oid in mibInstrIdx:
varBinds.append((oid, mibInstrIdx[oid](msgVer)))
else:
# No such instance
varBinds.append((oid, val))
pendingErrors.append(
(pMod.apiPDU.setNoSuchInstanceError, errorIndex)
)
break
elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):
print "request ?"
else:
print "unsupported..."
# Report unsupported request type
pMod.apiPDU.setErrorStatus(rspPDU, 'genErr')
pMod.apiPDU.setVarBinds(rspPDU, varBinds)
# Commit possible error indices to response PDU
for f, i in pendingErrors:
f(rspPDU, i)
transportDispatcher.sendMessage(
encoder.encode(rspMsg), transportDomain, transportAddress
)
return wholeMsg
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerRecvCbFun(cbFun)
# UDP/IPv4
transportDispatcher.registerTransport(
udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161))
)
# UDP/IPv6
transportDispatcher.registerTransport(
udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161))
)
transportDispatcher.jobStarted(1)
try:
# Dispatcher will never finish as job#1 never reaches zero
transportDispatcher.runDispatcher()
except:
transportDispatcher.closeDispatcher()
raise
当我发送snmp写入值时,我得到了
;AttributeError: 'module' object has no attribute 'setRequestPDU'
来自
行elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):
var reqPDU内容:
reqPDU SetRequestPDU().setComponentByPosition(0, Integer(1639861451)).setComponentByPosition(1, Integer('noError')).setComponentByPosition(2, Integer(0)).setComponentByPosition(3, VarBindList().setComponentByPosition(0, VarBind().setComponentByPosition(0, ObjectName(1.3.6.1.2.1.1.4.0)).setComponentByPosition(1, ObjectSyntax().setComponentByPosition(0, SimpleSyntax().setComponentByPosition(1, OctetString('57'))))))
感谢。
答案 0 :(得分:1)
你的代码中可能意味着pMod.SetRequestPDU()(注意资本'S')。
但是,我建议不要编写自己的模拟器,而是考虑使用通用SNMP simulator来配置模拟完整的支持SNMP的设备。