SNMP网管学习笔记
编译环境:win7,VC2008
解压net-snmp-5.7.1.zip
运行cmd到DOS窗口下;
cd C:\ProgramFiles\Microsoft Visual Studio 9.0\VC
vcvarsall.bat
到win32目录下:cd net-snmp-5.7.1\win32
执行build.bat
出现下面的信息:
Net-SNMP build and install options
==================================
1. OpenSSL support: disabled
2. Platform SDK support: disabled
3. Install path: c:/usr
4. Install after build: enabled
5. Perl modules: disabled
6. Install perl modules: disabled
7. Quiet build (logged): enabled
8. Debug mode: disabled
9. IPv6 transports (requiresSDK): disabled
10. winExtDLL agent (requires SDK): disabled
11. Link type: static
12. Install development files disabled
F. Finished - start build
Q. Quit - abort build
按相应的菜单项如2+回车,则使Platform SDK support 为enable.同样设置5,6,12为enable.设置完成后,按f+回车开始编译.
在环境变量中增加lib变量,并将c:\usr\lib追加到其中.
cd D:\SNMP\net-snmp-5.7.1\perl
perlmakefile.pl
Unable to locate the MIBs, Please enter thepath: [] C:\usr\share\snmp\mibs
Unable to locate "snmpd". Pleaseenter the path: [\sbin] C:\usr\bin
Unable to locate "snmptrapd".Please enter the path: [\sbin]C:\usr\bin
nmake
nmakeinstall
之后出现:
InstallingC:\Perl\site\lib\auto\NetSNMP\TrapReceiver\Tra
InstallingC:\Perl\site\lib\auto\NetSNMP\TrapReceiver\Tra
InstallingC:\Perl\site\lib\auto\NetSNMP\TrapReceiver\Tra
Installing C:\Perl\site\lib\auto\SNMP\SNMP.dll
InstallingC:\Perl\site\lib\auto\SNMP\SNMP.exp
InstallingC:\Perl\site\lib\auto\SNMP\SNMP.lib
InstallingC:\Perl\site\lib\auto\SNMP\SNMP.pdb
InstallingC:\Perl\html\site\lib\NetSNMP\OID.html
Appending installation info to C:\Perl\lib/perllocal.pod
此后,就可以使用mib2c了
MIB 对象按逻辑关系组织在一个称做树结构的层次结构中。每个 MIB 对象都有一个名称,这个名称从它在树结构中所处的位置派生出来。这个名称叫做对象标识符,通过跟踪从树结构顶部(或叫根)至其底部(即对象本身)的路径而创建。路径分支处的每个位置称为节点。节点可同时拥有父节点和子节点。如果一个节点没有子节点,它就称做叶节点。叶节点是实际的 MIB 对象。只有叶节点才从代理程序处返回 MIB 值。下图显示了一个 MIB 的树形结构。
一个完整的 MIB 对象标识符包括从根开始、包括叶节点在内的所有节点。各节点由句点连接和分隔,这是一种点分十进制表示法。例如,mib-2 子树为.iso.org.dod.internet.mgmt.mib-2,其简写为 .1.3.6.1.2.1。
已在 mib-2(1) 子树中注册了标准 MIB-I 和 MIB-II 定义。mib-2(1) 子树主要用于通过 SNMP 协议管理基于 TCP/IP 的网络。
在子树enterprises(1) 的 private(4) 分支注销特定于企业的 MIB。每个企业分配一个编号。Digital 分配的企业编号是 36;因此所有 Digital 的特定于企业的对象都有以.1.3.6.1.4.1.36开头的点分十进制表示,对应于树结构.iso.org.dod.internet.private.enterprises.digital。分配给 IBM 的企业编号为 2,因此所有 IBM 的特定于企业的对象都具有以 .1.3.6.1.4.1.2 开头的点分十进制表示的符号,对应着树结构.iso.org.dod.internet.private.enterprises.IBM。
NET-SNMP-EXAMPLES-MIB DEFINITIONS ::= BEGIN
…
END
NET-SNMP-EXAMPLES-MIB DEFINITIONS ::= BEGIN
--
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32,
NOTIFICATION-TYPE FROM SNMPv2-SMI
SnmpAdminString FROM SNMP-FRAMEWORK-MIB
netSnmp FROM NET-SNMP-MIB
RowStatus, StorageType FROM SNMPv2-TC
InetAddressType, InetAddress FROM INET-ADDRESS-MIB
;
--
END
MIB文件:
将自己的mib文件放到c:\usr\share\snmp\mibs目录下;
setMIBFILES=C:\usr\share\snmp\mibs\VCOM-EDU-MACHINE-MIB.txt
snmptranslate -Tp -IR vcomEduMachine
出现下面的树状结构,说明MIB文件是正确的.
+--vcomEduMachine(1135)
|
+--hardWare(1)
| |
| +--hardWareTable(1)
| |
| +--hardWareEntry(1)
| | Index: hardWareEntryIndex
| |
| +-- ---- Integer32hardWareEntryIndex(1)
| | Range: 1..65535
| +-- -R-- String hardWareID(2)
| Textual Convention:DisplayString
| Size: 0..255
|
+--softWare(2)
|
+-- -R-- String softWareID(1)
Textual Convention:DisplayString
Size: 0..255
从CMD中进入c:\usr\share\snmp目录,运行以下命令:
setMIBFILES=C:\usr\share\snmp\mibs\VCOM-EDU-MACHINE-MIB.txt
MIB文件中含有table和scalar变量,scalar变量用mib2c.scalar.conf生成.c和.h文件,table表用mib2c.iterate.conf 生成.c和.h文件。
File Name |
Usage |
Example |
mib2c.scalar.conf |
scalar |
|
mib2c.int_watch.conf
|
int scalar |
|
mib2c.mfd.conf |
Table(推荐) |
agent/mibgroup/if-mib/ifTable/ifTable*.c |
mib2c.iterate.conf mib2c. iterate_access.conf |
Table,要获取的数据在Agent外部 |
agent/mibgroup/mibII/vacm_context.c
examples/netSnmpHostsTable* |
mib2c.create-dataset.conf
mib2c.table_data.conf
mib2c.container.conf |
Table,要获取的数据在Agent内部 |
agent/mibgroup/examples/data_set.c |
mib2c.array-user.conf |
Table,要获取的数据在Agent内部,并对表排序 |
|
mib2c.column_defines.conf |
产生头文件 |
|
mib2c.column_enums.conf |
产生头文件 |
|
mib2c.notify.conf |
TRAP |
|
mib2c.old-api.conf |
OLD API(4.X) |
|
mib2c -c mib2c.create-dataset.confhardWareTable
将产生hardWareTable.h和hardWareTable.c文件,将这两个文件加入到Agent代理工程中,编译,根据报出的错误,修改hardWareTable.c文件。
mib2c -c mib2c.iterate.confhardWareTable
c:\usr\share\snmp>mib2c-c mib2c.iterate.confhardWareTable
writing to -
This framework can work in one of two ways:
1) Hold a local cached copy of some externaldata
which is then used toservice incoming requests.
2) Query the external data directly for eachrequest.
The first is typically more efficient, but results in
slightly "stale" data (depending on the expiration timeout
for the cache) and greater memory usage. The second can
provide more up-to-date information, but at the cost of
higher processing overheads.
Which is more appropriate for your needs?
Select your choice : 1
writing to hardWareTable.h
writing to hardWareTable.c
running indent on hardWareTable.c
'indent' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
running indent on hardWareTable.h
'indent' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
mib2c -c mib2c.scalar.confsoftWare
用mib2c.mfd.conf生成table类型的MIB文件,生成的文件比较多,包括:XXX.c/.h;XXX_data_access.c/.h;XXX_data_get.c/.h;XXX_data_set.c/.h;XXX_enums.h;XXX_interface.c/.h;XXX_oids.h;
Snmpget的修改:需要修改的是XXX_data_access.c中的XXX__container_load函数,修改XXXTable中的变量值。
Snmpset的修改:需要修改的是:XXX_data_set.c:XXXTable_commit中设置rowreq_ctx->column_set_flags的值,表示已经修改了XXXTable中的某一项。XXX_data_set.c:中所有的XXX_set.c中指定自己想要的值。
例如:
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
/* XXX: a pointer to the scalar's data */,
/* XXX:the length of the data in bytes */);
break;
将红色部分改为:
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
“abcdefgh”,
9);
break;
建立C++的控制台工程,一个空的工程就可以。设置工程的包含头文件和lib文件。这里需要注意的一点是:include头文件,lib库文件,就是上面4个lib库,别忘了设置连接器:在项目属性的--连接器--输入--"附加依赖项":添加netsnmp.lib netsnmpagent.libnetsnmpmibs.lib netsnmptrapd.lib wsock32.lib;如果环境变量没有起作用,netsnmp.dll与exe文件放在同一文件夹下就可以了。注意:wsock32.lib是其它lib库里用到的,缺少它会报错。
附加库路径:C:\usr\lib
附加包含路径:C:\usr\include
fatalerror C1853: “Release\TestAgent.pch”预编译头文件来自编译器的早期版本,或者预编译头为C++ 而在C 中使用它(或相反)
在.c文件上点右键,属性,c/c++,预编译头,不使用预编译头。
工程样例:
编译后生成TestAgent.exe,直接运行,提示:
example-demon is up and running.
如果对象是scalar类型,必须在OID最后加上0,如
snmpget -v1 -c public localhost .1.3.6.1.4.1.1135.2.1.0
VCOM-EDU-MACHINE-MIB::softWareID.0 = STRING:abcdefgh
snmpwalk -c public -v 2c localhost.1.3.6.1.4.1.1135.1.1
C:\Program Files\Net-SNMP\usr\bin>snmptrapd -f -Le -d
执行之后NET-SNMP开始接收trap,注意这是debug模式,会将收到的trap包内容打印出。
l ** 碰到错误couldn't open p:162 -- errno 2 ("No s h file ordirectory")?
碰到此错误很可能是有程序占用了windows的SNMP接受端口(162)。用下面命令来找出占用此端口的进程。
netstat -ano|find "162"
如果有输出则最后一个数字是进程号。从微软免费下一个ProcessExplorer,找出占用该端口的进程,决定是否停掉。
l ** 碰到错误 Warning: no access controlinformation configured. This receiver will *NOT* accept any incomingnotifications.
没有设定访问控制的情况下NET-SNMP对所有的进入trap都丢掉。因为一个snmp manager可能收到大量的trap而其中只有一小部分是真正需要处理的。具体设置可以通过net-snmp安装目录下的bin\snmpconf.bat来实现(用此方法需要保证计算机上已安装ActivePerl);或者参照docs\Net-SNMP.chm->configuratoin->snmptrapd.conf->AccessControl中的描述来手工修改。
**举例,最简单的设定的步骤(对所有的都不丢):
1.建一个snmptrapd.conf并在此文件中加入下面这行配置。
disableAuthorization yes
2. 在运行snmptrapd的时候加入读取配置文件的参数。e.g.
C:\Program Files\Net-SNMP\usr\bin>snmptrapd -c "C:\ProgramFiles\Net-SNMP\usr\bin\snmptrapd.conf" -f -Le -d
现在收到trap之后,会发现消息已经被尽可能地解开。
l * 如何调用其他windows程序来处理net-snmp捕捉到的trap?
1.在上面生成的文件中,加入下面配置
traphandle default <program>
**举例:
编写下面批处理文件test.bat:
@echo off
echo. >> c:/temp/log.txt
echo %date% %time% >> c:/temp/log.txt
set /P host=%=%
set /P ip=%=%
set /P oid=%=%
set /P val=%=%
echo TRAP: host=%host%; ip=%ip%; %oid% =%val%; >> c:/temp/log.txt
然后在snmptrapd.conf中加入
traphandle default c:/temp/test.bat
那么net-snmp在收到trap时会执行test.bat,打开c:/temp/log.txt会发现有记录在内
编写两个mib文件,包括snmp1和snmp2两种trap
Snmp1的mib:TRAP-TEST-MIB.txt:
TRAP-TEST-MIB DEFINITIONS ::= BEGIN
IMPORTSucdExperimental FROM UCD-SNMP-MIB;
demotraps OBJECTIDENTIFIER ::= { ucdExperimental 990 }
demo-trapTRAP-TYPE
STATUScurrent
ENTERPRISE demotraps
VARIABLES {sysLocation }
DESCRIPTION"This is just a demo"
::= 17
END
Snmp2的mib:NOTIFICATION-TEST-MIB.txt:
NOTIFICATION-TEST-MIB DEFINITIONS ::= BEGIN
IMPORTS ucdavis FROMUCD-SNMP-MIB;
demonotifs OBJECT IDENTIFIER ::={ ucdavis 991 }
demo-notif NOTIFICATION-TYPE
STATUS current
OBJECTS { sysLocation }
DESCRIPTION "Just atest notification"
::= { demonotifs 17 }
END