easysnmp


In [1]:
import easysnmp

In [15]:
session = easysnmp.Session(hostname='localhost', community='public', version=2, 
                           timeout=1, retries=1, use_sprint_value=True)
# IMPORTANT: use_sprint_value=True for proper formatting of values

In [16]:
location = session.get('sysLocation.0')
location.oid, location.oid_index, location.snmp_type, location.value


Out[16]:
('sysLocation', '0', 'OCTETSTR', 'Unknown (edit /etc/snmp/snmpd.conf)')

In [17]:
iftable = session.walk('IF-MIB::ifTable')

In [18]:
for item in iftable:
    print(item.oid, item.oid_index, item.snmp_type, item.value, type(item.value))


ifIndex 1 INTEGER 1 <class 'str'>
ifIndex 2 INTEGER 2 <class 'str'>
ifIndex 3 INTEGER 3 <class 'str'>
ifIndex 8 INTEGER 8 <class 'str'>
ifDescr 1 OCTETSTR lo <class 'str'>
ifDescr 2 OCTETSTR enp4s0 <class 'str'>
ifDescr 3 OCTETSTR cni-podman0 <class 'str'>
ifDescr 8 OCTETSTR vethfbbb3749 <class 'str'>
ifType 1 INTEGER softwareLoopback <class 'str'>
ifType 2 INTEGER ethernetCsmacd <class 'str'>
ifType 3 INTEGER ethernetCsmacd <class 'str'>
ifType 8 INTEGER ethernetCsmacd <class 'str'>
ifMtu 1 INTEGER 65536 <class 'str'>
ifMtu 2 INTEGER 1500 <class 'str'>
ifMtu 3 INTEGER 1500 <class 'str'>
ifMtu 8 INTEGER 1500 <class 'str'>
ifSpeed 1 GAUGE 10000000 <class 'str'>
ifSpeed 2 GAUGE 100000000 <class 'str'>
ifSpeed 3 GAUGE 0 <class 'str'>
ifSpeed 8 GAUGE 4294967295 <class 'str'>
ifPhysAddress 1 OCTETSTR  <class 'str'>
ifPhysAddress 2 OCTETSTR 1c:6f:65:8d:9a:d2 <class 'str'>
ifPhysAddress 3 OCTETSTR 36:37:96:62:8a:93 <class 'str'>
ifPhysAddress 8 OCTETSTR 46:fc:ac:66:d8:39 <class 'str'>
ifAdminStatus 1 INTEGER up <class 'str'>
ifAdminStatus 2 INTEGER up <class 'str'>
ifAdminStatus 3 INTEGER up <class 'str'>
ifAdminStatus 8 INTEGER up <class 'str'>
ifOperStatus 1 INTEGER up <class 'str'>
ifOperStatus 2 INTEGER up <class 'str'>
ifOperStatus 3 INTEGER up <class 'str'>
ifOperStatus 8 INTEGER up <class 'str'>
ifLastChange 1 TICKS 0:0:00:00.00 <class 'str'>
ifLastChange 2 TICKS 0:0:00:00.00 <class 'str'>
ifLastChange 3 TICKS 0:0:00:00.00 <class 'str'>
ifLastChange 8 TICKS 0:0:00:00.00 <class 'str'>
ifInOctets 1 COUNTER 78141774 <class 'str'>
ifInOctets 2 COUNTER 3350064535 <class 'str'>
ifInOctets 3 COUNTER 904712 <class 'str'>
ifInOctets 8 COUNTER 22662 <class 'str'>
ifInUcastPkts 1 COUNTER 51254 <class 'str'>
ifInUcastPkts 2 COUNTER 38954332 <class 'str'>
ifInUcastPkts 3 COUNTER 16845 <class 'str'>
ifInUcastPkts 8 COUNTER 324 <class 'str'>
ifInNUcastPkts 1 COUNTER 0 <class 'str'>
ifInNUcastPkts 2 COUNTER 650379 <class 'str'>
ifInNUcastPkts 3 COUNTER 0 <class 'str'>
ifInNUcastPkts 8 COUNTER 0 <class 'str'>
ifInDiscards 1 COUNTER 0 <class 'str'>
ifInDiscards 2 COUNTER 39648 <class 'str'>
ifInDiscards 3 COUNTER 0 <class 'str'>
ifInDiscards 8 COUNTER 0 <class 'str'>
ifInErrors 1 COUNTER 0 <class 'str'>
ifInErrors 2 COUNTER 0 <class 'str'>
ifInErrors 3 COUNTER 0 <class 'str'>
ifInErrors 8 COUNTER 0 <class 'str'>
ifInUnknownProtos 1 COUNTER 0 <class 'str'>
ifInUnknownProtos 2 COUNTER 0 <class 'str'>
ifInUnknownProtos 3 COUNTER 0 <class 'str'>
ifInUnknownProtos 8 COUNTER 0 <class 'str'>
ifOutOctets 1 COUNTER 78141774 <class 'str'>
ifOutOctets 2 COUNTER 2580625409 <class 'str'>
ifOutOctets 3 COUNTER 17102823 <class 'str'>
ifOutOctets 8 COUNTER 116468 <class 'str'>
ifOutUcastPkts 1 COUNTER 51254 <class 'str'>
ifOutUcastPkts 2 COUNTER 35430735 <class 'str'>
ifOutUcastPkts 3 COUNTER 22390 <class 'str'>
ifOutUcastPkts 8 COUNTER 1615 <class 'str'>
ifOutNUcastPkts 1 COUNTER 0 <class 'str'>
ifOutNUcastPkts 2 COUNTER 0 <class 'str'>
ifOutNUcastPkts 3 COUNTER 0 <class 'str'>
ifOutNUcastPkts 8 COUNTER 0 <class 'str'>
ifOutDiscards 1 COUNTER 0 <class 'str'>
ifOutDiscards 2 COUNTER 0 <class 'str'>
ifOutDiscards 3 COUNTER 0 <class 'str'>
ifOutDiscards 8 COUNTER 0 <class 'str'>
ifOutErrors 1 COUNTER 0 <class 'str'>
ifOutErrors 2 COUNTER 0 <class 'str'>
ifOutErrors 3 COUNTER 0 <class 'str'>
ifOutErrors 8 COUNTER 0 <class 'str'>
ifOutQLen 1 GAUGE 0 <class 'str'>
ifOutQLen 2 GAUGE 0 <class 'str'>
ifOutQLen 3 GAUGE 0 <class 'str'>
ifOutQLen 8 GAUGE 0 <class 'str'>
ifSpecific 1 OBJECTID zeroDotZero <class 'str'>
ifSpecific 2 OBJECTID zeroDotZero <class 'str'>
ifSpecific 3 OBJECTID zeroDotZero <class 'str'>
ifSpecific 8 OBJECTID zeroDotZero <class 'str'>

