1. 程式人生 > >簡單網路管理協議SNMP

簡單網路管理協議SNMP

一、SNMP

SNMP是基於TCP/IP協議族的網路管理標準,是一種應用層協議,是目前網路中應用最廣泛的網路管理協議。SNMP使用客戶/伺服器模型,對應著管理站和代理站。SNMP的核心是幫助管理員簡化一些支援SNMP裝置設定的操作(也包括這些資訊的收集),提供從網路上的裝置中手機網路管理資訊的方法。例如,使用SNMP可以關閉路由器的一個埠,也可以檢視乙太網埠的工作速率。SNMP還可以監控交換機的溫度,在出現過高現象進行報警。SNMP通常和管理路由器相關聯,實際上SNMP可以用於管理很多型別的裝置。

二、基於TCP/IP網路管理的網路管理模組的關鍵部分:

SNMP就是用來規定NMS和Agent之間是如何傳遞資訊管理的應用層協議。

1、網管站(NMS)

網管站通常是一個獨立的裝置,可以是一般桌上型電腦也可以是一臺高效能伺服器,用作網路管理者進行網路管理的使用者介面。基站上必須裝有管理軟體,管理員可以使用的使用者介面和從MIB取得資訊的資料庫。同時為了進行網路管理他應該具有將管理命令發出基站的能力。對網路裝置發出各種查詢報文,並接受來自北管裝置的響應以及陷阱報文,將結果顯示出來。

2、代理站(Agent)

代理站是被管物件,是一種網路裝置,如路由器、主機等,是一在被管網路裝置上執行的軟體模組,裝置出廠時已經開發好並燒錄如裝置上,這些裝置必須能接收管理站發來的資訊,他們的狀態也必須可以有管理站監視。負責接收、處理來自網管站的請求報文,然後從裝置上其他協議模組中取得管理變數的數值,形成響應報文,傳送給NMS。在一些特殊的情況下,如介面狀態發生改變等時候,主動給NMS傳送陷阱報文。

3、管理資訊庫(MIB)

MIB是物件的集合,在其上定義了網路裝置的各項引數,通過對這些引數的讀取和設定來實現對網路裝置的監控。SNMP的管理資訊庫採用和域名系統DNS相似的樹形結構,它的根在最上面,跟沒有名字。

  MIB樹形結構

OID由樹上一系列證書組成,整數間用.分開。例如,OID{1.3.6.1.2.1.1}就表示節點mib-2的子物件system,這個物件內儲存著與網路裝置有關係的系統資訊。

4、管理資訊結構(SMI)

用於定義通過網路管理協議可以訪問物件的規則。定義在MIB中使用的資料型別以及網路資源在MIN中的名稱或表示。

5、SNMP

SNMP為應用層協議,是TCP/IP協議族的一部分。通過使用者資料協議(UDP)來操作。在分立的管理站中,管理者進場對位於管理站中心的MIB的訪問進行控制,並提供網路管理介面。管理者程序通過SNMP完成網路管理。SNMP訊息去全部通過UPD埠161接收,只有trap資訊採用UDP的162埠。

三、SNMP基本原理

在SNMP中使用UDP協議,可能發生管理程序和代理程序之間的資料包丟失的情況,因此一定要有超時和重傳機制。資訊交換有2中觸發方式:一個是管理者以輪詢的方式,另一個是代理程序傳送trap報文。

sNMP的5中基本操作:

GET-REQUEST:從某變數中取值(NSM傳送給Agent)

GET-NEXT_REQUEST:從表格中去下一個值(NSM傳送給Agent)

GET-RESPONSE:響應操作(Agent傳送給NMS)

SET-REQUEST:把數值存入具體變數,可以對網路進行遠端配置,包括備名、裝置屬性等,由管理站設定代理的管理資訊庫的物件值(NSM傳送給Agent)

Trap:報告事件資訊(Agent傳送給NMS)

NMS週期性的傳送GET-REQUEST、GET-NEXT_REQUEST報文來輪詢各個Agent,獲取各個MIB中的管理資訊,NMS也接收Agent傳送來的Trap報文,並記錄在資料庫中。當Agent接收到NMS傳送的Get報文後,將根據請求的內容從本地MIB中提取所需的資訊,並以GET-RESPONSE報文方式將結果回送給NMS。


NMS必須在162埠上偵聽Trap訊息,並通過161埠傳送GET-REQUEST,GET-NET_REQUEST,SET-REQUEST。Agent必須在161埠上偵聽偵聽GET-REQUEST,GET-NEXT_REQUEST,SET-REQUEST訊息的到來,通過162埠傳送Trap,161埠傳送GET-RESPONSE。

四、SNMP++

SNMP++是HP公司開發的,開源的,用於SNMP程式設計的C++庫,把WinSNMP的API函式封裝成相關的C++類,面向物件化,簡化了SNMP開發的複雜性和開發難度。

SNMP++封裝了相關的類:

1、SNMP類

