Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trap receiver throws exception #107

Open
aschamberger opened this issue Oct 7, 2022 · 1 comment · May be fixed by #111
Open

Trap receiver throws exception #107

aschamberger opened this issue Oct 7, 2022 · 1 comment · May be fixed by #111

Comments

@aschamberger
Copy link

Issue Description

I tried to implement a trap receiver and it raises the following exception:

Exception in callback _SelectorDatagramTransport._read_ready()
handle: <Handle _SelectorDatagramTransport._read_ready()>
Traceback (most recent call last):
  File "/usr/lib/python3.9/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/lib/python3.9/asyncio/selector_events.py", line 1029, in _read_ready
    self._protocol.datagram_received(data, addr)
  File "/usr/local/lib/python3.9/dist-packages/puresnmp/transport.py", line 80, in datagram_received
    self.callback(SocketResponse(data, SocketInfo(addr[0], addr[1])))
  File "/usr/local/lib/python3.9/dist-packages/puresnmp/api/raw.py", line 903, in decode
    mproc = mpm.create(obj[0].value, handler, lcd)
TypeError: 'Integer' object is not subscriptable

My code:

import asyncio
from puresnmp import V1, V2C
from puresnmp.api.raw import register_trap_callback

port = 162
credentials = V2C('public')

def callback(trap)
    print(trap)

loop = register_trap_callback(callback, port=port, credentials=credentials)

async def main():
    while True:
        await asyncio.sleep(3600)

loop.run_until_complete(main())

HexDump

This was referenced Mar 26, 2023
@ziesemer
Copy link

First, @aschamberger - in your code: Your callback needs to be async (and, it's missing a trailing colon). Fixing that block:

async def callback(trap):
	print(trap)

Then, there is an issue within the library here that also needs to be fixed.

Referencing:

def decode(packet: SocketResponse) -> None:
async def handler(data: bytes) -> bytes:
return await send_udp(
Endpoint(ip_address(packet.info.address), packet.info.port),
data,
)
lcd: Dict[str, Any] = {}
as_sequence = Sequence.decode(packet.data)
obj = cast(Tuple[Integer, Integer, Trap], as_sequence[0])
mproc = mpm.create(obj[0].value, handler, lcd)
trap = mproc.decode(packet.data, credentials)
asyncio.ensure_future(callback(trap))

I don't believe the cast type on line # 900 is correct, as as_sequence[0] actually comes back as Integer(1) - reflecting the received SNMP version, in this case, v2c. As such, obj becomes (only) that Integer - and the current code is then trying to subscript an Integer, which is not possible - but also, surely not the intended action.

I think the quickest and one of the more correct fixes here is to fix the cast on the same line to instead cast the entire sequence,

However, then as_sequence actually comes back as Sequence[Integer, OctetString, Trap] - where the middle value / OctetString is the received SNMP community name (not a 2nd Integer, as currently declared). I'm not concerned with the Sequence vs. Tuple here. Combined, this is all just for semantics to support type hints...

Combined, this should be a proper fix:

        obj = cast(Tuple[Integer, OctetString, Trap], as_sequence)

Finally - I'd have too many questions for @exhuma here - but to start with, I think it would be nice to make more information around the larger trap that was received to the callback. I.E., I'd like to still at least have a supportable option for getting back the SocketInfo (for knowledge of the IP address and port that the trap was sent from), the community, and even the SNMP version indicator for potential consideration and use within the callback.

ziesemer added a commit to ziesemer/puresnmp that referenced this issue Mar 26, 2023
@ziesemer ziesemer linked a pull request Mar 26, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants