Re: [pysnmp-users] pysnmp / pyasn1 decode problem with multi-line traps
Brought to you by:
elie
From: Ilya E. <il...@gl...> - 2015-03-16 10:33:21
|
Hi Tom, You can check it like this: from pyasn1.type.univ import OctetString if isinstance(val, OctetString): val = str(val) ... The str() part is important because you are getting pyasn1 objects in response while "re" expects strings. -ilya On 03/16/2015 01:15 PM, Tom Kr. wrote: > Some good news to the beginning of the new week. > After I changed the method from .getVarBindsList() to .getVarBinds(), I can read the data with the stupid line feed. > > Now I tried to search and replace the line feed with this lines > for oid, val in varBinds: > print("DEBUG_oid: %s" % oid) > print("DEUBG_val: %s" % val) > new_val = "".join(val) > val = re.sub(r"[\r|\s]", "", new_val) > print("DEBUG_oid_2: %s" % oid) > print("DEBUG_val_2: %s" % val) > > Each time there is a trap with this characters I get this error message. > return _compile(pattern, flags).sub(repl, string, count) > ;TypeError: expected string or buffer > > How can I find out which type the val variable have? > And how can I change this to string? > > Tom > > > >> Am 12.03.2015 um 16:18 schrieb Ilya Etingof <il...@gl...>: >> >> >> Right, in 'val' you are getting the whole SNMP PDU value structure, not just a leaf scalar. That's the reason it does not match OctetString class instance check. >> >> Use .getVarBinds() method instead of .getVarBindsList(). The former returns a list of tuples of terminal values, while the latter returns original var-bindings list from SNMP PDU which always holds a record-like structure for value. >> >> -ilya >> >>> On 03/12/2015 05:29 PM, Tom Kr. wrote: >>> Hmm, I'm confused. >>> With this changes I also get hex values back and I still enter the else part for each value. >>> import sys,os >>> sys.path.append('/usr/share/pyshared/') >>> 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 >>> #from pysnmp.proto.rfc1902 import OctetString >>> from pyasn1.type.univ import OctetString >>> def pySnmpCheck(oval): >>> if isinstance(oval, OctetString): >>> print("DEBUG: OctetString") >>> val = oval.asOctets() >>> else: >>> print("DEBUG: else") >>> val = oval >>> return val >>> If this information are useful, this is the header I've got. >>> # python snmp-transports.py >>> Notification message from (1, 3, 6, 1, 6, 1, 1):('xxx.xxx.xxx.xxx', 52032): >>> Enterprise: 1.3.6.1.4.1.18494.2 >>> Agent Address: xxx.xxx.xxx.xxx >>> Generic Trap: 'enterpriseSpecific' >>> Specific Trap: 1 >>> Uptime: 1 >>> Var-binds: >>> DEBUG: else >>> 1.3.6.1.4.1.18494.2.1.9 = ObjectSyntax: >>> simple=SimpleSyntax: >>> string=0x4f70657261746f722058585858585858585858203a20585858585858585858582c2058585858585858202c204c6f63616c6c792061757468656e74696361746564202d207375636365737366756c6c79207369676e6564206f6e20746f20746865207465726d696e616c20275858582e5858582e582e584058272061742031343a3238207573696e672027585858585858585820585858205858585858585858272e0a4f70657261746f722050726f66696c65733a2058585858585858585858585858 >>> Tom >>> >>> >>> >>>> Am 12.03.2015 um 14:39 schrieb Ilya Etingof <il...@gl...>: >>>> >>>> >>>> Oh, if you are using SNMPv1 you should check against the base class: >>>> >>>> from pyasn1.type.univ import OctetString >>>> >>>> if isinstance(oval, OctetString): >>>> ... >>>> >>>> Perhaps this should be improved in pysnmp. >>>> >>>> -ilya >>>> >>>>> On 03/12/2015 04:29 PM, Tom Kr. wrote: >>>>> I made the following changes to the script. >>>>> ... >>>>> from pysnmp.proto.rfc1902 import OctetString >>>>> def pySnmpCheck(oval): >>>>> if isinstance(oval, OctetString): >>>>> print("DEBUG: OctetString") >>>>> val = oval.asOctets() >>>>> else: >>>>> print("DEBUG: else") >>>>> val = oval >>>>> return val >>>>> ... >>>>> for oid, val in varBinds: >>>>> val = pySnmpCheck(val) >>>>> print('%s = %s' % (oid.prettyPrint(), val.prettyPrint())) >>>>> ... >>>>> Then I start grabbing the snmp messages again. >>>>> Unfortunately every value of the message go through the else part. >>>>> But how could this happen? >>>>> Is there a possibility to check which type of string the values have? >>>>> Tom >>>>> >>>>> >>>>> >>>>>> Am 11.03.2015 um 14:17 schrieb Ilya Etingof <il...@gl...>: >>>>>> >>>>>> >>>>>> That's right, .asOctets() is only defined for OctetString type and its >>>>>> subclasses. Therefore, to deal with octets of OctetString() you should >>>>>> do additional check: >>>>>> >>>>>> from pysnmp.proto.rfc1902 import OctetString >>>>>> >>>>>> ... >>>>>> >>>>>> if isinstance(val, OctetString): >>>>>> val = val.asOctets() >>>>>> >>>>>> Keep in mind that octet string is not always the same as printable >>>>>> string. The former is not immune to your terminal potentially eating >>>>>> non-printable characters or garbling output in a funny way. Also, text >>>>>> encoding is not defined by OctetString. To be on a safe side default >>>>>> OctetString printout is done in hex whenever a non-printable is seen in >>>>>> its contents. >>>>>> >>>>>> -ilya >>>>>> >>>>>>>> On 03/11/2015 03:18 PM, Craig Small wrote: >>>>>>>> On Wed, Mar 11, 2015 at 07:02:44AM +0100, Tom wrote: >>>>>>>> ;AttributeError: ObjectSyntax instance has no attribute 'asOctets' >>>>>>> Are you sure each row is returning something asOctets makes sense for? >>>>>>> An Integer doesn't make sense. >>>>>>> >>>>>>>> Does it only works if a hex value is send by snmp? >>>>>>> I believe it works for certain types of values, such as an OctetString >>>>>>> >>>>>>>> How can I check if the value is hex or not? >>>>>>> Not sure, but the types are found in pyasn1.type.univ so you could >>>>>>> compare it to, say, univ.OctetString >>>>>>> >>>>>>> ObjectSyntax seems to be the superset of all types, from what I can tell >>>>>>> it means pysnmp wasn't sure what the type should be. >>>>>>> >>>>>>> It's been an interesting and educational discussion anyhow. >>>>>>> >>>>>>> - Craig |