SNMP协议对网络管理的好处,让很多人都开始使用它。那么现在我们就来讲解一下ucd-snmp工具中进行snmpd扩展的相关源码解析。本文涉及了三种snmpd扩展方法。那么我们会分别进行讲解。首先还是让我们来对snmpd这个命令进行一下简单的介绍。那么,对于常常接触这个命令的人来说,都知道snmpd命令是响应 SNMP请求的守护进程。那么它的标准语法格式是:
snmpd [OPTIONS] [LISTENING ADDRESSES]
语法格式是snmpd后面加上选项或者监听地址。
snmpd扩展方法一: 静态链接形式
先将生成的两个文件, ustScalarSet.h和ustScalarSet.c, 拷贝到下载的ucd-snmp源代码目录下agent/mibgroup子目录中. 例如在我的机器上, ucd-snmp 4.2.1的源代码在/usr/local/src/ucd-snmp-4.2.1中, 相应的拷贝的目标目录为, /usr/local/src/ucd-snmp-4.2.1/agent/mibgroup.
在ucd-snmp 4.2.1的主目录中(我的机器为/usr/local/src/ucd-snmp-4.2.1), 按如下序列执行命令
# ./configure -with-mib-modules="ustScalarSet" # make # make install
这样, 新的代理程序生成并安装. 运行SNMP代理程序
# /usr/local/sbin/snmpd
在用相应的工具程序检索新加入的MIB变量. 可以用如下任何命令:
% /usr/local/bin/snmpget localhost public UCD-SNMP-TUTORIAL-MIB::ustSSSimpleString.0 % /usr/local/bin/snmpwalk localhost public UCD-SNMP-TUTORIAL-MIB::ustScalarSet
#p#snmpd扩展方法二: 共享链接库形式
首先, 在任一目录下编译生成共享链接库. 假定目录为/usr/local/temp. 将两个源文件, ustScalarSet.h和ustScalarSet.c拷贝到此目录下. 按如下命令序列生成共享链接库:
gcc -g -I/usr/local/include -c -o ustScalarSet.o ustScalarSet.c gcc -g -fPIC -shared -o ustScalarSet.so ustScalarSet.o
有两种方法在代理程序中动态加载共享链接库.
第一种,适合于代理程序已运行的情况, 按如下命令序列执行:
# snmpset localhost hyj UCD-DLMOD-MIB::dlmodStatus.1 i create # snmpset localhost hyj UCD-DLMOD-MIB::dlmodName.1 s "ustScalarSet" # snmpset localhost hyj UCD-DLMOD-MIB::dlmodPath.1 s "/usr/local/temp/ustScalarSet.so" # snmpset localhost hyj UCD-DLMOD-MIB::dlmodStatus.1 i load
即可装载.这时可以用工具程序检索或设置相应的变量. 这里需要注意的是工具snmpset的用法. 代理snmpd的确省配置, 不支持任何用户设置变量. 我们可以通过配置文件snmpd.conf中的访问控制部分进行配置. 我在我的snmpd.conf文件中加入了如下两行:
rwcommunity hyj rocommunity public
设置了一个读写community, hyj和一个只读community, public. 配置文件确省位于/usr/local/share/snmp目录下.
第二种, 直接在snmpd.conf中加入一行:
dlmod ustScalarSet /usr/local/temp/ustScalarSet.so
重新启动snmpd代理, 代理自动装载共享库.
关于代理程序以及工具程序相应的配置情况, 参见snmp.conf, snmpd.conf, 和snmpconf的man手册.#p#
snmpd扩展方法三: AgentX子代理协议
首先, 编写一个子代理主函数文件, ustMain.c. 如下:
1) #include; 2) #include ; 3) #include ; 4) int main () { 5) int agentx_subagent=1; 6) snmp_enable_stderrlog(); 7) if (agentx_subagent) { 8) ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, 1); 9) } 10) init_agent("ustMain"); 11) init_ustScalarSet(); 12) init_snmp("ustMain"); 13) if (!agentx_subagent) 14) init_master_agent(161, NULL, NULL); 15) while(1) { 16) agent_check_and_process(1); 17) } 18) snmp_shutdown("ustMain"); 19) }
按如下命令进行编译:
gcc -g -I/usr/local/include -o ustMain ustMain.c ustScalarSet.c -lucdagent -lucdmibs -lsnmp
生成子代理程序, ustMain.
在snmpd.config配置文件中加入一行:
master agentx
以支持AgentX子代理. 并重新启动snmpd.然后启动 ustMain.运行相应的工具程序, 测试是否可以访问新加入的MIB信息.#p#
一个简单的SNMP代理程序
实际上, 我们可以利用ucd-snmp编写自己的SNMP代理程序. 如下文件, hsnmpd.c, 所示. 其实, 这个文件与上一个子代理程序完全相同. 我仅仅是将变量agentx_subagent赋成0.代码如下.
hsnmpd.c :
1) #include; 2) #include ; 3) #include ; 4) int main () { 5) int agentx_subagent=0; 6) if (agentx_subagent) { 7) ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, 1); 8) } 9) init_agent("snmpd"); 10) init_ustScalarSet(); 11) init_snmp("snmpd"); 12) if (!agentx_subagent) 13) init_master_agent(161, NULL, NULL); 14) while(1) { 15) agent_check_and_process(1); 16) } 17) snmp_shutdown("snmpd"); 18) }
第1-3行: 必须包含的头文件. 第5行: 定义一个变量, 表示该代理是主代理或子代理. 通过ucd-snmp开发包编写的代理程序, 既可以作为AgentX主代理, 也可以作为AgentX子代理. 第7-9行:子代理需要初始化的内容. 第10行:初始化代理. 第11行:初始化支持的MIB. 文件ustScalarSet.c中的函数. 第12行:初始化SNMP. 第13-14行:主代理需要初始化的内容. 第15-17行:SNMP协议PDU处理主循环. 第18行:关闭SNMP, 做一些释放资源的工作.
如下编译:
gcc -g -I/usr/local/include -o hsnmpd hsnmpd.c ustScalarSet.c /usr/local/lib/libucdagent.a /usr/local/lib/libucdmibs.a /usr/local/lib/libsnmp.a
运行该程序, hsnmpd. 除了一些关于无法解释配置文件的相关内容的报警外, 程序运行正常. 并且, 可以用工具程序, 如snmpget, snmpwalk等访问其中的MIB信息. 当然, 仅仅只有UCD-SNMP-TUTORIAL-MIB中所描述的信息, 而其他的没有实现的MIB信息无法获得.