Translating pysnmp oids to human readable strings

SpamMePlease PleasePlease spankthespam at googlemail.com
Thu Mar 5 23:30:55 CET 2009


On Thu, Mar 5, 2009 at 10:12 PM, birdsong <david.birdsong at gmail.com> wrote:
> On Mar 5, 1:05 pm, birdsong <david.birds... at gmail.com> wrote:
>> On Mar 5, 12:32 pm, SpamMePlease PleasePlease
>>
>>
>>
>> <spankthes... at googlemail.com> wrote:
>> > Hey list,
>>
>> > I was given a task, to reproduce functionality of command specified
>> > below by writing proper python functions to reuse in some monitoring
>> > script:
>>
>> > rivendell# snmpwalk -Os -mALL -v1 -cgabilgathol 10.0.6.66
>> > .1.3.6.1.4.1.2636.5.1.1.2
>> > jnxBgpM2PeerIdentifier.0.ipv4."".unknown."".0.1.38.101.87.145 =
>> > STRING: 66.250.1.253
>> > jnxBgpM2PeerIdentifier.0.ipv4.38.101.161.119.1.38.101.161.118 =
>> > STRING: 66.28.1.85
>> > jnxBgpM2PeerIdentifier.0.ipv4.64.200.59.74.1.64.200.59.73 = STRING: 64.200.68.12
>> > jnxBgpM2PeerIdentifier.0.ipv4.72.37.131.250.1.72.37.131.249 = STRING:
>> > 64.235.224.240
>> > jnxBgpM2PeerState.0.ipv4."".unknown."".0.1.38.101.87.145 = INTEGER:
>> > established(6)
>> > jnxBgpM2PeerState.0.ipv4.38.101.161.119.1.38.101.161.118 = INTEGER:
>> > established(6)
>> > jnxBgpM2PeerState.0.ipv4.64.200.59.74.1.64.200.59.73 = INTEGER: established(6)
>> > jnxBgpM2PeerState.0.ipv4.72.37.131.250.1.72.37.131.249 = INTEGER: established(6)
>> > (more output)
>>
>> > I have already found a pysnmp library to fetch the data from the
>> > device with a minimal amount of code:
>>
>> > from pysnmp.entity.rfc3413.oneliner import cmdgen
>> > from pysnmp.smi import *
>> > import string
>>
>> > cmdGen = cmdgen.CommandGenerator()
>> > errorIndication, errorStatus, errorIndex, varBinds =
>> > cmdgen.CommandGenerator().nextCmd(cmdgen.CommunityData('AmonMuil',
>> > 'gabilgathol', 0),
>> > cmdgen.UdpTransportTarget(('fw-1.datacenter.gondor.net', 161)),
>> > (1,3,6,1,4,1,2636,5,1,1,2))
>>
>> > print errorIndication, errorStatus
>> > for i in varBinds:
>> >     print i
>>
>> > The problem is that I have completely stuck on the result I am
>> > experiencing being totally human unreadable, like this:
>>
>> > rivendell# python snmp.py
>> > None 0
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.0.1.0.0.0.0.1.38.101.87.145'),
>> > OctetString('B\xfa\x01\xfd'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.0.1.38.101.161.119.1.38.101.161.118'),
>> > OctetString('B\x1c\x01U'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.0.1.64.200.59.74.1.64.200.59.73'),
>> > OctetString('@\xc8D\x0c'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.0.1.72.37.131.250.1.72.37.131.249'),
>> > OctetString('@\xeb\xe0\xf0'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2.0.1.0.0.0.0.1.38.101.87.145'),
>> > Integer32('6'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2.0.1.38.101.161.119.1.38.101.161.118'),
>> > Integer32('6'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2.0.1.64.200.59.74.1.64.200.59.73'),
>> > Integer32('6'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2.0.1.72.37.131.250.1.72.37.131.249'),
>> > Integer32('6'))]
>> > [(ObjectName('1.3.6.1.4.1.2636.5.1.1.2.1.1.1.3.0.1.0.0.0.0.1.38.101.87.145'),
>> > Integer32('2'))]
>>
>> > Since I cant find any way to translate these numbers to the same thing
>> > snmpwalk produce, is there any clue on how to achieve that? Is it
>> > possible at all for different devices (this one happend to be Juniper
>> > firewall if that does matter). Also, how can I know where does this
>> > magic oid ends and where does additional information starts (like ip
>> > addresses added to oid 0 they all looks like another oid string
>> > numbers) ?
>>
>> > Any sample of code, or hint to another lib will be very appreciated!
>>
>> > --
>> > --------------------
>> > Spank The Spam!
>>
>> Here's an example of walk that's part of a class I wrote, hopefully
>> indentation survives the paste.  I borrowed heavily from example code
>> on the pysnmp site.
>>
>> from pysnmp import asn1, v2c
>> from pysnmp import role
>>
>>   def walk(self, community_string, base_oids):
>>
>>     if type(base_oids) is str: base_oids = [base_oids]
>>     # this this does what it says, dont bother asking for oids that
>> we'll see in our walk
>>     base_oids = self.remove_child_oids(base_oids)
>>     # h_pair is just (host, port)
>>     client = role.manager(self.h_pair)
>>     client.timeout = 10
>>     req = v2c.GETNEXTREQUEST(community=community_string)
>>     rsp = v2c.GETRESPONSE()
>>     req['encoded_oids'] = map(asn1.OBJECTID().encode, base_oids)
>>
>>     oids_values = {}
>>     while req['encoded_oids']:
>>       try:
>>         answer, host_tuple = client.send_and_receive(req.encode())
>>       except (role.NoResponse, role.NetworkError):
>>         return oids_values
>>
>>       rsp.decode(answer)
>>
>>       parsed_oids_vals = self.parse_response(rsp, base_oids)
>>       oids_values.update(parsed_oids_vals)
>>
>>       req['request_id'] += 1
>>       req['encoded_oids'] = map(asn1.OBJECTID().encode,
>> parsed_oids_vals.keys())
>>
>>     return oids_values
>
> Just realized the parse_response() is needed to makes sense of it:
>
> def parse_response(self, rsp, head_oids):
>    # list of indices
>    overshot_oids = []
>
>    vals = map(lambda x: x[0](), map(asn1.decode, rsp
> ['encoded_vals']))
>    oids = map(lambda x: asn1.OBJECTID().decode(x)[0], rsp
> ['encoded_oids'])
>    oids_vals = dict(map(None, oids, vals))
>
>    for oid in oids_vals:
>      if not filter(lambda h: asn1.OBJECTID(h).isaprefix(oid),
> head_oids):
>        overshot_oids.append(oid)
>
>    map(lambda x: oids_vals.pop(x), overshot_oids)
>
>    return oids_vals
>
>
> I welcome critique btw, I'm here to learn.
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Sorry, but I dont understand the code at all. Where does it takes the
names for the oid numbers? Why the translation needs a 'walk' at all?
Isnt that possible to perform an acion on given oid (my code produces
a list of them) to translate it to human readable output like snmpwalk
binary does?

-- 
--------------------
Spank The Spam!



More information about the Python-list mailing list