我一直在研究自定义的SNMP Mib,我试图让代理返回正确的数据时遇到了问题.
MIB(通过运行验证smilint -l 6):
IDB-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32, enterprises
FROM SNMPv2-SMI
MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
idb MODULE-IDENTITY
LAST-UPDATED "201307300000Z" -- Midnight 30 July 2013
ORGANIZATION "*********"
CONTACT-INFO "email: *******"
DESCRIPTION "description"
REVISION "201307300000Z" -- Midnight 29 July 2013
DESCRIPTION "First Draft"
::= { enterprises 42134 }
iDBCompliance MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"Compliance statement for iDB"
MODULE
GROUP testGroup
DESCRIPTION
"This group is a test group"
::= {idb 1}
test2 OBJECT-TYPE
SYNTAX Integer32
UNITS "tests"
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"A test object"
DEFVAL { 5 }
::= { idb 3 }
testGroup OBJECT-GROUP
OBJECTS {
test2
}
STATUS current
DESCRIPTION "all test objects"
::= { idb 2 }
END
Run Code Online (Sandbox Code Playgroud)
代理文件:
#!/usr/bin/perl
use NetSNMP::OID(':all');
use NetSNMP::agent(':all');
use NetSNMP::ASN(':all');
sub myhandler {
my ($handler, $registration_info, $request_info, $requests) = @_;
print "Handling request\n";
for ($request = $requests; $request; $request = $request->next()) {
#
# Work through the list of varbinds
#
my $oid = $request->getOID();
print "Got request for oid $oi\n";
if ($request_info->getMode() == MODE_GET) {
if ($oid == new NetSNMP::OID($rootOID . ".3")) {
$request->setValue(ASN_INTEGER, 2);
}
}
}
}
{
$subagent = 0;
print "Running new agent\n";
my $rootOID = ".1.3.6.1.4.1.42134";
my $regoid = new NetSNMP::OID($rootOID);
if (!$agent) {
$agent = new NetSNMP::agent('Name'=>'my_agent_name','AgentX' => 1);
$subagent = 1;
print "Starting subagent\n";
}
print "Registering agent\n";
$agent->register("my_agent_name", $regoid, \&myhandler);
print "Agent registered\n";
if ($subagent) {
$SIG{'INT'} = \&shut_it_down;
$SIG{'QUIT'} = \&shut_it_down;
$running = 1;
while ($running) {
$agent->agent_check_and_process(1);
}
$agent->shutdown();
}
}
sub shut_it_down() {
$running = 0;
print "Shutting down agent\n";
}
Run Code Online (Sandbox Code Playgroud)
当我运行代理时,我得到以下内容:
Running new agent
Starting subagent!
Registering agent with oid idb
Agent registered
Run Code Online (Sandbox Code Playgroud)
所以我知道这很有用.但是当我运行以下命令时:
snmpget -v 1 -c mycommunity localhost:161 test2.0
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: IDB-MIB::test2.0
Run Code Online (Sandbox Code Playgroud)
我从snmptranslate知道mib文件设置正确.我甚至查看了snmpget的调试(使用-DALL)以确保正确加载和解析mib.
所以我的问题是:为什么我的子代理没有通过请求?
更新:
@EhevuTov告诉我,我的MIB文件无效,但是smilint没有报告任何问题,并且运行snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3.0确实报告了对象的名称(IDB-MIB :: test2.0),但没有找到任何数据为了它.
我得到了IDB-MIB::test2 = No Such Object available on this agent at this OID,这让我认为我的代理人没有正确注册,但它没有丢失任何错误.
更新2:
我一直在调整代理代码.根据CPAN文档(http://metacpan.org/pod/NetSNMP::agent),看起来$agent->register函数调用0如果成功则应返回.所以我检查了返回代码,得到了这个:
Agent registered. Result: NetSNMP::agent::netsnmp_handler_registration=SCALAR(0x201e688)
Run Code Online (Sandbox Code Playgroud)
使用以下Data::Dumper结果将其打印出来:
$VAR1 = bless( do{\(my $o = 34434624)}, 'NetSNMP::agent::netsnmp_handler_registration' );
Run Code Online (Sandbox Code Playgroud)
我模糊地理解了什么是祝福,但即便如此,我也不知道这个结果应该是什么意思.所以我开始认为代理人在某种程度上是错误的.有谁知道如何调试这些代理?有什么地方我可以看看它是否正确加载到主snmpd?
小智 2
我已经解决了这个问题。不是与 MIB 相关,而是与代理相关(我认为它一直工作正常,所以我从来没有费心去检查它)。
我一直在独立运行代理,因为它看起来工作正常(注册处理程序时从未抛出任何错误)。但显然,它需要直接由 snmpd 运行。
我将其移动到 snmpd 可以访问的目录(因为显然 snmpd 也无法从 /root 运行脚本,即使它以 root 身份运行),并在 snmpd.conf 中添加了这些行:
perl print "\nRunning agents now\n";
perl do "/usr/share/snmp/agent.pl" || print "Problem running agent script: $!\n";
perl print "Agents run\n";
Run Code Online (Sandbox Code Playgroud)
请注意,这两行已经存在:
disablePerl false
perlInitFile /usr/share/snmp/snmp_perl.pl
Run Code Online (Sandbox Code Playgroud)
我现在可以运行 snmpget 命令并获得预期的响应。
> snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3
IDB-MIB::test2 = INTEGER: 2 tests
Run Code Online (Sandbox Code Playgroud)