NET-SNMP開發實踐
|
||
[從興公司 - 王祖祥
瀏覽該做者其餘文章] 點擊:36
|
||
【摘 要】最近項目中須要用SNMP實現對APACHE http server的監控,因爲項目後臺開發使用C語言,故選擇使用NET-SNMP包來實現對SNMP的開發與實現。對於NET-SNMP本人才剛入門,總會碰到N多的問題,網上對於NET-SNMP的資料就更少了,特別是缺乏NET-SNMP的所涉及的整個開發過程。因此就有了一個衝動就是把學習中的過程寫下來。本文將從NET-SNMP的安裝配置、SNMP get、set、trap等主要三個用例的實現來描述使用NET-SNMP開發的全過程。
【關鍵字】SNMP、MIB、ASN一、OID
【系統環境】因爲移植及運行環境等緣由,本文的程序代碼及命令的使用環境及版本以下:
OS: SunOS solaris 5.9 Generic_112234-12 i86pc i386 i86pc
Perl: This is perl, v5.6.1 built for i86pc-solaris-64int
Net-snmp: Version: 5.4.1
GCC:Reading specs from /usr/local/lib/gcc/i386-pc-solaris2.9/3.4.1/specs gcc version 3.4.1
1 NET-SNMP基本介紹
爲了節約篇幅,關於SNMP(簡單網絡管理協議)的相關內容這裏就不用介紹了。
目前關於SNMP的開發包主要有NET-SNMP(for C)、SNMP++(for C++)、SNMP4J(snmp++的JAVA版本)、SNMPJ(NET-SNMP的JAVA版本)。NET-SNMP的早期版本(5.X之前)叫ucd-snmp,源自於卡耐基·梅隆大學的SNMP軟件包CMU snmp 2.1.2.1,由加州大學Davis分校(University of California at Davis)開發與維護,後來由SourceForge (
[url]www.sourceforge.net[/url])開發維護管理, 並改名爲net-snmp(5.X及之後版本),其最新版本爲5.4.1。
NET-SNMP的主要內容包括:
· 完整的API用於SNMP(支持V一、V二、V3版本)應用開發(包括c、perl、Python等的API)
· 一個可擴展的SNMP代理程序(snmpd);開發員能夠擴展本身的代理程序
· 一套工具命令集(snmpget、snmpset、snmptrap、snmpwalk、snmp等)
· 一個trap接收進程,用於接收和顯示trap。並能夠將trap記錄到日誌文件裏
· 一個圖形化的MIB瀏覽工具(tkmib:基於Tk/Perl的)
2 NET-SNMP的安裝、配置
2.1 NET-SNMP的安裝
NET-SNMP包目前能夠移植的版本包括各類UNIX(基於SYSTEM V內核及基於BSD內核)、LINUX、WINX版本。
目前NET-SNMP包的安裝主要有程序編譯安裝與二進制文件安裝兩種方式,源程序安裝能夠從NET-SNMP的官網下載而後按照常規的configure, make ,make install三個步驟就可成功編譯安裝。其相關的二進制安裝能夠到其官網及各OS廠商的網站下載。
FOR SOLARIS 9的安裝請到SUN的官網下載:
gcc-3.4.1-sol9-intel-local.gz、libgcc-3.4.1-sol9-intel-local.gz、
netsnmp-5.4.1-sol9-x86-local.gz、openssl-0.9.8h-sol9-x86-local.gz。
其遵循的安裝過程爲:
·gzip –d xxx.gz (解壓縮)
·tar –xvf *.tar (若是有打包文件,請解包)
·pkgadd –d ./xxxx(安裝)
安裝完畢後,請在/etc/profile中設置好BIN的PATH路徑。
2.2 NET-SNMP的配置
2.2.1
snmpconf
配置
咱們使用/usr/local/bin/ snmpconf,其由perl編寫,因此在運行前,請確認您的PERL安裝路徑,並更改snmpconf的第1行PERL腳本BIN路徑。Snmpconf腳本主要用來配置snmpd.conf、snmptrapd.conf。snmpconf運行後是一個能夠交互的配置設置過程,主要設置:
·System information setup ——包括位置、聯繫人信息等。
·Access control setup —— community name、
·Agent Operating Mode ——AGENT IP、PORT等。
設置完畢後,用戶能夠本身修改snmpd.conf文件中的參數信息。
2.2.2
啓動snmpd
使用NET-SNMP的snmpd可擴展的代理進程替換OS的snmpd。
爲了方便系統啓動時,自動運行net-snmp代理程序,生成/etc/rc3.d/ S78net-snmp shell文件(solaris的多用戶運行等級爲3):S78net-snmp 此SHELL腳本請參考
S78net-snmp。
屏蔽原來OS的SNMPD的配置文件/etc/rc3.d/ S76snmpdx及S77dmi文件。
啓動NET-SNMP的代理程序:./ S78net-snmp start。
中止NET-SNMP的代理程序:./ S78net-snmp stop。
2.2.3
測試NET-SNMP snmpd
# snmpget -v 1 -c public localhost sysDescr.0
SNMPv2-MIB::sysDescr.0 = STRING: SunOS solaris 5.9 Generic_112234-12 i86pc
# snmpget -v 1 -c public localhost sysLocation.0
SNMPv2-MIB::sysLocation.0 = STRING: wangzuxiang
至此NET-SNMP的安裝、配置完成。
3 NET-SNMP的開發
3.1 SNMP GET開發
獲取MIB中OID對象值(snmpget操做)的開發很是簡單,其大體的過程爲:
· 初始化一個SNMP會話;
· 定義會話屬性;
· 增長一個MIB到當前的MIB目錄樹中(可選項);
· 建立一個PDU包 (Primary Data Unit) ;
· 設置OID(或多個)到PDU中;
· 發送請求並等待響應;
· 根據響應值處理業務數據;
· 釋放PDU資源;
· 關閉會話。
mydemo.c範例爲獲取MIB表sysDescr對象(該對象表示設備的描述信息)、sysName、sysLocation等對象值,也可使用snmptranslate -On將其名稱轉換爲OID。例如:
% snmptranslate .1.3.6.1.2.1.1.3.0(轉換OID名稱)
SNMPv2-MIB::sysUpTime.0
% snmptranslate -On SNMPv2-MIB::sysUpTime.0(轉換OID)
.1.3.6.1.2.1.1.3.0 % snmptranslate -Tp -IR system(顯示MIB樹結構) +--system(1) | +-- -R-- String sysDescr(1) | Textual Convention: DisplayString +-- -R-- ObjID sysObjectID(2) +-- -R-- TimeTicks sysUpTime(3) +-- -RW- String sysContact(4)
編譯mydemo.c:
Gcc –o mydemo mydemo.c -lsnmp
運行mydemo:
./mydemo
SNMPv2-MIB::sysDescr.0 = STRING: SunOS solaris 5.9 Generic_112234-12 i86pc
SNMPv2-MIB::sysName.0 = STRING: solaris
SNMPv2-MIB::sysLocation.0 = STRING: wangzuxiang
值 #1 是一個字符串: SunOS solaris 5.9 Generic_112234-12 i86pc
值 #2 是一個字符串: solaris
值 #3 是一個字符串: wangzuxiang
注意:在實際的開發過程當中,若是輪詢多個agent上的MIB OID對象時,可使用異步的多路複用技術來實現。相似代碼以下:
while (active_hosts) {/*輪詢某個AGENT*/
int fds = 0, block = 1;
fd_set fdset;
struct timeval timeout;
FD_ZERO(&fdset);
snmp_select_info(&fds, &fdset, &timeout, &block);
fds = select(fds, &fdset, NULL, NULL, block ? NULL : &timeout);
if (fds < 0) {
perror("select failed");
exit(1);
}
if (fds)
snmp_read(&fdset);
else snmp_timeout();
}
3.2 SNMP agent開發
擴展Agent的開發,NET-SNMP提供了三種方式:
· 動態聯編(此方法須要NET-SNMP的源程序)。
· 動態加載庫。
· 子代理的方式。
接下來將重點描述動態加載庫的方式,其餘的方式我目前尚未去實驗,你們能夠參考其官網上的例子進行。下面的例子將在AGENT中實現,GET/SET的方法接口。
3.2.1
準備
MIB
文件
爲了方便,咱們使用的MIB仍是官網上的
NET-SNMP-TUTORIAL-MIB.txt。
將NET-SNMP-TUTORIAL-MIB.txt拷貝到/usr/local/share/snmp/mibs。
修改/usr/local/share/snmp/snmp.conf,在最後一行增長:mibs +NET-SNMP-TUTORIAL-MIB
或者在SHELL環境變量中定義:export MIBS=+NET-SNMP-TUTORIAL-MIB。
不然在運行程序或作SNMP操做時,會出現MIB沒法找到等錯誤現象。
3.2.2
編譯動態庫
NET-SNMP的usr/local/bin/mib2c工具可以將使用MIB2C工具程序把MIB庫模塊文件轉換成C源代碼。假設MIB庫模塊爲modulename,執行mib2c modulename此時,MIB2C會在當前目錄下生成兩個C源文件:modulename.h 和modulename.c,這兩個文件是根據所設計的MIB庫模塊轉換而成的,也是須要加入到NET-SNMP軟件包實現SNMP Agent功能擴展的源代碼。注意,MIB2C爲PERL腳本編寫,爲了讓PERL支持SNMP,您須要下載PERL CPAN FOR SNMP的包。
Mib2c須要爲-c操做指定一個配置文件,此配置文件感受爲預生成的模板文件,若是要寫scalars則用mib2c.scalar.conf文件,若是要寫Table則用mib2c.mfd.conf,若是帶有TRAP則用mib2c.notify.conf。
%mib2c -c mib2c.scalar.conf nstAgentPluginObject
MIB2C將生成的文件爲
nstAgentPluginObject.c和
nstAgentPluginObject.h文件。
在nstAgentPluginObject.c文件中爲實現SET/GET操做,能夠在switch (reqinfo->mode)下的MODE_SET_COMMIT(SET操做)與MODE_GET(GET操做)實現。
編譯成.so文件:
gcc –I. -c -o nstAgentPluginObject.o nstAgentPluginObject.c
gcc -g -fPIC -shared -o nstAgentPluginObject.so nstAgentPluginObject.o(編譯成SO庫)
3.2.3
加載動態庫
Net-snmp的snmpd加載動態庫以實現agent的擴展有2種加載方式:
(1)不中止SNMPD進程的狀況下加載。
UCD-DLMOD-MIB.txt定義了MIB條目的模塊名,動態庫路徑及狀態。使用此方法能夠在不重起代理的狀況下配置各動態模塊加載與卸載。
其詳細的MIB定義:cat /usr/local/share/snmp/mibs/UCD*DLMOD*.txt。
· 查看哪些.so被加載
#snmpget -v 1 -c public localhost UCD-DLMOD-MIB::dlmodStatus.1
· 嘗試獲取某個MIB的OID值
#Snmpget-v2c -c public localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0
NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0 = No Such Object available on this agent at this OID(其表示沒有找到)
· UCD-DLMOD-MIB表中建立一個模塊實例
#snmpset -v 1 -c private localhost UCD-DLMOD-MIB::dlmodStatus.1 i create
UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: create(6)
· 獲取dlmodStatus值
#snmpget -v 1 -c public localhost UCD-DLMOD-MIB::dlmodStatus.1
UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: unloaded(2)
說明模塊實例已經存在,但沒有被加載
· 設置需裝載模塊的名稱及路徑
#snmpset -v 1 -c private localhost UCD-DLMOD-MIB::dlmodName.1 s \ "nstAgentPluginObject" UCD-DLMOD-MIB::dlmodPath.1 s "/oracle/agent/plugin/nstAgentPluginObject.so"
UCD-DLMOD-MIB::dlmodName.1 = STRING: nstAgentPluginObject
UCD-DLMOD-MIB::dlmodPath.1 = STRING: /oracle/agent/plugin/nstAgentPluginObject.so
· 裝載模塊
# snmpset -v 1 -c private localhost UCD-DLMOD-MIB::dlmodStatus.1 i load
UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: load(4)
· 確認模塊被加載
#snmpget -v 1 -c public localhost UCD-DLMOD-MIB::dlmodStatus.1
UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: loaded(1)
· 測試新加載的.so是否成功
#snmpget -v 1 -c public localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0
NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0 = INTEGER: 3
(2)修改配置文件snmpd.conf加載
在/usr/local/share/snmp/snmpd.conf文件中增長一行:
dlmod nstAgentPluginObject /oracle/agent/plugin/nstAgentPluginObject.so
3.2.4
測試代理
$snmpget -v 1 -c public localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0
NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0 = INTEGER: 123456
$snmpset -v 1 -c private localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0 i 1000
NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0 = INTEGER: 1000
調用設置後,你會發如今/oracle/agent/plugin/test.log中的內容增長一行: 1000 mode=0x3
3.3 Trap的開發
3.3.1
準備MIB
文件
在SNMPV1版本中MIB的TRAP定義與V2版本中不徹底同樣,V2版本開始叫notification。咱們使用比較簡單的V1版原本定義含有TRAP功能的MIB文件
UCD-TRAP-TEST-MIB.txt。
在/usr/local/share/snmp/snmp.conf中增長一行:mibs +UCD-TRAP-TEST-MIB
將UCD-TRAP-TEST-MIB.txt拷貝到/usr/local/share/snmp/mibs目錄中。
3.3.2
Send trap
Trap的發送有幾種實現狀況,用戶能夠用snmp_add_var以及snmp_send等API編寫應用來觸發TRAP事件,也能夠在MIB2C中mib2c.notify.conf配置模板在代理中實現TRAP的發送。發送TRAP的代碼能夠詳細參考
mytrap.c。
編譯:Gcc –o mytrap mytrap.c –lsnmp
執行:./mytrap
3.3.3
啓動SNMPTRAPD
進程
· 修改snmptrapd.conf文件:
修改或產生/usr/loc1的snmptrapd進程默認下不接收任何TRAP,因此須要配置此文件,內容以下:al/share/snmp/snmptrapd.conf文件(在NET-SNMP5.4.1中好象沒有自動生成此文件。)
authCommunity log,execute,net public
· 啓動trapd進程
snmptrapd -P 或者snmptrapd -f -Le
此命令將snmptrapd不作爲後臺進程運行,並將接收到的TRAP信息,以標準輸出設備輸出。
· 接收TRAP
2008-06-27 15:18:53 localhost [UDP: [127.0.0.1]:32787]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1052691) 2:55:26.91 SNMPv2-M
IB::sysLocation.0 = STRING: 我在家。。。 UCD-TRAP-TEST-MIB::demotraps# =
INTEGER: 1230 SNMPv2-MIB::snmpTrapOID.0 = OID: ccitt.1
3.4 程序清單
本文中使用的文件清單以下:
3.5 結束語
接觸NET-SNMP時間較少,因此還有不少內容須要去發現與瞭解,不對之處,歡迎你們多多指正,不勝感激。
在本文中,您已經瞭解了使用 Net-SNMP的大體過程。本文介紹了以下幾個方面:
(1)NET-SNMP的安裝與配置。描述了NET-SNMP的安裝以及配置狀況。
(2)NET-SNMP的get、set、trap的操做。用代碼實踐了使用NET-SNMP API的操做全過程。
(3)使用NET-SNMP如何編寫本身的代理(agent),本文詳細介紹了使用動態庫開發代理的方法,有機會將介紹其餘兩種方法。
SNMP協議自己是很是複雜的,使用NET-SNMP或其餘SNMP的開發包,將使您忽略協議自己的細節,專一應用開發。
|