2017-04-11 119 views
0

我使用本實施例中(從here取)以接收SNMP陷阱與pysnmpValueConstraintError在pysnmp陷阱接收

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 

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('Notification message from %s:%s: ' % (
      transportDomain, transportAddress 
      ) 
     ) 
     reqPDU = pMod.apiMessage.getPDU(reqMsg) 
     if reqPDU.isSameTypeWith(pMod.TrapPDU()): 
      if msgVer == api.protoVersion1: 
       print('Enterprise: %s' % (
        pMod.apiTrapPDU.getEnterprise(reqPDU).prettyPrint() 
        ) 
       ) 
       print('Agent Address: %s' % (
        pMod.apiTrapPDU.getAgentAddr(reqPDU).prettyPrint() 
        ) 
       ) 
       print('Generic Trap: %s' % (
        pMod.apiTrapPDU.getGenericTrap(reqPDU).prettyPrint() 
        ) 
       ) 
       print('Specific Trap: %s' % (
        pMod.apiTrapPDU.getSpecificTrap(reqPDU).prettyPrint() 
        ) 
       ) 
       print('Uptime: %s' % (
        pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint() 
        ) 
       ) 
       varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU) 
      else: 
       varBinds = pMod.apiPDU.getVarBindList(reqPDU) 
      print('Var-binds:') 
      for oid, val in varBinds: 
       print('%s = %s' % (oid.prettyPrint(), val.prettyPrint())) 
    return wholeMsg 

transportDispatcher = AsynsockDispatcher() 

transportDispatcher.registerRecvCbFun(cbFun) 

# UDP/IPv4 
transportDispatcher.registerTransport(
    udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 162)) 
) 

# UDP/IPv6 
transportDispatcher.registerTransport(
    udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162)) 
) 

transportDispatcher.jobStarted(1) 

try: 
    # Dispatcher will never finish as job#1 never reaches zero 
    transportDispatcher.runDispatcher() 
except: 
    transportDispatcher.closeDispatcher() 
    raise 

而對於一些陷阱有以下範圍的約束錯誤:

ValueConstraintError: ConstraintsIntersection(ConstraintsIntersection(), ValueRangeConstraint(0, 4294967295L)) failed at: "ValueRangeConstraint(0, 4294967295L) failed at: "-8249051"" at TimeTicks 

有辦法處理它嗎?

回答

1

我在寫這個問題時找到了答案 - 類似的情況在FAQ中描述。它似乎是供應商編碼中的一個錯誤。存在用於Counter類型給定的一個解決方案,轉換負值陽性:

from pysnmp.proto import rfc1155, rfc1902, api 
from pyasn1.codec.ber import encoder, decoder 

# --- hack Counter type 

def counterCloneHack(self, *args): 
    if args and args[0] < 0: 
     args = (0xffffffff+args[0]-1,) + args[1:] 

    return self.__class__(*args) 

rfc1155.Counter.clone = counterCloneHack 
rfc1902.Counter32.clone = counterCloneHack 

本hack可以應用於TimeTicks,以及:

rfc1155.TimeTicks.clone = counterCloneHack