I'm trying to write a script that sends a trap when a syslog message is received. When i use a short literal string it works well, but when the string gets bigger or I use a string variable as the value of and OID, the trap is sent with the value converted to hex.
Here is a sample of my code.
from pysnmp import debug
from pysnmp.entity import engine, config
from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.entity.rfc3413 import ntforg
from pysnmp.proto.api import v2c
src_host = "192.168.1.100"
dst_host = "192.168.1.101"
dst_port = 162
syslog_msg = ("Dec 13 21:19:10 amt-srv-co7 This is a sylog test message")
snmp_engine = engine.SnmpEngine()
config.addV1System(snmp_engine, "my-area", "public", transportTag="all-my-managers")
config.addTargetParams(snmp_engine, "my-creds", "my-area", "noAuthNoPriv", 1)
config.addTransport(snmp_engine, udp.domainName, udp.UdpSocketTransport().openClientMode())
config.addTargetAddr(snmp_engine, "my-nms", udp.domainName, (dst_host, dst_port), "my-creds", tagList="all-my-managers", sourceAddress=(src_host, 0))
config.addNotificationTarget(snmp_engine, "my-notification", "my-filter", "all-my-managers", "trap")
config.addContext(snmp_engine, "")
config.addVacmUser(snmp_engine, 2, "my-area", "noAuthNoPriv", (), (), (1,3,6))
ntf_org = ntforg.NotificationOriginator()
ostr = v2c.OctetString(syslog_msg) #THE PROBLEM IS HERE!
# ostr = v2c.OctetString("Short message is OK")
# ostr = v2c.OctetString("A long message, not much longer than is converted to a hex string.")
varBinds = [((1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0), v2c.ObjectIdentifier((1, 3, 6, 1, 2, 1, 192, 0, 1))), ((1, 3, 6, 1, 2, 1, 192, 1, 2, 1, 11), ostr)]
send_request_handle = ntf_org.sendVarBinds(snmp_engine, "my-notification", None, "", varBinds, cb_fun)
snmp_engine.transportDispatcher.runDispatcher()
I tried changing de OID to something that would represent a string, but I get the same issue.
I believe that the issue happen when ntf_org.sendVarBinds is called... but maybe there is jist something I'm doing wrong.
Also if I just run a snmptrap from the CL I get the text in string format.
snmptrap -v 2c -c public 192.168.1.101 '1.3.6.1.6.3.1.1.4.1.0' '1.3.6.1.2.1.192.0.1' '1.3.6.1.2.1.192.1.2.11' s 'Dec 13 21:19:10 amt-srv-co7 This is a sylog test message'
But I get different Trap Types. For the script I get a Trap Type of 1.3.6.1.2.1.192.1.2.1.6.11 For the snmptrap command I get 1.3.6.1.2.1.6.192
This is what I get when I use a literal string inside the script
Unknown alert received from device amt-srv-co7 of type Host_Device. Device Time 0+00:00:00. (Trap type 1.3.6.1.2.1.192.1.2.1.6.11)
Trap var bind data: OID: 1.3.6.1.2.1.1.3.0 Value: 0 OID: 1.3.6.1.6.3.1.1.4.1.0 Value: 1.3.6.1.2.1.192.1.2.1.11 OID: 1.3.6.1.2.1.192.1.2.1.11 Value: Dec 13 21:19:10 amt-srv-co7 This is a syslog test message
And this is when I pass the string as a variable:
Unknown alert received from device amt-srv-co7 of type Host_Device. Device Time 0+00:00:00. (Trap type 1.3.6.1.2.1.192.1.2.1.6.11)
Trap var bind data: OID: 1.3.6.1.2.1.1.3.0 Value: 0 OID: 1.3.6.1.6.3.1.1.4.1.0 Value: 1.3.6.1.2.1.192.1.2.1.11 OID: 1.3.6.1.2.1.192.1.2.1.11 Value: 44.65.63.20.31.33.20.32.31.3A.31.39.3A.31.30.20.61.6D.74.2D.73.72.76.2D.63.6F.37.20.54.68.69.
Also the debug from pysnmp for the literal string includes:
2019-12-17 10:14:59,600 pysnmp: sendVarBinds: final varBinds [(<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.1.3.0]>, <SysUpTime value object, tagSet <TagSet object, tags 64:0:3>, subtypeSpec <ConstraintsIntersection object, consts <ValueRangeConstraint object, consts 0, 4294967295>>, payload [0]>), (<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.6.3.1.1.4.1.0]>, <ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.192.1.2.1.11]>), (<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.192.1.2.1.11]>, <OctetString value object, tagSet <TagSet object, tags 0:0:4>, subtypeSpec <ConstraintsIntersection object, consts <ValueSizeConstraint object, consts 0, 65535>>, encoding iso-8859-1, payload [Dec 13 21:19:10 ...log test message]>)]
Also the debug from pysnmp for the variable includes:
2019-12-17 10:15:42,987 pysnmp: sendVarBinds: final varBinds [(<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.1.3.0]>, <SysUpTime value object, tagSet <TagSet object, tags 64:0:3>, subtypeSpec <ConstraintsIntersection object, consts <ValueRangeConstraint object, consts 0, 4294967295>>, payload [0]>), (<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.6.3.1.1.4.1.0]>, <ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.192.1.2.1.11]>), (<ObjectIdentifier value object, tagSet <TagSet object, tags 0:0:6>, payload [1.3.6.1.2.1.192.1.2.1.11]>, <OctetString value object, tagSet <TagSet object, tags 0:0:4>, subtypeSpec <ConstraintsIntersection object, consts <ValueSizeConstraint object, consts 0, 65535>>, encoding iso-8859-1, payload [0x44656320313320...6d6573736167650a]>)]
Can you guys give me a tip?
Thanks!
How do you know the string is getting hexified?
The thing is, that pyasn1's OctetString
object would print out hexified if the payload is not all-ascii. It does not depend on the length, solely on the printability of the contents.
However, the above mentioned behavior is only about object printout, the payload itself is never changed. Having said that, I am wondering if you are actually getting corrupted data on the receiving end?
You can get consistent bytes
(on Py3) by calling .asOctets()
on OctetString
object.