1. 程式人生 > >網路協議篇之SNMP協議(一)——SNMP報文協議

網路協議篇之SNMP協議(一)——SNMP報文協議

    (前言:最近工作中遇到大量的網路協議開發,現就其中一些網路協議的基礎知識進行整理,文中借鑑了一些大神的整理,後面會貼上鍊接,如侵刪)

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

一套完整的SNMP系統主要包括管理資訊庫(MIB)管理資訊結構(SMI)

SNMP報文協議

我們先來了解一下SNMP報文協議:

一、SNMP協議概述

     簡單網路管理協議(SNMP:Simple Network Management Protocol)是由網際網路工程任務組(IETF:Internet Engineering Task Force )定義的一套網路管理協議。該協議基於簡單閘道器監視協議(SGMP:Simple Gateway Monitor Protocol)。利用SNMP,一個管理工作站可以遠端管理所有支援這種協議的網路裝置,包括監視網路狀態、修改網路裝置配置、接收網路事件警告等。 雖然SNMP開始是面向基於IP的網路管理,但作為一個工業標準也被成功用於電話網路管理。

二、SNMP的工作原理

       SNMP採用特殊的客戶機/伺服器模式,即代理/管理站模型。對網路的管理與維護是通過管理工作站與SNMP代理間的互動工作完成的。每個SNMP從代理負責回答SNMP管理工作站(主代理)關於MIB定義資訊的各種查詢。

SNMP的應用場景如圖所示:


管理站和代理端使用MIB進行介面統一,MIB定義了裝置中的被管理物件。管理站和代理都實現相應的MIB物件,使得雙方可以識別對方的資料,實現通訊。管理站向代理請求MIB中定義的資料,代理端識別後,將管理裝置提供的相關狀態或引數等資料轉換成MIB定義的格式,最後將該資訊返回給管理站,完成一次管理操作。

三、SNMP的報文型別

        SNMP中定義了五種訊息型別:Get-Request、Get-Response、Get-Next-Request、Set-Request和Trap 。

(1)Get-Request 、Get-Next-Request與Get-Response(監視網路狀態)

       SNMP 管理站用Get-Request訊息從擁有SNMP代理的網路裝置中檢索資訊,而SNMP代理則用Get-Response訊息響應。Get-Next- Request用於和Get-Request組合起來查詢特定的表物件中的列元素。

(2)Set-Request (修改網路裝置配置)

SNMP管理站用Set-Request 可以對網路裝置進行遠端配置(包括裝置名、裝置屬性、刪除裝置或使某一個裝置屬性有效/無效等)。

(3)Trap (接收網路事件警告)

       SNMP代理使用Trap向SNMP管理站傳送非請求訊息,一般用於描述某一事件的發生,如介面UP/DOWN,IP地址更改等。

      上面五種訊息中Get-Request、Get-Next-Request和Set-Request是由管理站傳送到代理側的161埠的;後面兩種Get-Response和Trap 是由代理程序發給管理程序的,其中Trap訊息被髮送到管理程序的162埠,所有資料都是走UDP封裝。SNMP工作流程如圖

  

四、SNMP報文格式  

        下圖是封裝成UDP資料報的5種操作的SNMP報文格式。可見一個SNMP報文共有三個部分組成,即公共SNMP首部、get/set首部、trap首部、變數繫結。

1、公共SNMP首部

共三個欄位:

a -- 版本 

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

b -- 共同體(community)

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

c -- PDU型別

      根據PDU的型別,填入0~4中的一個數字,其對應關係如下圖


2、get/set首部

a -- 請求識別符號(request ID)

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

b -- 差錯狀態(error status)

       由代理程序回答時填入0~5中的一個數字,見下圖描述

c -- 差錯索引(error index)

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

3、trap首部

a -- 企業(enterprise)

       填入trap報文的網路裝置的物件識別符號。此物件識別符號肯定是在圖3的物件命名樹上的enterprise結點{1.3.6.1.4.1}下面的一棵子樹上。

b -- trap型別

       此欄位正式的名稱是generic-trap,共分為表4中的7種


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

c -- 特定程式碼(specific-code)

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

d -- 時間戳(timestamp)

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

4、變數繫結(variable-bindings)

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

管理變數的表示

     管理變量表示管理物件型別在某一時刻的值(或稱該型別的例項),SNMP以管理變數作為操作物件。

     管理變數的表示方法是這樣規定的:形如x.y,其中x是管理物件的object identifery是能唯一確定物件型別值的一組數字,在非表型變數中為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、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相同。

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。這個響應通知網管站對錶的遍歷已經完成。

3、GetResponse PDU

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

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。

5、Trap PDU

         Trap PDU的有如下的形式


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