網絡:SNMP協議詳解

簡單網絡管理協議(SNMP)是TCP/IP協議簇的一個應用層協議。在1988年被制定,並被Internet體系結構委員會(IAB)採納作為一個短期的網絡管理解決方案;由於SNMP的簡單性,在Internet時代得到了蓬勃的發展,1992年發佈了SNMPv2版本,以增強SNMPv1的安全性和功能。現在,已經有了SNMPv3版本。

一套完整的SNMP系統主要包括管理信息庫(MIB)、管理信息結構(SMI)及SNMP報文協議。

(1)管理信息庫MIB:任何一個被管理的資源都表示成一個對象,稱為被管理的對象。MIB是被管理對象的集合。它定義了被管理對象的一系列屬性:對象的名稱、對象的訪問權限和對象的數據類型等。每個SNMP設備(Agent)都有自己的MIB。MIB也可以看作是NMS(網管系統)和Agent之間的溝通橋樑。它們之間的關係如圖1所示。


網絡:SNMP協議詳解


      圖1 NMS Agent和MIB的關係

MIB文件中的變量使用的名字取自ISO和ITU管理的對象標識符(object identifier)名字空間。它是一種分級樹的結構。如圖2所示,第一級有三個節點:ccitt、iso、iso-ccitt。低級的對象ID分別由相關組織分配。一個特定對象的標識符可通過由根到該對象的路徑獲得。一般網絡設備取iso節點下的對象內容。如名字空間ip結點下一個名字為ipInReceives的MIB變量被指派數字值3,因而該變量的名字為:

iso.org.dod.internet.mgmt.mib.ip.ipInReceives

相應的數字表示(對象標識符OID,唯一標識一個MIB對象)為:

1.3.6.1.2.1.4.3

snmps樹


網絡:SNMP協議詳解


                       圖2 MIB樹結構

當網絡管理協議在報文中使用MIB變量時,每個變量名後還要加一個後綴,以作為該變量的一個實例。如ipInReceives的實例數字表示為:1.3.6.1.2.1.4.3.0.

需要注意的是,MIB中的管理對象的OID有些需要動態確定,如IP路由表,為了指明地址202.120.86.71的下一站路由(next hop),我們可以引用這樣的實例:

iso.org.dod.internet.mgmt.mib.ip. ipRouteTable.ipRouteEntry.ipRouteNextHop.202.120.86.71, 相應的數字表示為:1.3.6.1.2.1.4.21.1.7.202.120.86.71

對於這種動態對象標識的實例,由於無法轉換為預先指定的Readkey名稱,與飛鄰的產品架構衝突(需要動態生成可變Readkey),暫不考慮支持。

(2)管理信息結構(SMI)

SMI定義了SNMP框架所用信息的組織、組成和標識,它還為描述MIB對象和描述協議怎樣交換信息奠定了基礎。

SMI定義的數據類型:

◆ 簡單類型(simple)

Integer:整型是-2,147,483,648~2,147,483,647的有符號整數

octet string: 字符串是0~65535個字節的有序序列

OBJECT IDENTIFIER: 來自按照ASN.1規則分配的對象標識符集

◆ 簡單結構類型(simple-constructed)

SEQUENCE 用於列表。這一數據類型與大多數程序設計語言中的“structure”類似。一個SEQUENCE包括0個或更多元素,每一個元素又是另一個ASN.1數據類型

SEQUENCE OF type 用於表格。這一數據類型與大多數程序設計語言中的“array”類似。一個表格包括0個或更多元素,每一個元素又是另一個ASN.1數據類型。

◆ 應用類型(application-wide)

IpAddress: 以網絡序表示的IP地址。因為它是一個32位的值,所以定義為4個字節;

counter:計數器是一個非負的整數,它遞增至最大值,而後回零。在SNMPv1中定義的計數器是32位的,即最大值為4,294,967,295;

Gauge :也是一個非負整數,它可以遞增或遞減,但達到最大值時保持在最大值,最大值為232-1;

time ticks:是一個時間單位,表示以0.01秒為單位計算的時間;

SNMP報文

SNMP報文結構如下:(編碼之前)

