Bassosimons
Bassosimons

Reputation: 11

Conversion of pysnmp OctetString to hex in python3

I have written python code that sends snmp get to a device using pysnmp then convert the output to an hex string. The code works successfully in python 2.7 but it does not in Python3.7

In both python2.7 and python3.7 the snmp get returns an pysnmp.proto.rfc1902.OctetString which is then converted to hex using binascii.hexlify.

In python2.7 the conversion is done by passing the str(OctateString_var) to the the hexlify function.

In python3.7 I use str(OctateString_var).encode() since the hexlify function requires byte string in python3.

I have noticed the results of the produced hex are different with the one from python3.7 having extra bytes and producing wrong values in the end

import binascii
from pysnmp.entity.rfc3413.oneliner import cmdgen

cmdGen = cmdgen.CommandGenerator()
ip = '10.1.1.1'
oid = '1.3.6.1.2.1.138.1.6.3.1.3'
comm = 'ro'

errIndicator, errStatus, errIndex, var = cmdGen.nextCmd(cmdgen.CommunityData(comm),
                                              cmdgen.UdpTransportTarget((ip, 161)),
                                                                             oid)

for varRow in var:
    for oid, ip in varRow:
        print('ID: ',ip, type(ip))

        try:
        # below is for python3.7
           hex_string = binascii.hexlify(str(ip).encode())
           hex_string = hex_string.decode()

        except:
        # below is for python2.7
           hex_string = binascii.hexlify(str(ip))

        print('HEX: ',hex_string)

When run on python2.7 I get below results:

('ID: ', <OctetString value object at 0x10506e80 subtypeSpec <ConstraintsIntersection object at 0xe4e0080 consts <ValueSizeConstraint object at 0xe4e0048 consts 0, 65535>> tagSet <TagSet object at 0xe4a9630 tags 0:0:4> encoding iso-8859-1 payload [0x9b0c0065]>, <class 'pysnmp.proto.rfc1902.OctetString'>)
('HEX: ', '9b0c0065')

When run on python3.7 I get below results:

ID: <0x9b><0x0c><0x00>e <class 'pysnmp.proto.rfc1902.OctetString'>
HEX:  c29b0c0065

Upvotes: 0

Views: 3647

Answers (2)

Bassosimons
Bassosimons

Reputation: 11

The quick fix I established is to convert each octate(byte) of the ocatestring to a string and put them together in a list as ip = [str(octate) for octate in ip] which will produce a list of numerical characters representing the decimal numbers which can then be converted to hex individually

Code

for varRow in var:
    for oid, ip in varRow:
         decimal_ip_octates = [str(octate) for octate in ip]

Upvotes: 1

Ilya Etingof
Ilya Etingof

Reputation: 5555

Perhaps you should better use version-neutral .asNumbers():

>>> from pyasn1.type.univ import OctetString
>>> OctetString(hexValue='01020304')
<OctetString value object, tagSet <TagSet object, tags 0:0:4>, encoding iso-8859-1, payload [0x01020304]>
>>> OctetString(hexValue='01020304').asNumbers()
(1, 2, 3, 4)
>>> ''.join('%.2x' % x for x in OctetString(hexValue='01020304').asNumbers())
'01020304'

Upvotes: 1

Related Questions