只走特定节点
Walking only specific node
我正在构建一个脚本,它应该通过 SNMP(步行)从调制解调器获取 MAC/IP 地址。为此,我使用 PySNMP 和 nextCmd
(asyncore)。虽然我得到了我想要的,但目前我收到的比我预期的要多:在走完特定节点后,它会继续剩下的所有其他节点。
代码:
nextCmd(snmpEngine,
CommunityData('private'),
UdpTransportTarget(('IP.goes.right.here', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.4.22.1.2')),
cbFun=cbFun)
snmpEngine.transportDispatcher.runDispatcher()
cbFun
def cbFun(snmpEngine, sendRequestHandle, errorIndication,
errorStatus, errorIndex, varBindTable, cbCtx):
if errorIndication:
print(errorIndication)
return
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex) - 1][0] or '?'))
return
else:
for varBindRow in varBindTable:
for varBind in varBindRow:
print(' = '.join([x.prettyPrint() for x in varBind]))
return True
这完全基于 documentation 以及在 Internet 上找到的其他一些示例。
示例输出:
1.3.6.1.2.1.4.22.1.2.536870914.some.ip.was.here = 0xMacAddress
1.3.6.1.2.1.4.22.1.3.1182728.some.ip.was.here = some.ip.was.here # next node
1.3.6.1.2.1.4.22.1.4.1182736.some.ip.was.here = 3 # and even further
...
所以此目的仅限于步行 1.3.6.1.2.1.4.22.1.2.
P.S。我刚开始使用 PySNMP,我想要类似的东西
snmpwalk -v 2c -c private some.ip.was.here ipNetToPhysicalPhysAddress
您是否考虑过将 lexicographicMode 添加到 nextCmd 属性?
类似于:
nextCmd(snmpEngine,
CommunityData('private'),
UdpTransportTarget(('IP.goes.right.here', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.4.22.1.2')),lexicographicMode=False,
cbFun=cbFun)
由于缺少解决此问题的任何内置方法,我对 cbFun()
进行了更改。它现在有一些额外的行包含 re.search()
并且模式是 OID(因此当模式不匹配时,即 nextCmd 转到另一个级别(节点),它只是 return
)。我让它变得简单,因为已经构造了响应 print(' = '.join([x.prettyPrint() for x in varBind]))
的字符串,我添加了 if
条件并将上面代码的结果分配给变量,所以我可以实现这张支票。
作为另一种可能的解决方案,也可以使用 this 示例中描述的方法 - 使用 varBindHead 并比较它们。
随时添加您的解决方案。
我正在构建一个脚本,它应该通过 SNMP(步行)从调制解调器获取 MAC/IP 地址。为此,我使用 PySNMP 和 nextCmd
(asyncore)。虽然我得到了我想要的,但目前我收到的比我预期的要多:在走完特定节点后,它会继续剩下的所有其他节点。
代码:
nextCmd(snmpEngine,
CommunityData('private'),
UdpTransportTarget(('IP.goes.right.here', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.4.22.1.2')),
cbFun=cbFun)
snmpEngine.transportDispatcher.runDispatcher()
cbFun
def cbFun(snmpEngine, sendRequestHandle, errorIndication,
errorStatus, errorIndex, varBindTable, cbCtx):
if errorIndication:
print(errorIndication)
return
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex) - 1][0] or '?'))
return
else:
for varBindRow in varBindTable:
for varBind in varBindRow:
print(' = '.join([x.prettyPrint() for x in varBind]))
return True
这完全基于 documentation 以及在 Internet 上找到的其他一些示例。
示例输出:
1.3.6.1.2.1.4.22.1.2.536870914.some.ip.was.here = 0xMacAddress
1.3.6.1.2.1.4.22.1.3.1182728.some.ip.was.here = some.ip.was.here # next node
1.3.6.1.2.1.4.22.1.4.1182736.some.ip.was.here = 3 # and even further
...
所以此目的仅限于步行 1.3.6.1.2.1.4.22.1.2.
P.S。我刚开始使用 PySNMP,我想要类似的东西
snmpwalk -v 2c -c private some.ip.was.here ipNetToPhysicalPhysAddress
您是否考虑过将 lexicographicMode 添加到 nextCmd 属性?
类似于:
nextCmd(snmpEngine,
CommunityData('private'),
UdpTransportTarget(('IP.goes.right.here', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.4.22.1.2')),lexicographicMode=False,
cbFun=cbFun)
由于缺少解决此问题的任何内置方法,我对 cbFun()
进行了更改。它现在有一些额外的行包含 re.search()
并且模式是 OID(因此当模式不匹配时,即 nextCmd 转到另一个级别(节点),它只是 return
)。我让它变得简单,因为已经构造了响应 print(' = '.join([x.prettyPrint() for x in varBind]))
的字符串,我添加了 if
条件并将上面代码的结果分配给变量,所以我可以实现这张支票。
作为另一种可能的解决方案,也可以使用 this 示例中描述的方法 - 使用 varBindHead 并比较它们。
随时添加您的解决方案。