版本號


團體名


協議數據單元PDU



SNMP共有5種報文,所以其PDU也有5中,第七點會詳細介紹SNMP的5種協議數據單元。

1 SNMP的5種協議數據單元

SNMP規定了5種協議數據單元PDU(也就是SNMP報文),用來在管理進程和代理之間的交換。

get-request操作:從代理進程處提取一個或多個參數值。

get-next-request操作:從代理進程處提取緊跟當前參數值的下一個參數值。

set-request操作:設置代理進程的一個或多個參數值。

get-response操作:返回的一個或多個參數值。這個操作是由代理進程發出的,它是前面三種操作的響應操作。trap操作:代理進程主動發出的報文,通知管理進程有某些事情發生。

前面的3種操作是由管理進程向代理進程發出的,後面的2個操作是代理進程發給管理進程的,為了簡化起見,前面3個操作今後叫做get、get-next和set操作。圖1描述了SNMP的這5種報文操作。請注意,在代理進程端是用熟知端口161倆接收get或set報文,而在管理進程端是用熟知端口162來接收trap報文。

snmp報文轉發流程


圖1 SNMP的5種報文操作

圖2是封裝成UDP數據報的5種操作的SNMP報文格式。可見一個SNMP報文共有三個部分組成,即公共SNMP首部、get/set首部、trap首部、變量綁定。

snmp報文格式PDU

(1)公共SNMP首部

共三個字段:

 版本

寫入版本字段的是版本號減1,對於SNMP(即SNMPV1)則應寫入0。

 共同體(community)

共同體就是一個字符串,作為管理進程和代理進程之間的明文口令,常用的是6個字符“public”。

 PDU類型

根據PDU的類型,填入0~4中的一個數字,其對應關係如表2所示意圖。

表2 PDU類型

PDU類型

名稱

0

get-request

1

get-next-request

2

get-response

3

set-request

4

trap

(2)get/set首部

 請求標識符(request ID)

這是由管理進程設置的一個整數值。代理進程在發送get-response報文時也要返回此請求標識符。管理進程可同時向許多代理發出get報文,這些報文都使用UDP傳送,先發送的有可能後到達。設置了請求標識符可使管理進程能夠識別返回的響應報文對於哪一個請求報文

 差錯狀態(error status)

由代理進程回答時填入0~5中的一個數字,見表3的描述

表3 差錯狀態描述

差錯狀態

名字

說明

0

noError

一切正常

1

tooBig

代理無法將回答裝入到一個SNMP報文之中

2

noSuchName

操作指明瞭一個不存在的變量

3

badValue

一個set操作指明瞭一個無效值或無效語法

4

readOnly

管理進程試圖修改一個只讀變量

5

genErr

某些其他的差錯

 差錯索引(error index)

當出現noSuchName、badValue或readOnly的差錯時,由代理進程在回答時設置的一個整數,它指明有差錯的變量在變量列表中的偏移。

(3)trap首部

 企業(enterprise)

填入trap報文的網絡設備的對象標識符。此對象標識符肯定是在圖3的對象命名樹上的enterprise結點{1.3.6.1.4.1}下面的一棵子樹上。

 trap類型

此字段正式的名稱是generic-trap,共分為表4中的7種。

trap類型

名字

說明

0

coldStart

代理進行了初始化

1

warmStart

代理進行了重新初始化

2

linkDown

一個接口從工作狀態變為故障狀態

3

linkUp

一個接口從故障狀態變為工作狀態

4

authenticationFailure

從SNMP管理進程接收到具有一個無效共同體的報文

5

egpNeighborLoss

一個EGP相鄰路由器變為故障狀態

6

enterpriseSpecific

代理自定義的事件,需要用後面的“特定代碼”來指明

當使用上述類型2、3、5時,在報文後面變量部分的第一個變量應標識響應的接口。

 特定代碼(specific-code)

指明代理自定義的時間(若trap類型為6),否則為0。

 時間戳(timestamp)

指明自代理進程初始化到trap報告的事件發生所經歷的時間,單位為10ms。例如時間戳為1908表明在代理初始化後1908ms發生了該時間。

