本模块实现了简单网络管理协议(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.