pysnmp是用python语言开发的snmp开源项目,感觉没有net-snmp强大。但如果你只开发snmp 客户端的 trap,那么用pysnmp还是很简单的。
1、安装
下载pysnmp和pyasn1源码python setup.py安装,比较简单。
2、pysnmp扩展trap
直接帖代码了:
简单标准MIB
# Notification Originator Application (TRAP)
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder
from pysnmp.proto import api
# Protocol version to use
verID = api.protoVersion1
pMod = api.protoModules[verID]
# Build PDU
trapPDU = pMod.TrapPDU()
pMod.apiTrapPDU.setDefaults(trapPDU)
# Traps have quite different semantics among proto versions
if verID == api.protoVersion1:
pMod.apiTrapPDU.setEnterprise(trapPDU, (1,3,6,1,6,3,1,1,5,1))
pMod.apiTrapPDU.setGenericTrap(trapPDU, 'coldStart')
# Build message
trapMsg = pMod.Message()
pMod.apiMessage.setDefaults(trapMsg)
pMod.apiMessage.setCommunity(trapMsg, 'public')
pMod.apiMessage.setPDU(trapMsg, trapPDU)
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerTransport(
udp.domainName, udp.UdpSocketTransport().openClientMode()
)
transportDispatcher.sendMessage(
encoder.encode(trapMsg), udp.domainName, ('10.8.80.108', 162)
)
transportDispatcher.runDispatcher()
transportDispatcher.closeDispatcher()
带参数的标准MIB
使用的是setVarBinds函数,注意函数的第二个参数,是一个list,每个list元素是一个字典变量。下边是一个很好的例子,开发时照猫画虎就OK了。
# Notification Originator Application (TRAP)
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder
from pysnmp.proto import api
# Protocol version to use
verID = api.protoVersion1
pMod = api.protoModules[verID]
# Build PDU
trapPDU = pMod.TrapPDU()
pMod.apiTrapPDU.setDefaults(trapPDU)
# Traps have quite different semantics among proto versions
if verID == api.protoVersion1:
pMod.apiTrapPDU.setEnterprise(trapPDU, (1,3,6,1,6,3,1,1,5,4))
pMod.apiTrapPDU.setGenericTrap(trapPDU, 'linkUp')
var = []
oid = (1,3,6,1,6,3,1,1,5,3,1)
val = pMod.Integer(1)
var.append((oid,val))
oid = (1,3,6,1,6,3,1,1,5,3,2)
val = pMod.Integer(2)
var.append((oid,val))
oid = (1,3,6,1,6,3,1,1,5,3,3)
val = pMod.Integer(3)
var.append((oid,val))
pMod.apiTrapPDU.setVarBinds(trapPDU, var)
# Build message
trapMsg = pMod.Message()
pMod.apiMessage.setDefaults(trapMsg)
pMod.apiMessage.setCommunity(trapMsg, 'public')
pMod.apiMessage.setPDU(trapMsg, trapPDU)
transportDispatcher = AsynsockDispatcher()
私有MIB
上面举的例子都是标准MIB中定义的。要扩展私有MIB会遇到什么问题呢?
问题在这句:pMod.apiTrapPDU.setGenericTrap(trapPDU, 'linkUp')
当setGenericTrap的第二个参数是一个标准MIB时,pysnmp是可以识别的,但是如果换成了私有MIB比如RamUsageThresExceed啥的,就会报错:
pyasn1.error.PyAsn1Error: Can't coerce RamUsageThresExceed into integer。
这需要修改pysnmp/proto下面的rfc1157.py,在里面定义class TrapPDU的地方
namedtype.NamedType('generic-trap', univ.Integer().clone(XXXXX)的那一行把你要定义的私有MIB加进来。
但是如果你发现pysnmp的版本不一样,找不到那一行,那你就把pysnmp和pyasn1目录建一个工程,在工程里面搜linkUp(注意大小写),看他们对linkUp做了什么,你就照猫画虎好了~~~
3、注意事项
几乎没有什么注意事项,勉强找一个的话那就是对标准的MIB属性,如ifIndex之类的,
在设置它的oid 的时候需要在后面加一个.0。比如:ifIndex的OID值是(1,3,6,1,2,1,2,2,1,1),但是在给他赋值的时候,要写成(1,3,6,1,2,1,2,2,1,1,0)