(4)變量綁定(variable-bindings)

指明一個或多個變量的名和對應的值。在get或get-next報文中,變量的值應忽略。

管理變量的表示

管理變量表示管理對象類型在某一時刻的值(或稱該類型的實例),SNMP以管理變量作為操作對象。

管理變量的表示方法是這樣規定的:形如x.y,其中x是管理對象的object identifer。y是能唯一確定對象類型值的一組數字,在非表型變量中為0,在表型變量中是這個表的索引,比如接口表中的接口號,或路由表中的目的網絡地址等等 。如:在MIB文件裡定義了ipAdEntNetMask這一管理對象,其object identifier為1.3.6.1.1.5.6.1.3它是個路由表中的一項,它的一個實例就是路由表中某一行的子網掩碼,如果這行的索引、目的網絡地址為129.102.1.0。則這個變量名是:1.3.6.1.1.5.6.1.3.129.102.1.0。在以後的說明中,為了方便,把唯一確定管理變量的一組數字,也就是x.y中的y稱作實例。

SNMP的運行過程

駐留在被管設備上的AGENT從UDP端口161接受來自網管站的串行化報文,經解碼、團體名驗證、分析得到管理變量在MIB樹中對應的節點,從相應的模塊中得到管理變量的值,再形成響應報文,編碼發送回網管站。網管站得到響應報文後,再經同樣的處理,最終顯示結果。

下面根據RFC1157詳細介紹Agent接受到報文後採取的動作:

首先解碼生成用內部數據結構表示的報文,解碼依據ASN.1的基本編碼規則,如果在此過程中出現錯誤導致解碼失敗則丟棄該報文,不做進一步處理。

第二步:將報文中的版本號取出,如果與本Agent支持的SNMP版本不一致,則丟棄該報文,不做進一步處理。當前北研的數據通信產品只支持SNMP版本1。

第三步:將報文中的團體名取出,此團體名由發出請求的網管站填寫。如與本設備認可的團體名不符,則丟棄該報文,不做進一步處理,同時產生一個陷阱報文。SNMPv1只提供了較弱的安全措施,在版本3中這一功能將大大加強。

第四步:從通過驗證的ASN.1對象中提出協議數據單元PDU,如果失敗,丟棄報文,不做進一不處理。否則處理PDU,結果將產生一個報文,該報文的發送目的地址應同收到報文的源地址一致。

根據不同的PDU,SNMP協議實體將做不同的處理:

1.1 GetRequest PDU

第一種情況:如果PDU中的變量名在本地維護的MIB樹中不存在,則接受到這個PDU的協議實體將向發出者發送一個GetResponse報文,其中的PDU與源PDU只有一點不同:將ERROR-STATUS置為noSuchName,並在ERROR-INDEX中指出產生該變量在變量LIST中的位置。

第二種情況:如果本地協議實體將產生的響應報文的長度大於本地長度限制,將向該PDU的發出者發送一個GetResponse報文,該PDU除了ERROR-STATUS置為tooBig,ERROR-INDEX置為0以外,與源PDU相同。

第三種情況:如果本地協議實體因為其他原因不能產生正確的響應報文,將向該PDU的發出者發送一個GetResponse報文,該PDU除了ERROR-STATUS置為genErr,ERROR-INDEX置為出錯變量在變量LIST中的位置,其餘與源PDU相同。

第四中情況:如果上面的情況都沒有發生,則本地協議實體向該PDU的發出者發送一個GetResponse報文,該PDU中將包含變量名和相應值的對偶表,ERROR-STATUS為noError,ERROR-INDEX為0,request-id域的值應與收到PDU的request-id相同。

1.2 GetNextRequest PDU

GetNextRequest PDU的最重要的功能是表的遍歷,這種操作受到了前面所說的管理變量的表示方法的支持,從而可以訪問一組相關的變量,就好象他們在一個表內。

下面通過一個例子解釋表遍歷的過程:

被管設備維護如下路由表:

Destination NextHop Metric

10.0.0.99 89.1.1.42 5

9.1.2.3 99.0.0.3 3

