使用SNMP,尝试访问TP-LINK调制解调器中的数据

时间:2015-04-18 01:32:38

标签: python net-snmp pysnmp

前几天,调制解调器坏了,我买了一台新的TP-LINK TD8816来取代它。我一直试图在SNMP中弄湿我的脚以获得调制解调器的统计数据。以下是我采取的步骤:

  • 我在调制解调器中启用了SNMP,仅在LAN端口上启用。
  • 我安装了pysnmp(4.2.5)和pysnmp-mibs
  • 安装并编译mbrowse
  • 将snmp.conf设置为最小rocommunity public default .1.3.6.1.2.1.1

当我尝试访问adslMIB中的变量时,找不到任何变量:

使用mbrowse我看到很多声明的变量,但'get'告诉我变量没有退出。 (修改的)pysnmp'one-liner'演示程序产生错误(见下文)。

我可以在调制解调器中访问sysDescr和OID:

$ snmpwalk -Os -c public -v 1 10.0.0.2 1.3.6.1.2.1.1.1 
sysDescr.0 = STRING: TD-8816
$ snmpwalk -Os -c public -v 1 10.0.0.2 1.3.6.1.2.1.1.2
sysObjectID.0 = OID: enterprises.1.2.3.4.5

但没有别的......

这是修改后的pysnmb脚本:

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

class SNMP_access():
    def __init__(self):
        self.cmdGen = cmdgen.CommandGenerator()

    def test(self):
        errorIndication, errorStatus, errorIndex, varBinds = \
            self.cmdGen.getCmd(
                cmdgen.CommunityData('public'),
                cmdgen.UdpTransportTarget(('10.0.0.2', 161)),
                cmdgen.MibVariable('ADSL-LINE-MIB', 'adslAturPerfLoss', '0')
            )

        # Check for errors and print out results
        if errorIndication:
            print(errorIndication)
        else:
            if errorStatus:
                print('%s at %s' % (
                    errorStatus.prettyPrint(),
                    errorIndex and varBinds[int(errorIndex)-1] or '?'
                    )
                )
            else:
                for name, val in varBinds:
                    print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))

def main():
    # use specific flags or 'all' for full debugging
    #debug.setLogger(debug.Debug('dsp', 'msgproc', 'secmode'))

    snmp = SNMP_access()
    snmp.test()
    return 0

if __name__ == '__main__':
    main()

以及由此产生的追溯:

Traceback (most recent call last):
  File "snmptest.py", line 63, in <module>
    main()
  File "snmptest.py", line 59, in main
    snmp.test()
  File "snmptest.py", line 37, in test
    cmdgen.MibVariable('ADSL-LINE-MIB', 'adslAturPerfLoss', '0')
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/entity/rfc3413/oneliner/cmdgen.py", line 424, in getCmd
    kwargs.get('contextName', null)
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/entity/rfc3413/oneliner/cmdgen.py", line 277, in getCmd
    self.makeReadVarBinds(varNames),
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/entity/rfc3413/oneliner/cmdgen.py", line 201, in makeReadVarBinds
    [ (x, self._null) for x in varNames ], oidOnly=True
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/entity/rfc3413/oneliner/cmdgen.py", line 209, in makeVarBinds
    varName.resolveWithMib(self.mibViewController, oidOnly=True)
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/entity/rfc3413/oneliner/mibvar.py", line 180, in resolveWithMib
    instIds = rowNode.getInstIdFromIndices(*self.__args[2:])
  File "/usr/lib64/python2.7/site-packages/pysnmp-4.2.5-py2.7.egg/pysnmp/smi/mibs/SNMPv2-SMI.py", line 1096, in getInstIdFromIndices
    mibObj.syntax.clone(indices[idx]), impliedFlag
  File "/usr/lib64/python2.7/site-packages/pyasn1-0.1.7-py2.7.egg/pyasn1/type/univ.py", line 107, in clone
    return self.__class__(value, tagSet, subtypeSpec, namedValues)
  File "/usr/lib64/python2.7/site-packages/pyasn1-0.1.7-py2.7.egg/pyasn1/type/univ.py", line 22, in __init__
    self, value, tagSet, subtypeSpec
  File "/usr/lib64/python2.7/site-packages/pyasn1-0.1.7-py2.7.egg/pyasn1/type/base.py", line 69, in __init__
    self._verifySubtypeSpec(value)
  File "/usr/lib64/python2.7/site-packages/pyasn1-0.1.7-py2.7.egg/pyasn1/type/base.py", line 33, in _verifySubtypeSpec
    raise c('%s at %s' % (i, self.__class__.__name__))
pyasn1.type.error.ValueConstraintError: ConstraintsIntersection(ConstraintsIntersection(ConstraintsIntersection(), ValueRangeConstraint(-2147483648, 2147483647)), ValueRangeConstraint(1, 2147483647)) failed at: "ValueRangeConstraint(1, 2147483647) failed at: "0"" at InterfaceIndex

编辑:更多细节,以回应伊利亚的回复:

  • 供应商不发布MIB。在他们的论坛上,我发现了几个“猜测”
  • 调制解调器配置中没有选项来限制访问。
  • 我用-v1和-v2c运行snmpwalk,输出相同
  • 我通过telnet连接访问了社区,只有“获取”社区名称是公开的(没有找到其他社区名称)
  • 此处没有其他启用SNMP的界面。
  • 调制解调器实际连接。我可以通过telnet接口查询所有参数(adsl和其他参数),甚至可以查询每个频道频率中SNR的详细数据。

1 个答案:

答案 0 :(得分:1)

发生此特定SNMP错误是因为您尝试使用无效的SNMP表索引构建OID。

adslAturPerfLoss表列属于adslAturPerfDataEntry,它使用ifIndex对象索引表对象。 ifIndex列具有值类型的InterfaceIndex,而该类型又是一个约束为1..2147483647值的整数。你给它0会产生错误。

然而,这并不能解释为什么您的调制解调器不会显示其大部分SNMP变量。与您的调制解调器相关的检查事项:

  • 供应商是否提供ADSL-MIB支持?
  • 供应商是否需要调制解调器SNMP代理的某些特定SNMP视图配置才能访问其他OID?
  • 调制解调器内部的SNMP代理可能与SNMP v2c的工作方式不同吗?
  • ..或使用其他一些SNMP社区名称时?
  • ..或查询其他网络接口时(如果还有其他网络接口)?
  • ..或当调制解调器完全可操作时(例如连接到其对等端)?