The type of .value is always a Python string but the string returned in .snmp_type can be used to convert to the correct Python type.

  • INTEGER32
  • INTEGER
  • UNSIGNED32
  • GAUGE
  • IPADDR
  • OCTETSTR
  • TICKS
  • OPAQUE
  • OBJECTID
  • NETADDR
  • COUNTER64
  • NULL
  • BITS
  • UINTEGER

In [19]:
macaddress = session.get('IF-MIB::ifPhysAddress.2')
macaddress


Out[19]:
<SNMPVariable value='1c:6f:65:8d:9a:d2' (oid='ifPhysAddress', oid_index='2', snmp_type='OCTETSTR')>

In [20]:
ifindex = session.get('IF-MIB::ifIndex.2')
ifindex


Out[20]:
<SNMPVariable value='2' (oid='ifIndex', oid_index='2', snmp_type='INTEGER')>

easysnmptable


In [22]:
import easysnmptable

In [23]:
session = easysnmptable.Session(hostname='localhost', community='public', version=2,
                               timeout=1, retries=1, use_sprint_value=True)
# IMPORTANT: use_sprint_value=True for proper formatting of values)

In [24]:
iftable = session.gettable('IF-MIB::ifTable')

In [25]:
iftable.indices


Out[25]:
{'1', '2', '3', '8'}