10.0.0.51 89.1.1.42 5

假設網管站欲取得這張路由表的信息,該表的索引是目的網絡地址。

網管站向被管設備發送一個GetNextRequest PDU,其中的受管對象的標識如下

GetNextRequest ( ipRouteDest, ipRouteNextHop, ipRouteMetric1 )

SNMP agent響應如下GetResponse PDU:

GetResponse (( ipRouteDest.9.1.2.3 = "9.1.2.3" ),

( ipRouteNextHop.9.1.2.3 = "99.0.0.3" ),

( ipRouteMetric1.9.1.2.3 = 3 ))

網管站繼續:

GetNextRequest ( ipRouteDest.9.1.2.3,

ipRouteNextHop.9.1.2.3,

ipRouteMetric1.9.1.2.3 )

agent響應:

GetResponse (( ipRouteDest.10.0.0.51 = "10.0.0.51" ),

( ipRouteNextHop.10.0.0.51 = "89.1.1.42" ),

( ipRouteMetric1.10.0.0.51 = 5 ))

值得注意的是agent必須能夠確定下一個管理變量名,以保證所有變量能被取到且只被取到一次。

網管站繼續:

GetNextRequest ( ipRouteDest.10.0.0.51,

ipRouteNextHop.10.0.0.51,

ipRouteMetric1.10.0.0.51 )

agent 響應:

GetResponse (( ipRouteDest.10.0.0.99 = "10.0.0.99" ),

( ipRouteNextHop.10.0.0.99 = "89.1.1.42" ),

( ipRouteMetric1.10.0.0.99 = 5 ))

網管站繼續

GetNextRequest ( ipRouteDest.10.0.0.99,

ipRouteNextHop.10.0.0.99,

ipRouteMetric1.10.0.0.99 )

這時因為路由表中所有的行都被取遍,agent因返回路由表對象的下一字典後繼即該管理對象在MIB樹中的後序遍歷的直接後繼。這裡應是nettoMediaIndex,管理對象的OBJECT IDENTIFIER。這個響應通知網管站對錶的遍歷已經完成。

1.3 GetResponse PDU

GetResponse PDU只有當受到getRequest GetNextRequest SetRequest才由協議實體產生,網管站收到這個PDU後,應顯示其結果。

1.4 SetRequest PDU

SetRequest PDU除了PDU類型標識以外,和GetRequest相同,當需要對被管變量進行寫操作時,網管站側的協議實體將生成該PDU。

對SetRequest的響應將根據下面情況分別處理:

如果是關於一個只讀變量的設置請求,則收到該PDU的協議實體產生一個GetReponse報文,並置error status為noSuchName, error index的值是錯誤變量在變量list中的位置。

如果被管設備上的協議實體收到的PDU中的變量對偶中的值,類型、長度不符和要求,則收到該PDU的協議實體產生一個GetReponse報文,並置error status為badValue, error index的值是錯誤變量在變量list中的位置。

如果需要產生的GetReponse報文長度超過了本地限制,則收到該PDU的協議實體產生一個GetReponse報文,並置error status為tooBig, error index的值是0。

如果是其他原因導致SET失敗,則收到該PDU的協議實體產生一個GetReponse報文,並置error status為genErr, error index的值是錯誤變量在變量list中的位置。

如果不符合上面任何情況,則agent將把管理變量設置收到的PDU中的相應值,這往往可以改變被管設備的運行狀態。同時產生一個GetResponse PDU,其中error status置為noError,error index的值為0。

1.5 Trap PDU

Trap PDU的有如下的形式

產生trap的系統的OBJECT IDENTIFIER

系統的IP地址

普通類型

特定類型

時戳

變量對偶表

Trap是被管設備遇到緊急情況時主動向網管站發送的消息。網管站收到trap PDU後要將起變量對偶表中的內容顯示出來。一些常用的trap類型有冷、熱啟動,鏈路狀態發生變化等。

關於SNMP的報文編碼請參考:SNMP協議 PDU報文格式分析(BER編碼)

這是我的一個拿手好文,可惜格式轉換有點問題!懶得處理了。


分享到:


相關文章: