檢視原始碼 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 系統中找到 snmp
和 myapp
應用程式的最新版本,並使用展開的路徑作為包含路徑。
請注意,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。以下是差異:
- 表格必須按以下順序撰寫:
tableObject
、entryObject
、column1
、...、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。