本模塊實現了簡單網絡管理協議(SNMP)的一、2c和3版本。node
該模塊使用node package manager (npm)安裝。git
npm install net-snmp
It is loaded using the require()
function:數據庫
var snmp = require ("net-snmp");
而後能夠建立到遠程主機的會話,並用於執行SNMP請求和發送SNMP陷阱或通知。npm
var session = snmp.createSession ("127.0.0.1", "public"); var oids = ["1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.1.6.0"]; session.get (oids, function (error, varbinds) { if (error) { console.error (error); } else { for (var i = 0; i < varbinds.length; i++) if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])) else console.log (varbinds[i].oid + " = " + varbinds[i].value); } session.close (); }); session.trap (snmp.TrapType.LinkDown, function (error) { if (error) console.error (error); });
RFC 3413 describes five types of SNMP applications:json
該庫提供了一個Session
類,爲創建 "命令生成器 "和 "通知發起者 "SNMP應用程序提供支持。數組
全部的SNMP請求都是使用Session
類的實例進行的。本模塊輸出兩個函數,用於建立Session
類的實例。安全
createSession()
- for v1 and v2c sessionscreateV3Session()
- for v3 sessionscreateSession()
函數實例化並返回一個SNMPv1或SNMPv2c的Session
類實例。網絡
// Default options var options = { port: 161, retries: 1, timeout: 5000, backoff: 1.0, transport: "udp4", trapPort: 162, version: snmp.Version1, backwardsGetNexts: true, idBitsSize: 32 }; var session = snmp.createSession ("127.0.0.1", "public", options);
可選的target
參數默認爲127.0.0.1
。可選的 "community "參數默認爲 "public"。可選的options
參數是一個對象,能夠包含如下項目。session
port
- 發送請求的UDP端口,默認爲161
。sourceAddress
----SNMP請求應來自的IP地址,該選項沒有默認值,操做系統將在發送SNMP請求時選擇一個適當的源地址。sourcePort
- UDP端口,SNMP請求應從該端口發出,默認爲操做系統選擇的短暫端口。timeout
-- -- 在從新嘗試或失敗以前等待響應的毫秒數,默認值爲5000
。transport
-- -- 指定要使用的傳輸,能夠是udp4
或udp6
,默認爲udp4
。trapPort
-- -- 發送陷阱和通知的UDP端口,默認值爲162
。version
- snmp.Version1
或snmp.Version2c
,默認爲snmp.Version1
。idBitsSize
- 16
或32
,默認爲32
。用來減小生成的id的大小,以便與一些舊設備兼容。當一個會話結束後,應該關閉它。數據結構
session.close ();
createV3Session()
函數實例化並返回一個與createSession()
相同的Session
類實例,只是爲SNMPv3進行了初始化。
// Default options for v3 var options = { port: 161, retries: 1, timeout: 5000, transport: "udp4", trapPort: 162, version: snmp.Version3, idBitsSize: 32, context: "" }; // Example user var user = { name: "blinkybill", level: snmp.SecurityLevel.authPriv, authProtocol: snmp.AuthProtocols.sha, authKey: "madeahash", privProtocol: snmp.PrivProtocols.des, privKey: "privycouncil" }; var session = snmp.createV3Session ("127.0.0.1", user, options);
target
和user
參數是強制性的。可選的 "options "參數與 "createSession() "調用的含義相同。選項參數中一個額外的字段是context
字段,它爲會話添加一個SNMPv3上下文。
user
對象必須包含name
和level
字段。level
字段能夠從snmp.SecurityLevel
對象中取值。
snmp.SecurityLevel.noAuthNoPriv
- 不進行消息認證或加密。snmp.SecurityLevel.authNoPriv
-- -- 用於信息認證,不進行加密。snmp.SecurityLevel.authPriv
-- -- 用於信息認證和加密。這些字段的含義符合RFC3414的規定。若是提供的 "level "是 "authNoPriv "或 "authPriv",那麼 "authProtocol "和 "authKey "字段也必須存在。authProtocol
字段能夠從snmp.AuthProtocols
對象中取值。
snmp.AuthProtocols.md5
- 用於MD5消息認證。若是提供的 "level "是 "authPriv",那麼 "privProtocol "和 "privKey "字段也必須存在。privProtocol
字段能夠從snmp.PrivProtocols
對象中取值。
snmp.PrivProtocols.des
- 用於DES加密。一旦建立了v3會話,就可使用與v1和v2c相同的一組 "會話 "方法。
當會話的底層UDP套接字被關閉時,會話會發出 "close "事件。
沒有參數傳遞給回調。
在該事件發出以前,全部未完成的請求都會被取消,致使每一個未完成的請求失敗。傳回給每一個請求的錯誤將是一個Error
類的實例,其錯誤message
屬性設置爲Socket forcibly closed
。
下面的例子是當一個會話的底層UDP套接字被關閉時,打印一條消息到控制檯。
session.on ("close", function () { console.log ("socket closed"); });
當會話的底層UDP套接字發出錯誤時,會話會發出 "error "事件。
如下參數將被傳遞給 "回調 "函數。
error
- Error
類的一個實例,暴露的message
屬性將包含一個詳細的錯誤信息。下面的例子是當一個會話的底層UDP套接字發生錯誤時,打印一條消息到控制檯,而後關閉該會話。
session.on ("error", function (error) { console.log (error.toString ()); session.close (); });
close()
方法關閉UDP套接字的底層會話。這將致使會話底層UDP套接字發出 "close "事件,並傳遞給會話,致使會話也發出 "close "事件。
下面的例子關閉了一個UDP套接字底層會話。
session.close ();
get()
方法獲取一個或多個OID的值。
oids
參數是一個OID字符串數組。一旦請求完成,callback
函數就會被調用。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。varbinds
- varbinds數組,若是發生錯誤將不提供。varbinds
數組中位置N的varbind將對應於請求中oids
數組中位置N的OID。
當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
如下示例獲取sysName(1.3.6.1.2.1.1.5.0
)和sysLocation(1.3.6.1.2.1.1.6.0
)OIDs的值。
var oids = ["1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.1.6.0"]; session.get (oids, function (error, varbinds) { if (error) { console.error (error.toString ()); } else { for (var i = 0; i < varbinds.length; i++) { // for version 1 we can assume all OIDs were successful console.log (varbinds[i].oid + "|" + varbinds[i].value); // for version 2c we must check each OID for an error condition if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } } });
getBulk()
方法獲取MIB樹中一個或多個OID後按詞法排列的OID的值。
oids
參數是一個OID字符串的數組。可選的nonRepeaters
參數指定oids
參數中只應返回1個varbind的OID的數量,默認爲0
。對於oids
參數中剩餘的每個OID,可選的maxRepetitions
參數指定了一個OID後面的詞法OID的數量,對於這些OID,varbind應該被獲取,默認值爲20
。
一旦請求完成,callback
函數就會被調用。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。varbinds
- varbinds數組,若是發生錯誤將不提供。varbinds
數組中N位置的varbind將與請求中oids
數組中N位置的OID相對應。
對於varbinds
中的第一個nonRepeaters
項目,每一個項目將是一個單一的varbind。對於varbinds
中全部剩餘的項目,每一個項目將是一個varbinds數組--這使得將響應的varbinds與請求的OID綁定起來很容易,由於響應的varbinds被分組並放在varbinds
中的相同位置。
當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
下面的例子獲取sysContact(1.3.6.1.2.1.4.0
)和sysName(1.3.6.1.2.1.5. 0
)OID,以及ifTable(1.3.6.1.2.1.2.1.2
)表中ifDescr(1.3.6.1.2.1.2.1.2
)和ifType(1.3.6.1.2.1.2.1.3
)列中最多前20個OID。
var oids = [ "1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.2.2.1.2", "1.3.6.1.2.1.2.2.1.3" ]; var nonRepeaters = 2; session.getNext (oids, nonRepeaters, function (error, varbinds) { if (error) { console.error (error.toString ()); } else { // step through the non-repeaters which are single varbinds for (var i = 0; i < nonRepeaters; i++) { if (i >= varbinds.length) break; if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } // then step through the repeaters which are varbind arrays for (var i = nonRepeaters; i < varbinds.length; i++) { for (var j = 0; j < varbinds[i].length; j++) { if (snmp.isVarbindError (varbinds[i][j])) console.error (snmp.varbindError (varbinds[i][j])); else console.log (varbinds[i][j].oid + "|" + varbinds[i][j].value); } } });
getNext()
方法獲取MIB樹中一個或多個OID後按詞法排列的OID的值。
oids
參數是一個OID字符串的數組。一旦請求完成,就會調用callback
函數。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。varbinds
- varbinds數組,若是發生錯誤將不提供。varbinds
數組中位置N的varbind將對應於請求中oids
數組中位置N的OID。
當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
下面的例子獲取sysObjectID(1.3.6.1.1.2.1.1.0
)和sysName(1.3.6.1.1.2.1.4.0
)OID以後的下一個OID的值。
var oids = [ "1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.4.0" ]; session.getNext (oids, function (error, varbinds) { if (error) { console.error (error.toString ()); } else { for (var i = 0; i < varbinds.length; i++) { // for version 1 we can assume all OIDs were successful console.log (varbinds[i].oid + "|" + varbinds[i].value); // for version 2c we must check each OID for an error condition if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } } });
inform()
方法發送一個SNMP信息。
typeOrOid
參數能夠是兩種類型之一:snmp.TrapType
對象中定義的常量之一(不包括snmp.TrapType.EnterpriseSpecific
常量),或者是一個OID字符串。
在請求消息中放置的第一個varbind將是sysUptime.0
OID(1.3.6.1.2.1.1.3.0
)。這個varbind的值將是process.uptime()
函數返回的值乘以100(這能夠經過在可選的options
參數中提供upTime
來覆蓋,以下文所述)。
這以後會有第二個varbind的snmpTrapOID.0
OID (1.3.6.1.6.3.1.1.4.1.0
)。這個值取決於typeOrOid
參數。若是指定了一個常量,那麼常量的陷阱OID將被用來做爲varbinds的值,不然指定的OID字符串將被用來做爲varbind的值。
可選的 "varbinds "參數是要包含在信息請求中的varbinds數組,默認爲空數組[]
。
可選的options
參數是一個對象,能夠包含如下項目。
upTime
- inform中sysUptime.0
OID(1.3.6.1.2.1.1.3.0
)的值,默認爲process.uptime()
函數返回的值乘以100。一旦收到對信息請求的答覆或發生錯誤,就會調用 "回調 "函數。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。varbinds
- varbinds數組,若是發生錯誤將不提供。varbinds
數組中N位置的varbind將與請求中varbinds
數組中N位置的varbind相對應。遠程主機應該按照請求中的指定回傳varbinds和它們的值,varbinds
數組將包含遠程主機發回的每一個varbind。
一般沒有理由使用varbinds
參數的內容,由於varbinds是在請求中發送的。
下面的例子發送了一個通用的冷啓動信息給遠程主機,它不包含任何varbinds。
session.inform (snmp.TrapType.ColdStart, function (error) { if (error) console.error (error); });
下面的例子是向遠程主機發送一個企業特定的信息,幷包含兩個企業特定的varbinds。
var informOid = "1.3.6.1.4.1.2000.1"; var varbinds = [ { oid: "1.3.6.1.4.1.2000.2", type: snmp.ObjectType.OctetString, value: "Periodic hardware self-check" }, { oid: "1.3.6.1.4.1.2000.3", type: snmp.ObjectType.OctetString, value: "hardware-ok" } ]; // Override sysUpTime, specfiying it as 10 seconds... var options = {upTime: 1000}; session.inform (informOid, varbinds, options, function (error) { if (error) console.error (error); });
set()
方法設置一個或多個OID的值。
varbinds
參數是一個varbind對象的數組。一旦請求完成,就會調用callback
函數。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。varbinds
- varbinds數組,若是發生錯誤將不提供。varbinds
數組中N位置的varbind將與請求中varbinds
數組中N位置的varbind相對應。除非發生錯誤,不然遠程主機應該按照請求中指定的varbinds和它們的值回傳。varbinds
數組將包含遠程主機發回的每一個varbind。
當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
下面的例子設置了sysName(1.3.6.1.2.1.1.4.0
)和sysLocation(1.3.6.1.2.1.1.6.0
)OID的值。
var varbinds = [ { oid: "1.3.6.1.2.1.1.5.0", type: snmp.ObjectType.OctetString, value: "host1" }, { oid: "1.3.6.1.2.1.1.6.0", type: snmp.ObjectType.OctetString, value: "somewhere" } ]; session.set (varbinds, function (error, varbinds) { if (error) { console.error (error.toString ()); } else { for (var i = 0; i < varbinds.length; i++) { // for version 1 we can assume all OIDs were successful console.log (varbinds[i].oid + "|" + varbinds[i].value); // for version 2c we must check each OID for an error condition if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } } });
subtree()
方法獲取MIB樹中以指定的OID爲基礎,按詞法排列在指定OID以後的全部OID的值。例如,sysName(1.3.6.1.2.1.1.5.0
)和sysLocation(1.3.6.1.2.1.1.6.0
)這兩個OID都有相同的基系統(1.3.6.1.2.1.1
)OID。
對於SNMP版本1,重複調用get()
,直到返回的一個OID不使用指定的OID做爲其基礎。對於SNMP版本2c,重複調用getBulk()
,直到返回的OIDs中沒有使用指定的OID做爲其基礎。
oid
參數是一個OID字符串。當使用SNMP版本2c時,可選的maxRepetitions
參數被傳遞給getBulk()
請求。
一旦獲取了全部的OID值,這個方法將不會調用一個回調。相反,feedCallback
函數將在每次從遠程主機收到響應時被調用。如下參數將被傳遞給feedCallback
函數。
varbinds
- varbinds數組,至少包含一個varbind。當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
一旦返回的OID中至少有一個沒有使用指定的OID做爲其基礎,或者發生了錯誤,doneCallback
函數將被調用。如下參數將被傳遞給doneCallback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。一旦doneCallback
函數被調用,請求就完成了,feedCallback
函數將再也不被調用。
若是feedCallback
函數調用時返回true
值,則再也不調用get()
或getBulk()
方法,調用doneCallback
。
下面的例子是獲取系統(1.3.6.1.2.1.1
)下的全部OID。
var oid = "1.3.6.1.2.1.1"; function doneCb (error) { if (error) console.error (error.toString ()); } function feedCb (varbinds) { for (var i = 0; i < varbinds.length; i++) { if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } } var maxRepetitions = 20; // The maxRepetitions argument is optional, and will be ignored unless using // SNMP verison 2c session.subtree (oid, maxRepetitions, feedCb, doneCb);
table()
方法獲取MIB樹中以指定的OID爲基礎的、按詞法排列在指定OID以後的全部OID的值,這與subtree()
方法很類似。
這個方法被設計用來獲取概念表,例如ifTable(1.3.6.1.2.1.2.2
)表。返回的varbinds的值將被結構化爲表明概念行的對象。而後將每一行放入一個對象中,行的索引是鍵,例如:
var table = { // Rows keyed by ifIndex (1 and 2 are shown) 1: { // ifDescr (column 2) and ifType (columnd 3) are shown 2: "interface-1", 3: 6, ... }, 2: { 2: "interface-2", 3: 6, ... }, ... }
本方法內部調用subtree()
方法來獲取指定表的子樹。
oid
參數是一個OID字符串。若是傳遞的OID字符串不表明一個表,那麼產生的用於保存表數據的對象將是空的,也就是說,它將不包含索引和行。可選的maxRepetitions
參數被傳遞給subtree()
請求。
一旦整個表被獲取,callback
函數將被調用。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。table
-- -- 包含對象引用,表明按索引鍵入的概念行(例如,ifTable表的行按ifIndex鍵入),每一個行對象將包含按列號鍵入的值,若是發生錯誤將不提供。若是subtree()
返回的任何varbind發生錯誤,將不會向callback
函數傳遞任何表。失敗的緣由和相關的OID字符串(從調用snmp.varbindError()
函數返回的),將做爲RequestFailedError
類的一個實例,在error
參數中傳遞給callback
函數。
下面的例子獲取ifTable(1.3.6.1.2.1.2.2
)表。
var oid = "1.3.6.1.2.1.2.2"; function sortInt (a, b) { if (a > b) return 1; else if (b > a) return -1; else return 0; } function responseCb (error, table) { if (error) { console.error (error.toString ()); } else { // This code is purely used to print rows out in index order, // ifIndex's are integers so we'll sort them numerically using // the sortInt() function above var indexes = []; for (index in table) indexes.push (parseInt (index)); indexes.sort (sortInt); // Use the sorted indexes we've calculated to walk through each // row in order for (var i = 0; i < indexes.length; i++) { // Like indexes we sort by column, so use the same trick here, // some rows may not have the same columns as other rows, so // we calculate this per row var columns = []; for (column in table[indexes[i]]) columns.push (parseInt (column)); columns.sort (sortInt); // Print index, then each column indented under the index console.log ("row for index = " + indexes[i]); for (var j = 0; j < columns.length; j++) { console.log (" column " + columns[j] + " = " + table[indexes[i]][columns[j]]); } } } } var maxRepetitions = 20; // The maxRepetitions argument is optional, and will be ignored unless using // SNMP verison 2c session.table (oid, maxRepetitions, responseCb);
tableColumns()
方法實現了與table()
方法相同的接口。可是,只有在columns
參數中指定的列纔會出如今生成的表中。
當只須要選定的列時,應該使用這個方法,而且會比table()
方法快不少倍,由於會影響更少的數據量。
下面的例子是獲取ifTable(1.3.6.1.2.1.2.2
)表,並指定只獲取ifDescr(1.3.6.1.2.1.2.1.2
)和ifPhysAddress(1.3.6.1.2.1.2.1.6
)列。
var oid = "1.3.6.1.2.1.2.2"; var columns = [2, 6]; function sortInt (a, b) { if (a > b) return 1; else if (b > a) return -1; else return 0; } function responseCb (error, table) { if (error) { console.error (error.toString ()); } else { // This code is purely used to print rows out in index order, // ifIndex's are integers so we'll sort them numerically using // the sortInt() function above var indexes = []; for (index in table) indexes.push (parseInt (index)); indexes.sort (sortInt); // Use the sorted indexes we've calculated to walk through each // row in order for (var i = 0; i < indexes.length; i++) { // Like indexes we sort by column, so use the same trick here, // some rows may not have the same columns as other rows, so // we calculate this per row var columns = []; for (column in table[indexes[i]]) columns.push (parseInt (column)); columns.sort (sortInt); // Print index, then each column indented under the index console.log ("row for index = " + indexes[i]); for (var j = 0; j < columns.length; j++) { console.log (" column " + columns[j] + " = " + table[indexes[i]][columns[j]]); } } } } var maxRepetitions = 20; // The maxRepetitions argument is optional, and will be ignored unless using // SNMP verison 2c session.tableColumns (oid, columns, maxRepetitions, responseCb);
trap()
方法發送一個SNMP trap.typeOrOid`參數能夠是兩種類型之一。
typeOrOid
參數能夠是兩種類型之一:snmp.TrapType
對象中定義的常量之一(不包括snmp.TrapType.EnterpriseSpecific
常量),或者一個OID字符串。
對於SNMP版本1,當指定常量時,陷阱中會設置如下字段。
1.3.6.1.4.1
。1.3.6.1.4.1
。當指定了OID字符串時,會在陷阱中設置如下字段。
snmp.TrapType.EnterpriseSpecific
。在這兩種狀況下,陷阱PDU中的時間戳字段被設置爲process.uptime()
函數返回的值乘以100
。
SNMP版本2c的消息與版本1相比有很大不一樣。2c版陷阱的格式要簡單得多,只是一個varbinds的序列。陷阱消息中的第一個varbind是sysUptime.0
的OID(1.3.6.1.6.3.1.1.4.1.0
)。這個varbind的值將是process.uptime()
函數返回的值乘以100(能夠經過在可選的options
參數中提供upTime
來覆蓋,以下文所述)。
這以後會有第二個varbind的snmpTrapOID.0
OID (1.3.6.1.6.3.1.1.4.1.0
)。這個值取決於typeOrOid
參數。若是指定了一個常量,那麼常量的陷阱OID將被用來做爲varbinds的值,不然指定的OID字符串將被用來做爲varbind的值。
可選的varbinds
參數是要包含在陷阱中的varbinds數組,默認爲空數組[]
。
可選的agentAddrOrOptions
參數能夠是兩種類型之一,一種是用於填充SNMP版本1類型陷阱的agent-addr字段的IP地址,默認爲127.0.0.1
,或者是一個對象,能夠包含如下項目。
agentAddr
- 用於填充SNMP版本1類型陷阱的代理地址字段的IP地址,默認值爲127.0.0.1
。upTime
- trap中sysUptime.0
OID(1.3.6.1.6.3.1.4.1.0
)的值,默認爲process.uptime()
函數返回的值乘以100。注意當使用SNMP版本2c時,若是指定了agentAddr
參數,則會被忽略,由於版本2c的陷阱信息沒有agent-addr字段。
一旦陷阱被髮送或發生錯誤,"callback "函數將被調用。如下參數將被傳遞給callback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。如下示例使用SNMP版本1的陷阱向遠程主機發送企業特定的陷阱,並在陷阱中包含sysName(1.3.6.1.2.1.1.5.0
)varbind。在發送trap以前,agentAddr
字段使用DNS計算出本地主機的主機名。
var enterpriseOid = "1.3.6.1.4.1.2000.1"; // made up, but it may be valid var varbinds = [ { oid: "1.3.6.1.2.1.1.5.0", type: snmp.ObjectType.OctetString, value: "host1" } ]; dns.lookup (os.hostname (), function (error, agentAddress) { if (error) { console.error (error); } else { // Override sysUpTime, specfiying it as 10 seconds... var options = {agentAddr: agentAddress, upTime: 1000}; session.trap (enterpriseOid, varbinds, agentAddress, function (error) { if (error) console.error (error); }); } });
下面的例子使用SNMP版本1的trap向遠程主機發送一個通用的link-down trap,它不包括任何varbinds或指定agentAddr
參數。
session.trap (snmp.TrapType.LinkDown, function (error) { if (error) console.error (error); });
The following example sends an enterprise specific trap to a remote host using a SNMP version 2c trap, and includes two enterprise specific varbinds:
var trapOid = "1.3.6.1.4.1.2000.1"; var varbinds = [ { oid: "1.3.6.1.4.1.2000.2", type: snmp.ObjectType.OctetString, value: "Hardware health status changed" }, { oid: "1.3.6.1.4.1.2000.3", type: snmp.ObjectType.OctetString, value: "status-error" } ]; // version 2c should have been specified when creating the session session.trap (trapOid, varbinds, function (error) { if (error) console.error (error); });
walk()
方法獲取MIB樹中指定的OID以後全部OID的詞法值。
對於SNMP版本1,會重複調用get()
方法,直到到達MIB樹的末端。對於SNMP版本2c,會重複調用getBulk()
,直到到達MIB樹的末端。
oid
參數是一個OID字符串。當使用SNMP版本2c時,可選的maxRepetitions
參數被傳遞給getBulk()
請求。
一旦獲取了全部的OID值,這個方法將不會調用一個回調。相反,feedCallback
函數將在每次從遠程主機收到響應時被調用。如下參數將被傳遞給feedCallback
函數。
varbinds
- varbinds數組,至少包含一個varbind。當使用SNMP版本2c時,必須使用snmp.isVarbindError()
函數檢查每一個varbind是否存在錯誤條件。
一旦到達MIB樹的終點,或者發生了錯誤,doneCallback
函數將被調用。如下參數將被傳遞給doneCallback
函數。
error
- Error
類或子類的實例,若是沒有發生錯誤,則爲null
。一旦doneCallback
函數被調用,請求就完成了,feedCallback
函數將再也不被調用。
若是feedCallback
函數在調用時返回一個true
值,則再也不調用get()
或getBulk()
方法,而調用doneCallback
。
下面的例子從ifTable(1.3.6.1.2.1.2.2
)OID開始走到MIB樹的最後。
var oid = "1.3.6.1.2.1.2.2"; function doneCb (error) { if (error) console.error (error.toString ()); } function feedCb (varbinds) { for (var i = 0; i < varbinds.length; i++) { if (snmp.isVarbindError (varbinds[i])) console.error (snmp.varbindError (varbinds[i])); else console.log (varbinds[i].oid + "|" + varbinds[i].value); } } var maxRepetitions = 20; // The maxRepetitions argument is optional, and will be ignored unless using // SNMP verison 2c session.walk (oid, maxRepetitions, feedCb, doneCb);
RFC 3413 classifies a "Notification Receiver" SNMP application that receives "Notification-Class" PDUs. Notifications include both SNMP traps and informs. This library is able to receive all types of notification PDU:
Trap-PDU
(original v1 trap PDUs, which are now considered obselete)Trapv2-PDU
(unacknowledged notifications)InformRequest-PDU
(same format as Trapv2-PDU
but with message acknowledgement)The library provides a Receiver
class for receiving SNMP notifications. This module exports the createReceiver()
function, which creates a new Receiver
instance.
The receiver creates an Authorizer
instance to control incoming access. More detail on this is found below in the Authorizer Module section below.
createReceiver()
函數實例化並返回一個Receiver
類的實例。
// Default options var options = { port: 162, disableAuthorization: false, accessControlModelType: snmp.AccessControlModelType.None, engineID: "8000B98380XXXXXXXXXXXX", // where the X's are random hex digits address: null transport: "udp4" }; var callback = function (error, notification) { if ( error ) { console.error (error); } else { console.log (JSON.stringify(notification, null, 2)); } }; receiver = snmp.createReceiver (options, callback);
選項'和
回調'參數是強制性的。options
參數是一個對象,能夠是空的,能夠包含如下字段: * port
- 偵聽通知的端口 - 默認爲162。
port
--監聽通知的端口--默認爲162。請注意,在某些系統中,綁定到162端口須要接收器進程以管理權限運行。若是不可能,則選擇一個大於1024的端口。engineID
-- -- 用於SNMPv3通訊的引擎ID,以十六進制字符串形式給出 -- -- 默認爲系統生成的引擎ID,包含隨機元素。transport
-- -- 要使用的傳輸系列 -- -- 默認爲udp4
。address
-- -- 要綁定的IP地址 -- -- 默認爲null
,即綁定到全部IP地址。callback
參數是一個回調函數,其形式爲function (error, notification)
。在發生錯誤時,"notification "參數被設置爲 "null"。當成功接收到一個通知時,錯誤參數被設置爲null
,notification
參數被設置爲一個對象,在pdu
字段中包含通知PDU細節,在rinfo
字段中包含發送方socket細節。例如:
{ "pdu": { "type": 166, "id": 45385686, "varbinds": [ { "oid": "1.3.6.1.2.1.1.3.0", "type": 67, "value": 5 }, { "oid": "1.3.6.1.6.3.1.1.4.1.0", "type": 6, "value": "1.3.6.1.6.3.1.1.5.2" } ], "scoped": false }, "rinfo": { "address": "127.0.0.1", "family": "IPv4", "port": 43162, "size": 72 } }
返回接收器的Authorizer
實例,用於控制對接收器的訪問。更多細節請參見 "Authorizer "部分。
關閉接收機的監聽插座,結束接收機的操做。
SNMP代理響應與命令響應器應用相關的全部四個 "請求類 "PDU。
代理髮送GetResponse PDU到全部四種請求PDU類型,符合RFC 3416。
代理商--和通知接收方同樣--維護一個Authorizer
實例來控制對代理的訪問,詳細內容見下面的Authorizer模塊部分。
代理維護的中央數據結構是一個Mib
實例,其API詳見下面的Mib模塊部分。代理商容許經過API對MIB進行查詢和操做,也容許經過SNMP接口與上述四個請求類PDU進行查詢和操做。
該代理還經過其單人Forwarder
實例支持SNMP代理轉發應用,這在下面的Forwarder模塊部分有說明。
createAgent()
函數實例化並返回一個Agent
類的實例。
// Default options var options = { port: 161, disableAuthorization: false, accessControlModelType: snmp.AccessControlModelType.None, engineID: "8000B98380XXXXXXXXXXXX", // where the X's are random hex digits address: null transport: "udp4" }; var callback = function (error, data) { if ( error ) { console.error (error); } else { console.log (JSON.stringify(data, null, 2)); } }; agent = snmp.createAgent (options, callback);
選項'和
回調'參數是強制性的。options
參數是一個對象,能夠是空的,能夠包含如下字段。
port
--代理要監聽的端口--默認爲161。請注意,在某些系統上綁定到161端口須要接收方進程以管理權限運行。若是沒法作到這一點,則選擇一個大於1024的端口。accessControlModelType
-- -- 指定使用哪一種訪問控制模型。默認值爲snmp.AccessControlModelType.None
,但能夠設置爲snmp.AccessControlModelType.Simple
,以得到更多的訪問控制能力。更多信息請參見Authorization
類描述。engineID
--用於SNMPv3通訊的引擎ID,給定爲十六進制字符串--默認爲系統生成的引擎ID,包含隨機元素。transport
-- -- 要使用的傳輸系列 -- -- 默認爲udp4
。address
-- -- 要綁定的IP地址 -- -- 默認爲null
,即綁定到全部IP地址。mib
參數是可選的,它設置了代理的單體Mib
實例。若是不提供,代理會給本身建立一個新的空的Mib
單體。若是提供,則須要按照下面的Mib模塊部分來建立和填充Mib
實例。
返回代理的單人Authorizer
實例,用於控制對代理的訪問。更多細節請參見 "Authorizer "部分。
Returns the agent's singleton Mib
instance, which holds all the management data for the agent.
Sets the agent's singleton Mib
instance to the supplied one. The agent discards its existing Mib
instance.
Returns the agent's singleton Forwarder
instance, which holds a list of registered proxies that specify context-based forwarding to remote hosts.
Closes the agent's listening socket, ending the operation of the agent.
接收器和代理都維護一個單例的 "Authorizer "實例,它負責維護SNMP社區的受權列表(針對v1和v2c通知)和SNMP用戶的受權列表(針對v3通知)。這些列表用於受權接收方對通知的訪問,並存儲安全協議和密鑰設置。RFC 3414將用戶列表稱爲存儲在接收器的 "本地配置數據庫 "中的 "usmUserTable"。
若是收到的v1或v2c通知中的社區不在接收器的社區受權列表中,接收器將不接受該通知,而是向提供的回調函數返回一個類RequestFailedError
的錯誤。相似的,若是接收到一個v3通知,其用戶名稱不在接收者的用戶受權列表中,接收者將返回一個RequestFailedError
。若是在啓動時爲接收器提供了disableAuthorization
選項,那麼對於社區通知和noAuthNoPriv用戶通知,這些本地受權列表檢查將被禁用。請注意,即便有這個設置,用戶列表仍然會對 authNoPriv 和 authPriv 通知進行檢查,由於庫仍然須要訪問正確的密鑰來進行消息認證和加密操做,而這些密鑰是針對用戶受權列表中的用戶存儲的。
API容許對接收者/代理的社區受權和用戶受權列表進行添加、查詢和刪除管理。
對於代理來講,還有一個可選的訪問控制檢查,它能夠根據代理提供的做爲選項的AccessControlModelType
來限制給定社區或用戶的訪問。默認的模型類型是snmp.AccessControlModelType.None
,這意味着--在前面幾段描述的受權列表檢查以後,沒有進一步的訪問控制限制,即全部請求都被代理授予訪問權。能夠選擇第二個訪問控制模型類型snmp.AccessControlModelType.Simple
,它建立了一個SimpleAccessControlModel
對象,該對象能夠被操做,以指定社區或用戶對代理信息具備三個級別的訪問權限之一。
*讀寫器
關於如何使用 "SimpleAccessControlModel "類配置訪問的更多信息,將在下面對該類的描述中提供。
受權器實例能夠經過使用getAuthorizer()
調用得到,對於接收方和代理方來講都是如此。例如:
receiver.getAuthorizer ().getCommunities ();
在接收者的社區受權列表中添加一個社區字符串。若是社區已經在列表中,則不作任何操做,確保列表中任何給定的社區字符串只出現一次。
若是接收者的社區受權列表中存儲了一個社區字符串,則返回 "null",不然返回 "null"。
返回接收者的社區受權列表。
從接收者的社區受權列表中刪除一個社區字符串。若是社區不在列表中,則不作任何操做。
在接收方的用戶受權列表中添加一個用戶。若是列表中存在同名用戶,則該調用將刪除現有用戶,並以提供的用戶取而代之,確保列表中只存在一個同名用戶。用戶對象的格式與session.createV3Session()
調用的格式相同。
var user = { name: "elsa" level: snmp.SecurityLevel.authPriv, authProtocol: snmp.AuthProtocols.sha, authKey: "imlettingitgo", privProtocol: snmp.PrivProtocols.des, privKey: "intotheunknown" }; receiver.getAuthorizer ().addUser (elsa);
若是接收者的用戶受權列表中存儲了一個使用所提供名字的用戶,則返回一個用戶對象,不然返回null
。
Returns the receiver's user authorization list.
Deletes a user from the receiver's user authorization list. Does nothing if the user with the supplied name is not in the list.
Returns the snmp.AccessControlModelType
of this authorizer, which is one of:
snmp.AccessControlModelType.None
snmp.AccessControlModelType.Simple
Returns the access control model object:
snmp.AccessControlModelType.None
- returns null (as the access control check returns positive every time)snmp.AccessControlModelType.Simple
- returns a SimpleAccessControlModel
objectSimpleAccessControlModel'類能夠選擇做爲
Agent'使用的訪問控制模型。SimpleAccessControlModel
爲給定的社區或用戶提供基本的三級訪問控制。訪問級別由snmp.AccessLevel常量指定。
snmp.AccessLevel.None
--不授予社區或用戶任何訪問權。snmp.AccessLevel.ReadWrite
-- -- 容許社區或用戶訪問Get、GetNext、GetBulk和Set請求。SimpleAccessControlModel
不是經過直接的API調用建立的,而是由Agent
的Authorizer
單人在內部建立的。因此能夠用如下方法訪問代理的訪問控制模型。
var acm = agent.getAuthorizer ().getAccessControlModel ();
請注意,本節中任何 API 調用中使用的任何社區或用戶都必須首先在代理的 "受權者 "中建立,不然代理將沒法經過受權者執行的初始社區/用戶列表檢查。
當使用簡單訪問控制模型時,Authorizer
中新建立的社區或用戶的默認訪問級別是隻讀。
Example use:
var agent = snmp.createAgent({ accessControlModelType: snmp.AccessControlModelType.Simple }, function (error, data) { // null callback for example brevity }); var authorizer = agent.getAuthorizer (); authorizer.addCommunity ("public"); authorizer.addCommunity ("private"); authorizer.addUser ({ name: "fred", level: snmp.SecurityLevel.noAuthNoPriv }); var acm = authorizer.getAccessControlModel (); // Since read-only is the default, explicitly setting read-only access is not required - just shown here as an example acm.setCommunityAccess ("public", snmp.AccessLevel.ReadOnly); acm.setCommunityAccess ("private", snmp.AccessLevel.ReadWrite); acm.setUserAccess ("fred", snmp.AccessLevel.ReadWrite);
Grant the given community the given access level.
Remove all access for the given community.
Return the access level for the given community.
Return a list of all community access control entries defined by this access control model.
Grant the given user the given access level.
Remove all access for the given user.
Return the access level for the given user.
Return a list of all user access control entries defined by this access control model.
代理'實例在建立時,又建立了
Mib'類的一個實例。一個代理老是有且只有一個Mib
實例。經過agent.getMib()
調用來訪問代理的Mib
實例。
MIB是一個樹狀結構,它保存着管理信息。信息在樹中由一系列整數 "尋址",這些整數從樹的根部向下造成一個對象ID(OID)。
在MIB中,只有兩種數據結構能夠保存數據。
標量數據--標量變量存儲在MIB樹的某個節點上,變量的值是標量變量節點的單個子節點,地址老是 "0"。例如,sysDescr標量變量的地址爲 "1.3.6.1.2.1.1.1"。sysDescr變量的值存儲在 "1.3.6.1.2.1.1.0"
``` 1.3.6.1.2.1.1.1 <= sysDescr (標量變量) 1.3.6.1.2.1.1.0 = OctetString: MyAwesomeHost <= sysDescr.0 (標量變量值) ```
*表數據--SNMP表以列和行的形式存儲數據。一般狀況下,若是一個表存儲在MIB中的某個節點上,那麼在表OID的正下方有一個地址爲 "1 "的 "條目 "對象。在 "條目 "的正下方是一個列的列表,這些列的編號一般是從 "1 "往上的。在每一列的下面是一系列的行。在最簡單的狀況下,一行的 "索引 "是表中的一列,但行索引能夠是一系列列,也能夠是給出多個整數的列(如一個IPv4地址的索引有四個整數),或者二者都有。下面是ifTable中部分SNMP表的層次結構的例子。
``` 1.3.6.1.2.1.2.2 <= ifTable (table) 1.3.6.1.2.1.2.2.1 <= ifEntry (表項) 1.3.6.1.2.1.2.2.1.1 <= ifIndex (第1欄) 1.3.6.1.2.1.2.1.1 = Integer: 1 <= ifIndex row 1 value = 1。 1.3.6.1.2.1.2.2.1.1.2 = Integer: 2 <= ifIndex row 2 value = 2。 ```
在建立時,"Agent "實例會建立一個 "Mib "模塊的單人實例。而後,您能夠向代理的Mib
實例註冊一個 "提供者",它爲標量數據實例或表提供一個接口。
var myScalarProvider = { name: "sysDescr", type: snmp.MibProviderType.Scalar, oid: "1.3.6.1.2.1.1.1", scalarType: snmp.ObjectType.OctetString, handler: function (mibRequest) { // e.g. can update the MIB data before responding to the request here mibRequest.done (); } }; var mib = agent.getMib (); mib.registerProvider (myScalarProvider); mib.setScalarValue ("sysDescr", "MyAwesomeHost");
這段代碼首先給出了標量 "提供者 "的定義。在mib.registerProvider()
部分對這些字段作了進一步的解釋。重要的是,name
字段是提供者的惟一標識符,在後續的API調用中用於選擇特定的提供者。
registerProvider()
調用將提供者添加到MIB持有的提供者列表中。請注意,這個調用不會將 "oid "節點添加到MIB樹中。第一次調用setScalarValue()
將把實例OID "1.3.6.1.2.1.1.1.0 "連同其值一塊兒添加到MIB樹中。
此時,當經過SNMP查詢實例OID "1.3.6.1.1.2.1.1.1.0 "時,代理將提供該MIB節點的值。
一個表提供者也有相似的定義。
var myTableProvider = { name: "smallIfTable", type: snmp.MibProviderType.Table, oid: "1.3.6.1.2.1.2.2.1", tableColumns: [ { number: 1, name: "ifIndex", type: snmp.ObjectType.Integer }, { number: 2, name: "ifDescr", type: snmp.ObjectType.OctetString }, { number: 3, name: "ifType", type: snmp.ObjectType.Integer, constraints: { enumeration: { "1": "goodif", "2": "averageif", "3": "badif" } } } ], tableIndex: [ { columnName: "ifIndex" } ] }; var mib = agent.getMib (); mib.registerProvider (myTableProvider); mib.addTableRow ("smallIfTable", [1, "eth0", 6]);
在這裏,提供者的定義須要兩個添加字段。tableColumns
表示列的定義,tableIndex
表示用於行索引的列。在本例中,tableIndex
是ifIndex
列。mib.registerProvider()
部分有關於構成提供者定義的字段的進一步細節。
oid
必須是 "表條目 "節點的節點,而不是它的父 "表 "節點,例如對於ifTable
,提供者中的oid
是 "1.3.6.1.2.1.2.2.1"(ifEntry
的OID)。
請注意,在這個特殊的例子中,沒有handler
回調函數,因此任何交互都是直接在SNMP請求和MIB值之間進行,沒有其餘干預。
createMib()
函數實例化並返回一個Mib
類的實例。新的Mib沒有任何節點(除了一個根節點),也沒有任何註冊的提供者。
請注意,這隻適用於一個代理,而不是AgentX子代理。因爲代理在建立時就會實例化一個Mib
實例,因此在不少狀況下不須要這個調用。有兩種狀況可能會用到它。
Mib
實例。Mib
實例換成一個全新的實例。在MIB中註冊一個提供者定義。不向MIB樹添加任何內容。
提供者定義有如下幾個字段: * name
(強制性的) - 提供者的名稱。
name
(強制) - 提供方的名稱,它是獲取和設置值時引用提供方的惟一鍵。type
(強制性) - 必須是snmp.MibProviderType.Scalar
或snmp.MibProviderType.Table
(強制性)oid
(必須填寫) -提供者在MIB樹中註冊的OID。請注意,這不是*的 "實例節點"(".0 "節點),而是它上面的節點。在這種狀況下,提供者在 "1.3.6.1.2.1.1.1 "處註冊,以提供 "1.3.6.1.2.1.1.0 "處的值。scalarType
(標量類型必須填寫) -只與標量提供者類型相關,這給出了變量的類型,從snmp.ObjectType
中選擇。tableColumns
(表類型必須填寫) -- -- 提供表的任何列定義對象數組。每一個列對象必須有一個獨特的數字'、
名稱'和snmp.ObjectType'的
類型'。類型爲ObjectType.Integer
的列對象能夠選擇性地包含一個constraints
對象,其格式和含義與在單個標量提供者上定義的對象相同(具體內容見下文constraints
)。tableIndex
(表類型可選) -給出一個用於行索引的索引入口對象數組。對於單列索引使用單元素數組,對於複合索引使用多個值。一個索引條目對象有一個columnName
字段,若是條目在另外一個提供者的表中,那麼包括一個foreign
字段,寫上外表提供者的名稱。若是沒有tableAugments
字段,tableIndex
是必須的。tableAugments
(表類型可選) -給出本表 "加強 "的另外一個註冊提供者的名稱。這意味着索引信息是從給定提供者的表中獲取的,而且不存在於本地表的列定義中。若是tableIndex
字段不存在,tableAugments
是必須的,即tableIndex
和tableAugments
中的一個須要存在,才能定義表的索引。handler
(optional) - 一個可選的回調函數,在向MIB提出請求以前被調用。這能夠更新這個提供者處理的MIB值。若是沒有給定,那麼這些值將被簡單地從MIB中返回(或設置),而不須要任何其餘處理。回調函數須要一個MibRequest
實例,它有一個done()
函數。當處理完請求時,必須調用這個函數。MibRequest
也有一個oid
字段,寫着被操做的實例OID,還有一個operation
字段,寫着來自snmp.PduType
的請求類型。若是 "MibRequest "是針對 "SetRequest "PDU的,那麼變量 "setValue "和 "setType "就包含了 "SetRequest "varbind中接收到的值和類型。constraints
(對於標量類型是可選的) - 一個可選的對象,用於指定基於整數的枚舉類型的約束。目前惟一支持的約束是enumeration
對象,它將整數映射到它們的命名類型,以捕獲RFC 2578第7.1.1節中描述的 "命名數枚舉"。任何SetRequest協議操做都會根據定義的約束條件進行檢查,若是SetRequest中的值會違反約束條件,例如該值不是定義的枚舉的成員,則不會採起行動。請注意,表列能夠以相同的方式指定這樣的 "約束",只是這些約束存儲在每一個列的列對象定義下。在向MIB註冊提供者後,在其餘API調用中,提供者由其名稱
引用。
雖然這個調用將提供者註冊到MIB,但它不會改變MIB樹。
Convenience method to register an array of providers in one call. Simply calls registerProvider()
for each provider definition in the array.
Unregisters a provider from the MIB. This also deletes all MIB nodes from the provider's oid
down the tree. It will also do upstream MIB tree pruning of any interior MIB nodes that only existed for the MIB tree to reach the provider oid
node.
Returns an object of provider definitions registered with the MIB, indexed by provider name.
Returns a single registered provider object for the given name.
Retrieves the value from a scalar provider.
Sets the value for a scalar provider. If this is the first time the scalar is set since the provider has registered with the MIB, it will also add the instance (".0") node and all required ancestors to the MIB tree.
將錶行--以值數組的形式--添加到表提供者。若是表是空的,則在添加值行以前,實例化提供者的oid
節點和祖先,即其列。請注意,該行是一個按照表列順序排列的元素數組。若是表有任何外來索引列(即那些不屬於本表的索引列),那麼這些列的值必須按照它們在MIB INDEX子句中出現的順序,包含在行數組的開頭。
Returns a list of column definition objects for the provider.
返回表格數據的二維數組。若是byRow
爲false(默認),那麼表格數據是以列數組列表的形式給出的,即按列給出。若是byRow
是true
,那麼數據就是一個行數組的列表。若是includeInstances
是true
,那麼,對於列視圖,將有一個額外的第一列的實例索引信息。若是行視圖中includeInstances
爲true
,那麼在每一行的開始會有一個附加元素,包含索引信息。
Returns a single column of table data for the given column number. If includeInstances
is true
, then two arrays are returned: the first with instance index information, and the second with the column data.
返回給定行索引的單行表數據。行索引是一個由索引值組成的數組,從緊挨着列下的節點到行實例末尾的節點,這將是MIB樹中的一個葉子節點。最終,非整數值須要轉換爲整數序列,構成OID的實例部分。下面是將索引值轉換爲行實例OID序列的細節。
Returns a single cell value from the column and row specified. The row index array is specified in the same way as for the getTableRowCells()
call.
Sets a single cell value at the column and row specified. The row index array is specified in the same way as for the getTableRowCells()
call.
Deletes a table row at the row index specified. The row index array is specified in the same way as for the getTableRowCells()
call. If this was the last row in the table, the table is pruned from the MIB, although the provider still remains registered with the MIB. Meaning that on the addition of another row, the table will be instantiated again.
以文本格式轉儲MIB。options
對象經過這些選項字段控制轉儲的顯示(全部選項都是布爾值,默認爲true
)。
leavesOnly
--不單獨顯示內部節點--只顯示葉子節點的前綴部分(實例節點)。showProviders
-- -- 顯示提供者與MIB相連的節點。showValues
- 顯示實例值。For example:
mib.dump ();
produces this sort of output:
1.3.6.1.2.1.1.1 [Scalar: sysDescr] 1.3.6.1.2.1.1.1.0 = OctetString: Rage inside the machine! 1.3.6.1.2.1.2.2.1 [Table: ifTable] 1.3.6.1.2.1.2.2.1.1.1 = Integer: 1 1.3.6.1.2.1.2.2.1.1.2 = Integer: 2 1.3.6.1.2.1.2.2.1.2.1 = OctetString: lo 1.3.6.1.2.1.2.2.1.2.2 = OctetString: eth0 1.3.6.1.2.1.2.2.1.3.1 = Integer: 24 1.3.6.1.2.1.2.2.1.3.2 = Integer: 6
該庫支持MIB解析,爲ModuleStore
實例提供了一個接口,您能夠從文件中加載MIB模塊,並獲取由此產生的JSON MIB模塊表示。
此外,一旦一個MIB被加載到模塊存儲中,你就能夠生成一個MIB "提供者 "定義的列表,一個 "代理 "能夠註冊(更多細節請參見 "代理 "文檔),這樣你就能夠立刻開始操做你的MIB文件中定義的全部值。
// Create a module store, load a MIB module, and fetch its JSON representation var store = snmp.createModuleStore (); store.loadFromFile ("/path/to/your/mibs/SNMPv2-MIB.mib"); var jsonModule = store.getModule ("SNMPv2-MIB"); // Fetch MIB providers, create an agent, and register the providers with your agent var providers = store.getProvidersForModule ("SNMPv2-MIB"); // Not recommended - but authorization and callback turned off for example brevity var agent = snmp.createAgent ({disableAuthorization: true}, function (error, data) {}); var mib = agent.getMib (); mib.registerProviders (providers); // Start manipulating the MIB through the registered providers using the `Mib` API calls mib.setScalarValue ("sysDescr", "The most powerful system you can think of"); mib.setScalarValue ("sysName", "multiplied-by-six"); mib.addTableRow ("sysOREntry", [1, "1.3.6.1.4.1.47491.42.43.44.45", "I've dreamed up this MIB", 20]); // Then hit those bad boys with your favourite SNMP tools (or library ;-), e.g. snmpwalk -v 2c -c public localhost 1.3.6.1
這意味着您能夠用最少的模板代碼直接實現您的MIB功能。
建立一個新的ModuleStore
實例,該實例預裝了一些 "基礎 "MIB模塊,這些模塊提供了其餘MIB模塊經常使用的MIB定義("導入")。預裝的 "基礎 "模塊列表以下:
將給定文件中的全部MIB模塊加載到模塊存儲中。按照慣例,每一個文件中一般只有一個MIB模塊,但一個文件中能夠存儲多個模塊定義。而後,加載的MIB模塊被這個API用它們的MIB模塊名而不是源文件名來引用。MIB模塊名是MIB文件中DEFINITIONS ::= BEGIN
前面的名稱,一般是MIB文件中最早出現的東西。
請注意,若是您的MIB依賴於("導入")其餘MIB文件中的定義,則必須首先加載這些定義,例如,流行的IF-MIB使用了來自IANAifType-MIB的定義,所以必須首先加載。這些依賴關係列在MIB模塊的IMPORTS部分,一般在MIB文件的頂部。預先加載的 "基礎 "MIB模塊包含了許多經常使用的導入。
Retrieves the named MIB module from the store as a JSON object.
從商店中檢索全部的MIB模塊,若是includeBase
boolean被設置爲true,那麼基本的MIB模塊就會被包含在列表中。若是 "includeBase "布爾值被設置爲true,那麼基本的MIB模塊就被包含在列表中。模塊做爲一個單一的JSON "對象中的對象 "返回,以模塊名稱爲鍵,其值是整個JSON模塊的表示。
Retrieves a list of the names of all MIB modules loaded in the store. If the includeBase
boolean is set to true, then the base MIB modules names are included in the list.
Returns an array of Mib
"provider" definitions corresponding to all scalar and table instance objects contained in the named MIB module. The list of provider definitions are then ready to be registered to an agent's MIB by using the agent.getMib().registerProviders()
call.
代理'實例在建立後,又會建立
Forwarder'類的實例。沒有直接的API調用來建立 "Forwarder "實例;這種建立是代理的責任。一個代理老是隻有一個Forwarder
實例。代理的Forwarder
實例是經過agent.getForwarder()
調用來訪問的。
Forwader
就是RFC 3413所說的 "代理轉發應用"。它維護着一個 "代理 "條目列表,每一個條目都配置了一個命名的SNMPv3上下文名稱,以使用戶憑證可以訪問給定的目標主機。Forwarder
只支持SNMPv3會話的代理。
var forwarder = agent.getForwarder (); forwarder.addProxy({ context: "slatescontext", host: "bedrock", user: { name: "slate", level: snmp.SecurityLevel.authNoPriv, authProtocol: snmp.AuthProtocols.sha, authKey: "quarryandgravel" }, });
如今,使用所提供的 "slatescontext "上下文向代理髮出的請求將被轉發到主機 "bedrock",並使用所提供的用戶 "slate "的證書。
你可使用本地代理用戶(與代理的Authorizer
實例一塊兒添加)查詢代理。假設你的代理運行在localhost,161端口,你能夠添加本地用戶 "fred",而後用新的 "fred "用戶訪問代理。
var authorizer = agent.getAuthorizer(); authorizer.addUser ({ name: "fred", level: snmp.SecurityLevel.noAuthNoPriv }); // Test access using Net-SNMP tools (-n is the context option): snmpget -v 3 -u fred -l noAuthNoPriv -n slatescontext localhost 1.3.6.1.2.1.1.1.0
This proxies requests through to "bedrock" as per the proxy definition.
爲轉發者添加一個新的代理。代理是一個包含如下字段的對象。
context
(強制) - 這個代理條目的SNMPv3上下文名稱。這是代理條目的惟一鍵,即不能有兩個代理條目的上下文名稱相同。transport
(可選) - 指定到達遠程目標的傳輸。能夠是udp4
或udp6
,默認爲udp4
。target
(強制) - 接收代理請求的遠程主機。port
(可選) - 遠程主機上SNMP代理的端口。默認值爲161。user
(必填) - SNMPv3用戶。用戶的格式在createV3Session()
調用文檔中描述。Delete the proxy for the given context from the forwarder.
Returns the forwarder's proxy for the given context.
Returns an object containing a list of all registered proxies, keyed by context name.
Prints a dump of all proxy definitions to the console.
AgentX子代理實現了RFC 2741中指定的功能,成爲AgentX "主代理 "的一個 "子代理"。AgentX的目標是經過一個單獨的 "子代理 "來擴展示有的 "主代理 "SNMP代理的功能,註冊它想爲主代理管理的MIB樹的部分。
除了兩個 "管理 "PDU類型外,AgentX子代理支持生成全部的PDU類型,全部的PDU都是從子代理髮送到主代理的。
兩種不支持的 "管理 "PDU類型是: * IndexAllocate PDU - 請求從索引由主代理管理的表分配索引。
這些都是不支持的,由於它們不適合當前的MIB提供者註冊模型,該模型只支持註冊標量和整個表格。未來能夠經過進一步歸納註冊模型來支持錶行註冊來支持這些。
子代理響應全部與命令響應者應用相關的 "請求處理 "PDU類型,這些類型是從主代理接收的。
根據 RFC 2741,除了 CleanupSet PDU 外,全部這些都會返回一個 Response PDU 給主代理。
與SNMP代理同樣,AgentX子代理維護的是一個Mib
實例,其API在上面的Mib模塊部分有詳細介紹。子代理容許經過API查詢和操做MIB,也容許經過AgentX接口查詢和操做上述 "請求處理 "PDU(當主代理調用其SNMP接口時,主代理會產生)。
重要的是,MIB提供者是使用子代理的subagent.registerProvider()
調用來註冊的(以下所述),而不是使用subagent.getMib().registerProvider()
,由於子代理既須要在其內部Mib
對象上註冊提供者,_又須要爲提供者的MIB區域發送一個Register PDU給主代理。若是直接在MIB對象上註冊提供者,則跳事後一步。
The createSubagent ()
function instantiates and returns an instance of the Subagent
class:
// Default options var options = { master: localhost masterPort: 705, timeout: 0, description: "Node net-snmp AgentX sub-agent", }; subagent = snmp.createSubagent (options);
The options
parameter is a mandatory object, possibly empty, and can contain the following fields:
master
- the host name or IP address of the master agent, which the subagent connects to.masterPort
- the TCP port for the subagent to connect to the master agent on - defaults to 705.timeout
- set the session-wide timeout on the master agent - defaults to 0, which means no session-wide timeout is set.description
- a textual description of the subagent.Returns the agent's singleton Mib
instance, which is automatically created on creation of the subagent, and which holds all of the management data for the subagent.
Sends an Open
PDU to the master agent to open a new session, invoking the callback on response from the master.
Sends a Close
PDU to the master agent to close the subagent's session to the master, invoking the callback on response from the master.
See the Mib
class registerProvider()
call for the definition of a provider. The format and meaning of the provider
object is the same for this call. This sends a Register
PDU to the master to register a region of the MIB for which the master will send "request processing" PDUs to the subagent. The supplied callback
is used only once, on reception of the subsequent Response
PDU from the master to the Register
PDU. This is not to be confused with the handler
optional callback on the provider definition, which is invoked for any "request processing" PDU received by the subagent for MIB objects in the registered MIB region.
Unregisters a previously registered MIB region by the supplied name of the provider. Sends an Unregister
PDU to the master agent to do this. The supplied callback
is used only once, on reception of the subsequent Response
PDU from the master to the Unregister
PDU.
Convenience method to register an array of providers in one call. Simply calls registerProvider()
for each provider definition in the array. The callback
function is called once for each provider registered.
Returns an object of provider definitions registered with the MIB, indexed by provider name.
Returns a single registered provider object for the given name.
Adds an agent capability - consisting of oid
and descr
- to the master agent's sysORTable. Sends an AddAgentCaps
PDU to the master to do this. The supplied callback
is called on reception of the subsequent Response
PDU from the master to the AddAgentCaps
PDU.
Remove an previously added capability from the master agent's sysORTable. Sends a RemoveAgentCaps
PDU to the master to do this. The supplied callback
is called on reception of the subsequent Response
PDU from the master to the RemoveAgentCaps
PDU.
Sends a notification to the master agent using a Notify
PDU. The notification takes the same form as outlined in the session.inform()
section above and also in RFC 2741 Section 6.2.10, which is creating two varbinds that are always included in the notification:
snmp.TrapType
value)The optional varbinds
list is an additional list of varbind objects to append to the above two varbinds. The supplied callback
is called on reception of the subsequent Response
PDU from the master to the Notify
PDU.
Sends a "ping" to the master agent using a Ping
PDU, to confirm that the master agent is still responsive. The supplied callback
is called on reception of the subsequent Response
PDU from the master to the Ping
PDU.
Example programs are included under the module's example
directory.