In [26]:
iftable.cols


Out[26]:
{'ifAdminStatus',
 'ifDescr',
 'ifInDiscards',
 'ifInErrors',
 'ifInNUcastPkts',
 'ifInOctets',
 'ifInUcastPkts',
 'ifInUnknownProtos',
 'ifIndex',
 'ifLastChange',
 'ifMtu',
 'ifOperStatus',
 'ifOutDiscards',
 'ifOutErrors',
 'ifOutNUcastPkts',
 'ifOutOctets',
 'ifOutQLen',
 'ifOutUcastPkts',
 'ifPhysAddress',
 'ifSpecific',
 'ifSpeed',
 'ifType'}

In [27]:
iftable


Out[27]:
<easysnmptable.table.Table at 0x7f92f15afb90>

In [28]:
import pprint
for index,row in iftable.rows.items():
    pprint.pprint(index)
    pprint.pprint(row)


'1'
{'ifAdminStatus': 'up',
 'ifDescr': 'lo',
 'ifInDiscards': '0',
 'ifInErrors': '0',
 'ifInNUcastPkts': '0',
 'ifInOctets': '78216562',
 'ifInUcastPkts': '51573',
 'ifInUnknownProtos': '0',
 'ifIndex': '1',
 'ifLastChange': '0:0:00:00.00',
 'ifMtu': '65536',
 'ifOperStatus': 'up',
 'ifOutDiscards': '0',
 'ifOutErrors': '0',
 'ifOutNUcastPkts': '0',
 'ifOutOctets': '78216562',
 'ifOutQLen': '0',
 'ifOutUcastPkts': '51573',
 'ifPhysAddress': '',
 'ifSpecific': 'zeroDotZero',
 'ifSpeed': '10000000',
 'ifType': 'softwareLoopback'}
'2'
{'ifAdminStatus': 'up',
 'ifDescr': 'enp4s0',
 'ifInDiscards': '39648',
 'ifInErrors': '0',
 'ifInNUcastPkts': '650437',
 'ifInOctets': '3350199419',
 'ifInUcastPkts': '38955261',
 'ifInUnknownProtos': '0',
 'ifIndex': '2',
 'ifLastChange': '0:0:00:00.00',
 'ifMtu': '1500',
 'ifOperStatus': 'up',
 'ifOutDiscards': '0',
 'ifOutErrors': '0',
 'ifOutNUcastPkts': '0',
 'ifOutOctets': '2581107288',
 'ifOutQLen': '0',
 'ifOutUcastPkts': '35431426',
 'ifPhysAddress': '1c:6f:65:8d:9a:d2',
 'ifSpecific': 'zeroDotZero',
 'ifSpeed': '100000000',
 'ifType': 'ethernetCsmacd'}
'3'
{'ifAdminStatus': 'up',
 'ifDescr': 'cni-podman0',
 'ifInDiscards': '0',
 'ifInErrors': '0',
 'ifInNUcastPkts': '0',
 'ifInOctets': '904712',
 'ifInUcastPkts': '16845',
 'ifInUnknownProtos': '0',
 'ifIndex': '3',
 'ifLastChange': '0:0:00:00.00',
 'ifMtu': '1500',
 'ifOperStatus': 'up',
 'ifOutDiscards': '0',
 'ifOutErrors': '0',
 'ifOutNUcastPkts': '0',
 'ifOutOctets': '17102823',
 'ifOutQLen': '0',
 'ifOutUcastPkts': '22390',
 'ifPhysAddress': '36:37:96:62:8a:93',
 'ifSpecific': 'zeroDotZero',
 'ifSpeed': '0',
 'ifType': 'ethernetCsmacd'}
