我正在研究一个小脚本,它将充当snmp pass_persist处理程序。我希望它读取一个文件(称为“数字”,现在在同一个目录中),它只包含一些整数并将它们作为oid树返回。
我已经被困在这几天了,现在我意识到这是由于对于snmpd如何工作的基本误解。我正在使用snmpd.conf手册页,它没有提到如何处理'get'和'getnext'请求的任何区别,但我认为有一个。我无法为我的生活轻松地使用这个剧本。
对于snmp有更多了解的人可以看一下这段代码吗?我已经看过几个其他版本的pass脚本,包括python中的一些,但是我无法从代码中看到它们如何处理协议与我的代码不同。我看到一个实现处理了一个空白命令(''),但其他人显然没有。
基本上,我在这一点上很困惑! - 它也很难调试snmpd,因为它是调用我脚本的那个,而不是我。我正在记录我能做的事情,并且在前台运行snmpd,但除此之外它还有点“黑盒子”。
任何人都能解释一下吗?
即: 数字文件:
101 102 103 I want returned as: .1.3.6.1.4.1..[snip]..1 = 101 .1.3.6.1.4.1..[snip]..2 = 102 .1.3.6.1.4.1..[snip]..3 = 103
我的脚本(我不担心返回除整数之外的任何内容,我知道文件关闭永远不会到达,但它让我感觉更好):
#!/bin/python -u
import os,sys, syslog
def getLine():
return sys.stdin.readline().strip()
def getFileLine(sub_oid, lines):
sub_oid = int(sub_oid)
if sub_oid >= len(lines):
return 'NONE'
else:
return lines[sub_oid]
def printOutput(oid, var_type, varbind_value):
if varbind_value == 'NONE':
print 'NONE'
else:
print oid
print var_type
print varbind_value
######################################################
sub_oid = 0
FH = open('numbers','r')
lines = FH.readlines()
while True:
command = getLine()
syslog.syslog("command: %s" % command)
if command == 'PING':
syslog.syslog('got a ping')
print 'PONG'
elif command == 'get':
given_oid = getLine()
sub_oid = int(given_oid.split('.')[-1])
varbind_value = getFileLine(sub_oid, lines)
printOutput(given_oid, 'integer', varbind_value.strip())
elif command == 'getnext':
given_oid = getLine()
syslog.syslog("got a requested oid of: %s" % given_oid)
sub_oid = int(given_oid.split('.')[-1])
varbind_value = getFileLine(sub_oid, lines)
printOutput(given_oid, 'integer', varbind_value.strip())
else:
syslog.syslog("Unknown command: %s" % command)
FH.close()
答案 0 :(得分:2)
首先,已经有一个专门用于此任务的snmp-passpersist Python module。其页面包含指向实际使用示例的链接。您的案例的示例代码如下。
关于您的具体问题:
getnext
的描述确实在规范和维基百科中都不为人所知。在TUT:snmpgetnext - Net-SNMP Wiki中很好地解释了这一点
简而言之,它检索第一个有效的OID (及其值),它位于代理程序层次结构中的指定值之后。这里的“层次结构”可以表示为代理知道的当前有效的所有OID的有序列表。
pass_persist
处理程序 - "NONE"
)。getnext
确实与get
不同(其请求类型ID为1
,get
为0
。< / LI>
get
相同的方式处理它:这只意味着“行走”和“猜测”不起作用(行走可能无限循环)。这就是我在上一次职业中维护的处理程序如何工作,这正是您当前代码中正在发生的事情:^)。getFileLine(int(sub_oid)+1, lines)
- 因为您的代码已足够聪明,可以在耗尽时返回"NONE"
。 “猜测”仍然无效,但......你需要吗? net-snmpd
有很多日志记录选项 - 在its manpage上搜索“log”(而且,它是免费软件!当其他所有方法都失败时,您可以随时查阅甚至调试源代码)。但在这种特殊情况下,在使用snmpget
/ snmpgetnext
和/或使用嗅探器进行查询时记录stdin和stdout已经足够了。
使用前面提到的snmp-passpersist
,您的代码归结为:
base_oid=".1.3.6.1.4.1..[snip]"
data_file="<path>"
import snmp_passpersist as snmp
pp=snmp.PassPersist(base_oid)
for l in (l.rstrip() for l in open(data_file)):
pp.add_int(l,int(l))
pp.start(user_func=lambda:True,refresh=1800) # If data updates are needed,
# replace lambda with a real fn
# and adjust refresh (sec)
如果您需要监控文件的更改,您可以轮询它(如上面的评论建议)或(在Linux中)使用类似pyinotify的内容 - 在这种情况下,您可能需要在调用pp.main_update()
之前替换pp.start()
或者以某种方式修补模块的机制。