net snmp 開發實踐

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.cnstAgentPluginObject.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的開發包,將使您忽略協議自己的細節,專一應用開發。
相關文章
相關標籤/搜索