檢視原始碼 MIB 編譯器

本章節MIB 編譯器描述了 MIB 編譯器,並包含以下主題:

  • 操作
  • 匯入
  • MIB 之間的相容性檢查
  • .hrl 檔案產生
  • Emacs 整合
  • 與標準的偏差

注意

匯入 MIB 時,請確保匯入的 MIB 以及進行匯入的 MIB 都是使用相同版本的 SNMP 編譯器進行編譯的。

操作

MIB 必須先以 ASN.1 表示法,以 SMIv1 或 SMIv2 的文字檔格式撰寫,才能進行編譯。此文字檔必須與 MIB 同名,但加上 .mib 副檔名。這對於處理 IMPORT 陳述式是必要的。

關聯檔案,其中包含 MIB 的儀器函數名稱,應該使用 .funcs 副檔名。如果編譯器找不到關聯檔案,它會給出警告訊息並使用預設的儀器函數。(有關更多詳細信息,請參閱預設儀器)。

MIB 編譯器通過呼叫 snmpc:compile(<mibname>). 來啟動。例如:

snmpc:compile("RFC1213-MIB").

輸出是一個名為 <mibname>.bin 的新檔案。

MIB 編譯器理解 SMIv1 和 SMIv2 MIB。它使用 MODULE-IDENTITY 陳述式來確定 MIB 是以 SMI 版本 1 還是 2 撰寫。

匯入 MIB

編譯器會處理 IMPORT 陳述式。重要的是匯入已編譯的檔案,而不是 ASN.1 (來源) 檔案。必須重新編譯 MIB,才能讓其他匯入它的 MIB 看見變更。

匯入的 MIB 編譯檔案必須存在於目前目錄,或目前路徑中的目錄。路徑使用 {i, Path} 選項提供,例如:

snmpc:compile("MY-MIB",
       [{i, ["friend_mibs/", "../standard_mibs/"]}]).

也可以使用 il 選項,以類似 "include_lib" 的方式從 OTP 應用程式匯入 MIB。範例:

snmpc:compile("MY-MIB",
       [{il, ["snmp/priv/mibs/", "myapp/priv/mibs/"]}]).

在 OTP 系統中找到 snmpmyapp 應用程式的最新版本,並使用展開的路徑作為包含路徑。

請注意,SMIv2 MIB 可以匯入 SMIv1 MIB,反之亦然。

以下 MIB 是 Erlang SNMP 編譯器的內建模組:SNMPv2-SMI、RFC-1215、RFC-1212、SNMPv2-TC、SNMPv2-CONF 和 RFC1155-SMI。因此,它們不能單獨編譯。

MIB 相容性檢查

編譯 MIB 時,編譯器會偵測是否有數個受管理物件使用相同的 OBJECT IDENTIFIER。如果是這種情況,它會發出錯誤訊息。但是,編譯器無法偵測不同 MIB 之間的 Oid 衝突。這些衝突會在載入時產生錯誤。為了避免這種情況,可以使用以下函式來執行 MIB 之間的相容性檢查:


erl>snmpc:is_consistent(ListOfMibNames).

ListOfMibNames 是已編譯 MIB 的清單,例如 ["RFC1213-MIB", "MY-MIB"]。該函式還會執行陷阱定義的相容性檢查。

.hrl 檔案產生

可以從已編譯的 MIB 檔案產生一個 .hrl 檔案,其中包含 Erlang 常數的定義。然後,可以將此檔案包含在 Erlang 原始程式碼中。該檔案將包含下列常數:

  • 表格、表格項目和變數的物件識別碼
  • 欄號
  • 列舉值
  • 變數和表格欄的預設值。

使用以下命令從 MIB 產生 .hrl 檔案:

erl>snmpc:mib_to_hrl(MibName).

Emacs 整合

使用 Emacs 編輯器,next-error (C-X `) 函式可以用來指示發生編譯錯誤的位置,前提是錯誤訊息由行號描述。

使用 M-x compile 從 Emacs 內部編譯 MIB,並輸入:

 erl -s snmpc compile <MibName> -noshell

<MibName> 的範例是 RFC1213-MIB

從 Shell 或 Makefile 編譯

可以使用 erlc 命令來編譯 SNMP MIB。範例:

 erlc MY-MIB.mib

支援所有標準 erlc 標誌,例如:

 erlc -I mymibs -o mymibs -W MY-MIB.mib

可以使用 + 語法來指定 MIB 編譯器特定的標誌:

 erlc +'{group_check,false}' MY-MIB.mib

與標準的偏差

在某些方面,Erlang MIB 編譯器並未完全遵循或實作 SMI。以下是差異:

  • 表格必須按以下順序撰寫:tableObjectentryObjectcolumn1、...、columnN (依序)。
  • 整數值,例如在 SIZE 表達式中,必須以十進制語法輸入,而不是十六進制或位元語法。
  • 符號名稱在 MIB 內和系統內必須是唯一的。
  • 在 SMIv2 中允許使用連字符號(一種務實的方法)。這樣做的原因是,根據 SMIv2,連字符號允許用於從 SMIv1 轉換而來的物件,但不允許用於其他物件。編譯器無法檢查這一點。
  • 如果某個詞是 SMIv1 或 SMIv2 中任何一個的關鍵字,則它在編譯器中也是關鍵字(僅與 SMIv1 偏差)。
  • 表格中的索引必須是物件,而不是類型(僅與 SMIv1 偏差)。
  • 實作了類型上所有語意檢查的一個子集。例如,嚴格來說,TimeTicks 可能無法子類化,但編譯器允許這樣做(標準 MIB 必須通過編譯器)(僅與 SMIv2 偏差)。
  • 未實作 MIB.Object 語法(因為無論如何所有物件都必須是唯一的)。
  • 兩個不同的名稱不能定義相同的 OBJECT IDENTIFIER。
  • SEQUENCE 建構中的類型檢查是非嚴格的(即可以指定子類型)。這樣做的原因是某些標準 MIB 會使用它。
  • 定義通常具有一個狀態欄位。當狀態欄位的值為 deprecated 時,MIB 編譯器將會忽略此定義。使用 MIB 編譯器選項 {deprecated,true} 時,MIB 編譯器不會忽略已棄用的定義。
  • 物件具有 DESCRIPTIONS 欄位。預設情況下,描述欄位不會包含在已編譯的 mib 中。為了取得描述,必須使用選項 description 編譯 mib。