SNMP類是SNMP++中最重要的類,它封裝了SNMP會話和基本的SNMP協議操作(get、getnext、set、trap、getbulk、inform)過程。SNMP類管理通訊:1、在UDP或IPX連線基礎上管理傳輸層;2、負責打包盒解包PDU中的繫結變數;分發和接收PDU;4、管理所有SNMP所需的資源。

2、Address類

所有地址類都派生自這個抽象基類,通過使用虛成員函式,提供了公共介面,可以使用公共介面呼叫各個不同地址類的函式。如IP地址,UDP地址。

3、Oid類

Oid類封裝了SMI的物件標識。通過建構函式和成員函式可以定義和操作OID物件。

4、Vb類

variable Binding class是SNMP“繫結變數”的封裝。一個繫結變數時由SNMP的object ID和SMI的value組合而成的。即:一個Vb物件含有一個oid物件及其SMI的value。可以通過成員函式對繫結變數進行設定和取出。

5、Pdu類

Pdu類是SNMP++類庫對5中協議資料單元PDU做的封裝。是管理端和代理端進行SNMP通訊的基本概念。可以在Pdu物件上載入、解除安裝Vb物件。

6、Snmptarget類

抽象目標類。在SNMP++中SnmpTarget有2個子類:CTarget(基於共同體的目標類,用於SNMPv1和SNMPv2)和UTarget(基於使用者的目標類,用於SNMPv3)。每個target都與一個地址物件關聯。每個target都有重發機制,超時和重發。

五、SNMP程式設計流程

1、呼叫Snmp::socket_startup;//初始化socket子系統

2、建立所需的物件,並初始化

UdpAddress address(“192.168.0.17”);//udp地址

address.set_port(161); //udp地址物件的埠號

Oid oid("1.3.6.1.2.1.1.1.0");//建立Oid物件

Pdu pdu;//建立pdu物件

Vb vb;//建立vb物件

vb.set_oid(oid);//將Oid物件繫結到Vb物件上

pdu+=vb;//將Vb物件新增到Pdu物件的末尾

Ctarget ctarget(address); //利用已建立的address物件建立CTarget物件

ctarget.set_version(version);//設定SNMP版本

ctarget.set_retry(retries);//設定重傳次數

ctarget.set_timeout(timeout);//設定超時時間

ctarget.set_readcommunity(community);//設定共同體

SnmpTarget* target;//建立snmptarget物件指標

target=&ctarget;//將snmptarget物件指標指向Ctargett物件;

Snmp snmp(status);//建立一個snmp++會話

if (status=snmp.get(pdu,target)!=SNMP_CLASS_SUCCESS) //向代理站請求MIB資訊,正常情況下代理程序將傳送一個Getresponse報文,該返回的pdu中將包含變數名和相應值。

cout<<snmp.error_msg(status);

else{

pdu.get_vb(vb,0); //取出pdu中vb繫結的

cout<<“oid=”<<vb.get_printable_oid();

cout<<value<<vb.get_printable-value();

}

六、接收Trap

#include “snmp_pp.h”  //-----------------[ trap callback function definition]-------------------------------------------------------------------  
void my_trap_callback ( 
int reason,                // reason                     
Snmp* session,            // session handle                     
Pdu & pdu,               // trap pdu                    
TimeTicks &timestamp,     // timestamp                     
SnmpTarget &target,       // source of the trap                     
void * cbd)               // optional callback data 
{     
Address *address;     
unsigned char get_cummunity[80], set_community[80];   
unsigned long timeout;    
int retry;       
if ( reason == SNMP_CLASS_TRAP) 
{         
target.resolve_to_C( 
get_community,            // get community                          
set_community,    // set community                         
 &address,             // address object                         
 timeout,             // timeout                    
 retry);                // retry         
cout << “Trap Received from << address->get_printable() << “Trap Id = “ << trapid.get_printable(); 
   }   
else       
 cout << “Trap Receive Error = “ << session->error_msg( reason);   
};    


//---------------[ trap receive register ]---------------------------------------------------------------------  
Snmp *snmp;                         // dynamic Snmp object 
void trap_register()
 {     //----------------[ instantiate an Snmp object, delete when no longer receiving traps ]------------ 

 int status; 

    snmp = new Snmp( status); 

   if (( snmp == NULL) || ( status != SNMP_CLASS_SUCCESS))      

cout << “Error constructing Snmp Object\n”;    else    { 

      //-------[ set up two empty collections, empty denotes receive all ]------------------------------- 

  TargetCollection targets;            

OidCollection trapids; 

      //------[ invoke the regsiter ]----------------------

if ( status = snmp->notify_register( trapids, targets, & my_trap_callback)) != SNMP_CLASS_SUCCESS)

cout << “ Snmp Trap Register Error “ << snmp->error_msg( status);
}
   

參考:

SNMP++官方文件http://www.agentpp.com/doc_snmp++3.x/index.html

陳雲昊翻譯的SNMP++中文說明資料

 基於SNMP_類庫的簡單網路管理平臺的實現_周志成