python 实现的 snmptrap 接收器
因为网上找到的代码总有一些问题,也取不到需要的数据,所以对代码进行了修改
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import decoder
from pysnmp.proto import api
from pysnmp.proto.rfc1905 import VarBind
import re
def pick(varbind):
pattern="name=(.*)[\s\S]*value=(.*)"
regx=re.compile(pattern)
matchs=regx.findall(varbind)
if matchs:
return matchs[0][0],matchs[0][1]
else:
return False
def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
while wholeMsg:
msgVer = int(api.decodeMessageVersion(wholeMsg))
if msgVer in api.protoModules:
pMod = api.protoModules[msgVer]
else:
print('Unsupported SNMP version %s' % msgVer)
return
reqMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message(),)
# print("reqmsg:", reqMsg)
# print("wholemsg:",wholeMsg)
print('Notification message from %s:%s: ' % (transportDomain, transportAddress))
reqPDU = pMod.apiMessage.getPDU(reqMsg)
# print("pdu:",reqPDU)
varBinds = pMod.apiPDU.getVarBindList(reqPDU)
# print("varbinds:",varBinds)
for row in varBinds:
row: VarBind
row=row.prettyPrint()
k,v=pick(row)
print("%s:%s" % (k,v))
return wholeMsg
if __name__ == '__main__':
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerRecvCbFun(cbFun)
# UDP/IPv4
transportDispatcher.registerTransport(
udp.domainName, udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162))
)
# UDP/IPv6
transportDispatcher.registerTransport(
udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
)
transportDispatcher.jobStarted(1)
try:
transportDispatcher.runDispatcher()
except:
transportDispatcher.closeDispatcher()
raise