使 PySNMP 解析对象 ID
Making PySNMP resolve Object IDs
我正在尝试使用 PySNMP 执行 SNMP-walk。我编写了以下脚本,该脚本有效,但对于每个设备,我 "walk" 只有大约十行的 OID 可以解析为 "real name".
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
import os
# Turn on debugging
#debug.setLogger(debug.Debug('msgproc', 'secmod'))
# Enter parameters
target_IP = raw_input('Target IP (192.168.13.100): ') or '192.168.13.100'
target_port = raw_input('Target port (161): ') or 161
max_timeout = int(raw_input('Maximum timeout in seconds (1):')) or 1
max_retries = int(raw_input('Maximum number of retries (0):')) or 0
target_file_name = raw_input('Target filename (.txt is added): ') + '.txt'
# Check for already existing file
path = 'walks/'
if not os.path.exists(path):
os.makedirs(path)
if exists(path+target_file_name):
sys.exit("The file '%s' already exists. Try again." % target_file_name)
else:
target_file = open(path+target_file_name, 'w+')
# Initialize counter to zero
counter = 0
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Get data
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port), timeout=max_timeout, retries=max_retries),
'1.3',
lexicographicMode=True,
#maxRows=1000,
ignoreNonIncreasingOid=True,
lookupNames=True
)
# Print errors and values to file
if errorIndication:
print(errorIndication)
else:
# Print error messages
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
# Print values
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
counter += 1
target_file.write("(%s)\t %s value = \t%s\n" % (counter, name.prettyPrint(), val.prettyPrint()))
# Finish the operation
target_file.close()
print('Writing to %s successful. %d lines have been written' % (target_file_name, counter))
sys.exit(0)
结果是一个包含很多行的文件。
第一个条目如下所示:
(1) SNMPv2-MIB::sysDescr."0" value = Hirschmann MAR
(2) SNMPv2-MIB::sysObjectID."0" value = 1.5.6.9.1.1.248.4.10.90
(3) SNMPv2-MIB::sysUpTime."0" value = 2626357
(4) SNMPv2-MIB::sysContact."0" value = Hirschmann Automation and Control GmbH
(5) SNMPv2-MIB::sysName."0" value = mar1030.plc-s7-15000
(6) SNMPv2-MIB::sysLocation."0" value = Hirschmann MAR
(7) SNMPv2-MIB::sysServices."0" value = 2
(8) SNMPv2-MIB::sysORLastChange."0" value = 300
但随后 OID 不再解析:
(9) SNMPv2-SMI::mib-2."2.1.0" value = 27
(10) SNMPv2-SMI::mib-2."2.2.1.1.1" value = 1
(11) SNMPv2-SMI::mib-2."2.2.1.1.2" value = 2
(12) SNMPv2-SMI::mib-2."2.2.1.1.3" value = 3
.....
是什么原因造成的,我该怎么办?
要使用 pysnmp 解析 MIB,您必须在进行 SNMP 查询之前将它们加载到 pysnmp 引擎中。您的脚本为 SNMPv2-MIB 执行 MIB 解析,因为它是由 pysnmp 引擎自动加载的。
要在 pysnmp 中使用纯文本 MIB,您必须将它们从纯文本形式(例如 ASN.1)转换为 pysnmp 格式(Python 代码)。您可以使用 build-pysnmp-mib shell 脚本(基于 libsmi)或下载并安装预编译的常用 MIB 包(pysnmp-mibs Python 包)。
要加载部分或所有可用的 MIB,您可以使用 MibVariable.loadMibs(*mibs) 方法。例如,参见 this script。
我正在尝试使用 PySNMP 执行 SNMP-walk。我编写了以下脚本,该脚本有效,但对于每个设备,我 "walk" 只有大约十行的 OID 可以解析为 "real name".
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
import os
# Turn on debugging
#debug.setLogger(debug.Debug('msgproc', 'secmod'))
# Enter parameters
target_IP = raw_input('Target IP (192.168.13.100): ') or '192.168.13.100'
target_port = raw_input('Target port (161): ') or 161
max_timeout = int(raw_input('Maximum timeout in seconds (1):')) or 1
max_retries = int(raw_input('Maximum number of retries (0):')) or 0
target_file_name = raw_input('Target filename (.txt is added): ') + '.txt'
# Check for already existing file
path = 'walks/'
if not os.path.exists(path):
os.makedirs(path)
if exists(path+target_file_name):
sys.exit("The file '%s' already exists. Try again." % target_file_name)
else:
target_file = open(path+target_file_name, 'w+')
# Initialize counter to zero
counter = 0
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Get data
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port), timeout=max_timeout, retries=max_retries),
'1.3',
lexicographicMode=True,
#maxRows=1000,
ignoreNonIncreasingOid=True,
lookupNames=True
)
# Print errors and values to file
if errorIndication:
print(errorIndication)
else:
# Print error messages
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
# Print values
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
counter += 1
target_file.write("(%s)\t %s value = \t%s\n" % (counter, name.prettyPrint(), val.prettyPrint()))
# Finish the operation
target_file.close()
print('Writing to %s successful. %d lines have been written' % (target_file_name, counter))
sys.exit(0)
结果是一个包含很多行的文件。 第一个条目如下所示:
(1) SNMPv2-MIB::sysDescr."0" value = Hirschmann MAR
(2) SNMPv2-MIB::sysObjectID."0" value = 1.5.6.9.1.1.248.4.10.90
(3) SNMPv2-MIB::sysUpTime."0" value = 2626357
(4) SNMPv2-MIB::sysContact."0" value = Hirschmann Automation and Control GmbH
(5) SNMPv2-MIB::sysName."0" value = mar1030.plc-s7-15000
(6) SNMPv2-MIB::sysLocation."0" value = Hirschmann MAR
(7) SNMPv2-MIB::sysServices."0" value = 2
(8) SNMPv2-MIB::sysORLastChange."0" value = 300
但随后 OID 不再解析:
(9) SNMPv2-SMI::mib-2."2.1.0" value = 27
(10) SNMPv2-SMI::mib-2."2.2.1.1.1" value = 1
(11) SNMPv2-SMI::mib-2."2.2.1.1.2" value = 2
(12) SNMPv2-SMI::mib-2."2.2.1.1.3" value = 3
.....
是什么原因造成的,我该怎么办?
要使用 pysnmp 解析 MIB,您必须在进行 SNMP 查询之前将它们加载到 pysnmp 引擎中。您的脚本为 SNMPv2-MIB 执行 MIB 解析,因为它是由 pysnmp 引擎自动加载的。
要在 pysnmp 中使用纯文本 MIB,您必须将它们从纯文本形式(例如 ASN.1)转换为 pysnmp 格式(Python 代码)。您可以使用 build-pysnmp-mib shell 脚本(基于 libsmi)或下载并安装预编译的常用 MIB 包(pysnmp-mibs Python 包)。
要加载部分或所有可用的 MIB,您可以使用 MibVariable.loadMibs(*mibs) 方法。例如,参见 this script。