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

implement send_trap() #22

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

atodorov-storpool
Copy link
Contributor

Hello,

I choose your library to implement snmp agent for our company project. It is working fine but there was need to implement functionality to send traps. I am beginner Python developer and it took some time to figure out your code flow and how to add sending trap functionality how to glue python ctypes to libnetsnmp. I do not use your code for defining ASN types because I found net-snmp function that is used in sendtrap tool for creating the needed varbind list for send_trap(). You can find some example scripts for using it. The traps that are received by snmptrapd ara passed to simple shell handler for logging to syslog - I do not found a way to log on console because the handler is started by snmptrapd.

I see in your TODO list that such functionality is planned and I hope the code will help to faster extend your library.

Best Regards,
Anton Todorov

ps. Please bump the pip package - I can confirm the recent commit in master about the string handling are working but pip is not updated.

extract from _prepareRegistration() to separate function _prepareOID()
which returns tuple of (c_oid) oid and (size_t) oid_len

The code is improved by trimming trailing zeroes from the oid array
depending on function arguments it is possible to send all types of traps

actually tested v1 and v2c traps, informs are received too

When sending traps with Counter64 there is warning issued by net-snmp:
send_trap: v1 traps can't carry Counter64 varbinds
send_trap: failed to convert v2->v1 template PDU

In this case snmptrapd receives the trap only on trap2sink and informsink interfaces
@pief
Copy link
Owner

pief commented Apr 16, 2015

Looks very interesting, I'll have to take a closer look this weekend :)

Once I close #20, I'll prepare a new 0.5.1 stable release.

@atodorov-storpool
Copy link
Contributor Author

I just spot small bug in the init of snmp_pdu class:

def __init__(self, pduType = SNMP_MSG_TRAP2):
"""create PDU object """
self.pdu = libnsX.snmp_pdu_create(SNMP_MSG_TRAP2)

I am not passing pduType variable to snmp_pdu_create() function usiing hardcoded value instead. It is not important because I use the PDU structure as temporary container where snmp_add_var() function is doing its magic to pdu.variables. Everything other is not used at all so it does not matter actually.

@wreszelewski
Copy link

Are there any issues blocking this pull request from being merged?

@pief
Copy link
Owner

pief commented Aug 29, 2016

Please note that this PR is still on my to-do list.

@sewashinobi
Copy link

@atodorov-storpool Can you please merge master in your branch?

are your commits stable.. can I use it?

@atodorov-storpool
Copy link
Contributor Author

@sewashinobi merged.

They are working for me, sure you can try using them :)

@pief
Copy link
Owner

pief commented Aug 9, 2017

@sewashinobi Does it work for you too, then?

@sewashinobi
Copy link

sewashinobi commented Sep 5, 2017

@pief @atodorov-storpool

Sorry for delayed response
yes it works, but I see following warning when Counter64 is used in traps

Warning : send_trap: failed to convert v2->v1 template PDU

Although there is some discussion about it in netsnmp mailing list,
https://sourceforge.net/p/net-snmp/mailman/message/27295298/

FYI.. I have configured snmpd for only v2c, and there is only one trap and that is configured as follows.. not sure then why this warning is coming..

trap2sink xxx.xxx.xxx.xxx <community>

Netsnmp Version ( Ubuntu)

snmpd --version

NET-SNMP version:  5.7.2
Web:               http://www.net-snmp.org/
Email:             [email protected]

@sewashinobi
Copy link

@atodorov-storpool I have trap running in production and looks good, but sometime there is race condition and same trap is getting send twice.. from the log I am sure that my agentx is calling it only once..

in my implementation, the trap function is running in separate thread and in the main thread I have called the check_and_process.. Once I bombard approx 20 traps then few traps are coming twice.. I looked in your code but couldn't find the issue.. Appreciate if you can spot something

@sewashinobi
Copy link

@atodorov-storpool digged a little more for duplicate trap issue, it is happening when the data update and trap both happen same time ( In production it is very much possible that get request and trap both happen at same time, correct me if this shouldn't be the case )

@sewashinobi
Copy link

@atodorov-storpool any suggestion, I tried to debug in your implementation but no luck. This happens when the data update and traps are happening in parallel.

@sewashinobi
Copy link

sewashinobi commented Sep 18, 2018

@atodorov-storpool you code doesn't work with Python 3, this part has problem. The c_char expects bytes, I tried to encode but then trap has corrupted data.

				ret = libnsX.snmp_add_var(
						self.pdu,
						ctypes.cast(ctypes.byref(varOid), c_oid_p),
						varOidLen.value,
						ctypes.c_char(varType),
						ctypes.c_char_p('{0}'.format(varData))
				)

I fixed following as has_key is not supported

			for entry in traps:
				if 'oid' in entry:
					varOid = entry['oid']
					if 'val' in entry:
						varData = entry['val']
						varType = None
						if 'type' in entry:
							varType = entry['type']
						pdu.add(varOid, varData, varType)
					else:
						msg = "missing 'val' key in trap list!"
						raise netsnmpAgentException(msg)

While not able to figure out the c_char solution, Will you be able to help?

@sewashinobi
Copy link

I was able to fix it with encode, earlier I was trying the ctypes.c_wchar, ctypes.c_wchar_p which was giving unexpected results.

ret = libnsX.snmp_add_var(
self.pdu,
ctypes.cast(ctypes.byref(varOid), c_oid_p),
varOidLen.value,
ctypes.c_char(varType.encode()),
ctypes.c_char_p('{0}'.format(varData).encode())
)

@j123b567
Copy link
Contributor

This no longer works, because in Net-SNMP v 5.8 and up, there is additional field msgMaxSize in the netsnmp_pdu data type which breaks binary compatibility.

@j123b567 j123b567 mentioned this pull request Sep 9, 2020
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 this pull request may close these issues.

5 participants