作者:zyq
Email:[email protected]
时间:2010-11-3
Snmp Agent扩展
该文档将主要讲述基于开源项目net-snmp的snmp代理端开发流程,首先讲标准代理的安装流程,再讲述三种mib扩展方式,每种方式对应不同的开发需求,最后会讲下如何移植到arm板上。
一.系统环境:
操作系统:CentOS 5.4 内核:Linux_2.6
编译环境:gcc 4.1.2 代码版本:net-snmp-5.4.3.tar.gz
(下载地址:http://jaist.dl.sourceforge.net/project/net-snmp/net-snmp/5.4.3/net-snmp-5.4.3.tar.gz)
二.安装net-snmp
1.解压缩包并切换目录:
# tar zxvf net-snmp-5.4.3.tar.gz
#cd net-snmp-5.4.3
2.配置configure
# ./configure --enable-mfd-rewrites --enable-embedded-perl --with-perl-modules --with-default-snmp-version="2" --with-sys-contact="linux" --with-sys-location="China"
此时会提示还需要一些参数,直接回车就行了
3.编译和安装
#make
#make install
此时一个标准的snmp代理端已经安装完成(默认安装在/usr/local/share/snmp/路径下,snmpd即为代理程序)
4.配置代理,修改配置文件(可以通过snmpconf命令生成配置文件,这里我手动建立配置文件,只做简单配置,保证其可以工作,具体设置可以自己查询)
#vim /usr/local/share/snmp/snpmd.conf
输入如下两行配置,保存(其中public为默认读密码 ,123456为读写密码)
rocommunity public
rwcommunity 123456
5.测试我们的代理是否正常工作,输入:
# snmpwalk -v 1 -c public localhost 1.3.6.1.2.1.1
提示如下类似信息,则配置成功
SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost 2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-TC::linux
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1047697) 2:54:36.97
SNMPv2-MIB::sysContact.0 = STRING: linux
SNMPv2-MIB::sysName.0 = STRING: mylinux
SNMPv2-MIB::sysLocation.0 = STRING: China
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.6 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.7 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.8 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (1) 0:00:00.01
三.扩展自己的mib
以上步骤只是完成了一个包含标准mib库的代理端安装,下面将介绍如何加入自己的mib库,以下灰色部分是用mib2c工具生成.c和.h文件的方法,仅供参考,个人不推荐,可以跳过
1.假如下面是我们自己编写的mib文件(保存为BVCOM-SYSTEMUPTIME-MIB.txt)
BVCOM-SYSTEMUPTIME-MIB DEFINITIONS ::= BEGIN
IMPORTS
TimeTicks FROM SNMPv2-SMI
enterprises FROM SNMPv2-SMI
OBJECT-TYPE, Integer32, MODULE-IDENTITY FROM SNMPv2-SMI;
bvcom OBJECT IDENTIFIER ::= { enterprises 26814 }
ipq6800 OBJECT IDENTIFIER ::= { bvcom 6800 }
bvcomAgentModules OBJECT IDENTIFIER ::= { ipq6800 1 }
bvcomAgentModuleObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when compiled into the agent. See
http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
implementation details."
DEFVAL { 1 }
::= { bvcomAgentModules 1 }
bvcomAgentSubagentObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when attached to the agent. The object should be accessible
when the agentx subagent containing this object is attached.
See http://www.net-snmp.org/tutorial-5/toolkit/XXX for
further implementation details."
DEFVAL { 2 }
::= { bvcomAgentModules 2 }
bvcomAgentPluginObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when attached to the agent. This object should be accessible
when the dynamic plugin has been loaded into the agent. See
http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
implementation details."
DEFVAL { 3 }
::= { bvcomAgentModules 3 }
END
2. 复制mib库文件到/usr/local/share/snmp/mibs/
# cp BVCOM-SYSTEMUPTIME-MIB.txt /usr/local/share/snmp/mibs/BVCOM-SYSTEMUPTIME-MIB.txt
3. 加载mib库(修改snmp.conf文件,该文件也要自己建立,或通过snmpconf生成)
vim /usr/local/share/snmp/snmp.conf
输入如下并保存:
mibs +BVCOM-SYSTEMUPTIME-MIB
4.测试mib库是否加载成功
# snmptranslate -IR -Tp bvcom
出现如下信息表示成功
+--bvcom(26814)
|
+--ipq6800(6800)
|
+--bvcomAgentModules(1)
|
+-- -RW- Integer32 bvcomAgentModuleObject(1)
+-- -RW- Integer32 bvcomAgentSubagentObject(2)
+-- -RW- Integer32 bvcomAgentPluginObject(3)
5. 查看mib2c支持的模板
# ls /usr/local/share/snmp/
显示如下
mib2c.access_functions.conf mib2c.create-dataset.conf mib2c.scalar.conf
mib2c.array-user.conf mib2c-data mib2c.table_data.conf
mib2c.check_values.conf mib2c.genhtml.conf mibs
mib2c.check_values_local.conf mib2c.int_watch.conf snmp.conf
mib2c.column_defines.conf mib2c.iterate_access.conf snmp.conf~
mib2c.column_enums.conf mib2c.iterate.conf snmpconf-data
mib2c.column_storage.conf mib2c.mfd.conf snmpd.conf
mib2c.conf mib2c.notify.conf snmp_perl.pl
mib2c.container.conf mib2c.old-api.conf snmp_perl_trapd.pl
6. 通过模板生成.c 和 .h 文件(因为自定义的mib库中的变量都是int类型的所以模板选择int_watch.conf,不同的模板功能不同)
自己建立一个文件夹example-demon,并切换到该目录下,
# mib2c -c mib2c.int_watch.conf bvcomAgentModules
writing to -
*** Warning: only generating code for nodes of MIB type INTEGER
writing to bvcomAgentModules.h
writing to bvcomAgentModules.c
running indent on bvcomAgentModules.c
running indent on bvcomAgentModules.h
这样在当前目录下就生成了我们自己mib库对应的bvcomAgentModules.c和bvcomAgentModules.h,这两个文件只提供了框架,具体的读内容和写内容需要自己完成
这种通过工具生成的c和h文件,比较模式化,不够灵活,不建议采用,建议参考源代码net-snmp-5.4.3/agent/mibgroup/examples下的example.c和example.h,其相应的mib文件在net-snmp-5.4.3/mibs/ NET-SNMP-EXAMPLES-MIB.txt
有了我们mib库对应的example.c 和example.h文件,现在我们就需要将其加入snmp代理中了,首先我们通过snmp_agent_api 编写守护程序 example-demon.c(新建一个test文件夹,将example.c 和example.h考入其中),并将如下代码保存为example-demon.c (文章末尾有附件可以下载)
/*主函数: */
#include
#include
#include
#include
#include "example.h" //这里要包含刚才的头文件
static int keep_running;
RETSIGTYPE
stop_server(int a) {
keep_running = 0;
}
int
main (int argc, char **argv) {
int agentx_subagent=0; /* change this if you want to be a SNMP master agent */
int background = 0; /* change this if you want to run in the background */
int syslog = 0; /* change this if you want to use syslog */
/* print log errors to syslog or stderr */
if (syslog)
snmp_enable_calllog();
else
snmp_enable_stderrlog();
/* we're an agentx subagent? */
if (agentx_subagent) {
/* make us a agentx client. */
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
}
/* run in background, if requested */
if (background && netsnmp_daemonize(1, !syslog))
exit(1);
/* Initialize tcpip, if necessary */
SOCK_STARTUP;
/* Initialize the agent library */
init_agent("example-demon"); // 配置文件名
/* Initialize our mib code here */
printf("Before init bvcomAgentModules /n");
init_bvcomAgentModules(); // 加载节点信息
printf("End init bvcomAgentModules /n");
/* initialize vacm/usm access control */
if (!agentx_subagent) {
void init_vacm_vars();
void init_usmUser();
}
/* Example-demon will be used to read example-demon.conf files. */
init_snmp("example-demon");
/* If we're going to be a snmp master agent, initial the ports */
if (!agentx_subagent)
init_master_agent(); /* open the port to listen on (defaults to udp:161) */
printf("---------------------/n");
/* In case we recevie a request to stop (kill -TERM or kill -INT) */
keep_running = 1;
signal(SIGTERM, stop_server);
signal(SIGINT, stop_server);
snmp_log(LOG_INFO,"example-demon is up and running./n");
/* your main loop here... */
while(keep_running) {
/* if you use select(), see snmp_select_info() in snmp_api(3) */
/* --- OR --- */
agent_check_and_process(1); /* 0 == don't block */
}
/* at shutdown time */
snmp_shutdown("example-demon");
SOCK_CLEANUP;
return 0;
}
下面是makefile;
CC=gcc
OBJS2=example-demon.o example.o
TARGETS=example-demon
CFLAGS=-I. `net-snmp-config --cflags`
BUILDLIBS=`net-snmp-config --libs`
BUILDAGENTLIBS=`net-snmp-config --agent-libs`
# shared library flags (assumes gcc)
DLFLAGS=-fPIC –shared
all: $(TARGETS)
example-demon: $(OBJS2)
$(CC) -o example-demon $(OBJS2) $(BUILDAGENTLIBS)
clean:
rm $(OBJS2) $(OBJS2) $(TARGETS)
编译即可生成我们的代理example-demon;
这里要讲一下int agentx_subagent=0;这个参数的意义
/* =0表示该程序要作为主代理,即不需要snmpd进程的支持,程序自身可以独立运行(需要自己的配置文件Vim /usr/local/share/snmp/example-demon.conf,与上配置一样),此时能读到的mib库只有自己定义的那部分,;=1表示作为子代理,需要snmpd先运行(在配置文件snmpd.conf中添加master agentx,使snmpd作为主代理运行,),此时在运行我们的进程,即可以读到原来的mib库和自己添加的mib库 */
通过agentx_subagent参数的设置我们已经实现了两种方式的代理扩展,
第三种方式
就是将我们自己的mib库对应的c文件和h文件直接编译进snmpd中,使其作为一个整体运行,这时我们需要重新编译安装net-snmp
1.将example.c和example.h复制到net-snmp-5.4.3/agent/mibgroup下
#cp example.? /net-snmp-5.4.3/agent/mibgroup/
2.设置编译参数(红色部分即为加上我们自己的mib模块)
#./configure --enable-mfd-rewrites --with-default-snmp-version="2" --with-sys-contact="linux" --with-sys-location="China" --enable-shared --with-mib-modules="example"
3.编译并安装
#make & make install
然后按第一步一样进行snmpd.conf配置文件修改,
此时再运行snmpd,我们自己的mib库就已经在里面了
四.将snmp代理移植到arm板上
移植主要就是修改configure参数,(当然要装arm-linux-gcc,我的版本是gcc version 2.95.3 20010315)进行重新编译,使其尽量小,尽量精简,下面提供一种参数,至于进一步优化,可以自己尝试修改
执行下列命令:
CC=arm-linux-gcc LDFLAGS="-static" ./configure --build=i386-linux --host=arm-linux --enable-mini-agent --disable-ipv6 --with-endianness=little --disable-manuals --disable-ucd-snmp-compatibility --enable-as-needed --disable-embedded-perl --without-perl-modules --disable-snmptrapd-subagent --disable-applications --disable-scripts
配置完成后进行编译:make
切换到snmpd所在目录/agent
使用如下命令进行压缩,使代理更小:
#arm-linux-strip snmpd
将snmpd和snmpd.conf文件移到linux的nfs(一个网络内的主机共享主目录)下,snmpd文件上传到nfs/usr/local/sbin目录下(需要更改访问权限为可执行),将snmpd.conf文件上传到nfs/usr/local/share/snmp/下(不存在的目录先要创建)。
至此,我们就可以在arm板上运行snmp代理了,当然这种最小话安装,少了很多mib库,能查看的信息不多,我们可以自己扩展和修改configure参数加入我们想要的mib库
总结
扩展snmp 代理的难点在于例程中example.c和example.h文件的编写,例程里提供的这两个文件写的非常好,包含各种数据类型,整合度很高,建议对着这个示例进行扩展。
这个是压缩包附件,下载后重命名为rar格式即可,地址http://hi.csdn.net/attachment/201011/3/0_1288781185t02E.gif