簡單網路管理協議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 ×tamp, // 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_類庫的簡單網路管理平臺的實現_周志成