5

Hello I'm trying to listen for traps with this code from pysnmp doc:

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):
    print('cbFun is called')
    while wholeMsg:
    print('loop...')
        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
    print('run dispatcher')
    transportDispatcher.runDispatcher()
except:
    transportDispatcher.closeDispatcher()
    raise

But when I test it with this command:

$ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2
127.0.0.1 1 1 123 1.3.6.1.2.1.1.1.0 s test

Nothing is displayed. Could someone help me ? Everything I want is to display traps received by this receiver.

EDIT: I added some prints and this is what I get when I run the program:

C:\user\snmp\test>python fonction.py
rundispatcher
_

When I send a trap, nothing displays. When I press Ctrl+C I get:

C:\user\snmp\test>python fonction.py
rundispatcher
Traceback (most recent call last):
  File "fonction.py", line 73, in <module>
    transportDispatcher.runDispatcher()
  File "C:\user\snmp\test\pysnmp\carrier\asyncore\dispatch.py", line 37, in runDispatcher
    use_poll=True, map=self.__sockMap, count=1)
  File "C:\Python27\lib\asyncore.py", line 220, in loop
    poll_fun(timeout, map)
  File "C:\Python27\lib\asyncore.py", line 145, in poll
    r, w, e = select.select(r, w, e, timeout)
KeyboardInterrupt
Drakorcarnis
  • 51
  • 1
  • 1
  • 3
  • Did you try adding some test print to beginning of cbFun before the while to make sure it gets called at all? If so, try putting one right after the first while as well. – Bemmu Nov 17 '15 at 09:02
  • I tried and cbFun is never called – Drakorcarnis Nov 17 '15 at 09:48
  • Your script works on my Mac. Could it be a firewall issue? Make sure port 162/udp is allowed. You may want to enable pysnmp debugging to see if any traffic is coming in from the network. – Ilya Etingof Nov 17 '15 at 11:15
  • Thanks for your response. Port 162/udp was already open. Could you tell me exactly what steps you did to make it works ? I'm very new in Python/pysnmp – Drakorcarnis Nov 20 '15 at 08:32
  • Note that "print('loop...')" should be indented. – sqqqrly Sep 02 '20 at 12:54

1 Answers1

3

On Windows I found I had to change the listener address from 'localhost' to ''.

netstat -a then shows it bound as 0.0.0.0:162 instead of 127.0.0.0:162 and it works correctly:

C:\>netstat -a | find ":162"
  UDP    0.0.0.0:162            *:*
  • 1
    Agree on the listening port change it works for me too. But I also had problems in lines 51: `AttributeError: 'str' object has no attribute 'prettyPrint'` so I have to uncomment the **prettyPrint** invocation and it solved for me. My `pysnmp.__version__` is 4.4.2. – daparic Dec 08 '17 at 13:00