Snmp Agent開發流程
作者:zyq
時間: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
此時一個標準的
4.配置代理,修改配置檔案(可以通過snmpconf命令生成配置檔案,這裡我手動建立配置檔案,只做簡單配置,保證其可以工作,具體設定可以自己查詢)
#vim /usr/local/share/snmp/snpmd.conf
輸入如下兩行配置,儲存(其中public為預設讀密碼,123456為讀寫密碼)
rocommunitypublic
rwcommunity123456
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 <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <signal.h>
#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檔案的編寫,例程裡提供的這兩個檔案寫的非常好,包含各種資料型別,整合度很高,建議對著這個示例進行擴充套件。