'8'
{'ifAdminStatus': 'up',
 'ifDescr': 'vethfbbb3749',
 'ifInDiscards': '0',
 'ifInErrors': '0',
 'ifInNUcastPkts': '0',
 'ifInOctets': '22662',
 'ifInUcastPkts': '324',
 'ifInUnknownProtos': '0',
 'ifIndex': '8',
 'ifLastChange': '0:0:00:00.00',
 'ifMtu': '1500',
 'ifOperStatus': 'up',
 'ifOutDiscards': '0',
 'ifOutErrors': '0',
 'ifOutNUcastPkts': '0',
 'ifOutOctets': '116468',
 'ifOutQLen': '0',
 'ifOutUcastPkts': '1615',
 'ifPhysAddress': '46:fc:ac:66:d8:39',
 'ifSpecific': 'zeroDotZero',
 'ifSpeed': '4294967295',
 'ifType': 'ethernetCsmacd'}

A short-coming of easysnmptable is that it does not return the snmp_type for columns. A possible work-around is to use easysnmp to fetch a single column for a random index. This should probably be memoized or cached.


In [72]:
random_index = iftable.indices.pop()
iftable.indices.add(random_index)
random_index


Out[72]:
'3'

In [76]:
column2type = {column: session.get('{}.{}'.format(column, random_index)).snmp_type for column in iftable.cols}
column2type


Out[76]:
{'ifLastChange': 'TICKS',
 'ifOutNUcastPkts': 'COUNTER',
 'ifInDiscards': 'COUNTER',
 'ifOutOctets': 'COUNTER',
 'ifInErrors': 'COUNTER',
 'ifPhysAddress': 'OCTETSTR',
 'ifSpeed': 'GAUGE',
 'ifSpecific': 'OBJECTID',
 'ifOutQLen': 'GAUGE',
 'ifDescr': 'OCTETSTR',
 'ifInOctets': 'COUNTER',
 'ifOutUcastPkts': 'COUNTER',
 'ifAdminStatus': 'INTEGER',
 'ifOperStatus': 'INTEGER',
 'ifType': 'INTEGER',
 'ifIndex': 'INTEGER',
 'ifInNUcastPkts': 'COUNTER',
 'ifInUcastPkts': 'COUNTER',
 'ifInUnknownProtos': 'COUNTER',
 'ifOutDiscards': 'COUNTER',
 'ifOutErrors': 'COUNTER',
 'ifMtu': 'INTEGER'}

Such a table could be build by "walking" a device.


In [82]:
column2type = {item.oid: item.snmp_type for item in session.walk('IF-MIB::ifTable')}
column2type


Out[82]:
{'ifIndex': 'INTEGER',
 'ifDescr': 'OCTETSTR',
 'ifType': 'INTEGER',
 'ifMtu': 'INTEGER',
 'ifSpeed': 'GAUGE',
 'ifPhysAddress': 'OCTETSTR',
 'ifAdminStatus': 'INTEGER',
 'ifOperStatus': 'INTEGER',
 'ifLastChange': 'TICKS',
 'ifInOctets': 'COUNTER',
 'ifInUcastPkts': 'COUNTER',
 'ifInNUcastPkts': 'COUNTER',
 'ifInDiscards': 'COUNTER',
 'ifInErrors': 'COUNTER',
 'ifInUnknownProtos': 'COUNTER',
 'ifOutOctets': 'COUNTER',
 'ifOutUcastPkts': 'COUNTER',
 'ifOutNUcastPkts': 'COUNTER',
 'ifOutDiscards': 'COUNTER',
 'ifOutErrors': 'COUNTER',
 'ifOutQLen': 'GAUGE',
 'ifSpecific': 'OBJECTID'}

In [ ]: