`
diy8187
  • 浏览: 75859 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

OpenNMS扩展–基于JoeSNMP/MIB数据访问实现

阅读更多

OpenNMS扩展基于JoeSNMP/MIB数据访问实现

1. MIB访问流程及原理

JoeSNMPOpenNMS采用的SNMP API,已独立成为一个Open Source Framework,基于JoeSNMP可以对MIB网络数据进行相应的操作。JoeSNMP封装了多个对SNMP Get,Set等操作的处理。

l Get:用于读取设备MIB信息库中实例对象的单个值,GetOID表示对象实例值,

l Set:用于简单的设置MIB中可读写的对象实例值。

MIB访问的主流程图如下:

1. MIB访问的主流程图

首先根据自变量接收一个要访问的被管理对象主机名,并接收要查询的对象标识符的简略定义形式. 过程首先生成SNMP 报文,一旦报文生成,再把报文简单反转过来,发送出去.生成SNMP 报文后,建立代理地址,创建套接字连接,以便代理能将响应发回. 然后,SNMP 请求报文发给代理 ,等待一个响应的到来.因为SNMP 是工作在UDP 之上的,所以在SNMP 应用实体间通信时,无需先建立连接,这样虽降低了系统开销,UDP 传输是不可靠的,为此,网络管理站采取了相应的超时和重发策略. 系统在发出请求报文之后,启动超时计数器,等待响应的到来,并设置重发次数为3. 3 次之后仍没有收到响应,则关闭套接字,并返回一个接收失败错误代码. 反之,若确定收到一个响应,则调用一过程来把响应转换成为内部表示形式, 即对SNMP 报文进行译码. 再用已保存的Request-id与响应Request-id段进行比较,来验证这个报文是否是刚才发出的请求报文的响应. 若是,就调用另一个过程,把每段对象标识符的ASN.1表示形式转换成自己的内部形式,并显示其值

2. Get-Request/Set-Request步骤

实现SnmpHandler接口

写一个SnmpSet, SnmpGet, implement SnmpHandler,实现处理SNMP的方法:snmpReceivedPdu, snmpTimeoutErrortsnmpInternalError. 如:SnmpGet.java

public class SnmpGet implements SnmpHandler {

/**

* The log4j category used to log debug messsages and statements.

*/

private static final String LOG4J_CATEGORY = "SureTech.NMS";

public void snmpInternalError(SnmpSession session, int err, SnmpSyntax pdu) {

System.out.println("InternalError");

value ="Internal Error";

synchronized (session) {

session.notify();

}

}

public void snmpReceivedPdu(SnmpSession session, int command, SnmpPduPacket pdu) {

ThreadCategory.setPrefix(LOG4J_CATEGORY);

Category log = ThreadCategory.getInstance();

SnmpVarBind varBind = pdu.getVarBindAt(0);

value = varBind.getValue().toString();

if(log.isDebugEnabled()){

log.debug("Received value: " + varBind.getName() + "="

+ varBind.getValue());

}

synchronized (session) {

session.notify();

}

}

public void snmpTimeoutError(SnmpSession session, SnmpSyntax pdu) {

System.out.println("SnmpTimeout");

value ="Snmp Timeout";

synchronized (session) {

session.notify();

}

}

}

2.2创建SnmpPeer对象

创建一个SnmpPeer对象,需定义:

l AgentIP地址

l port (defaults to 161)

l retries (defaults to 3)

l timeout (defaults to .8 seconds)

如下在方法snmpGet方法中的红色代码片段:

/**

* The value of snmpget command.

*/

public String snmpGet(String host, String oid) throws SocketException,

UnknownHostException {

InetAddress remote = InetAddress.getByName(host);

SnmpPeer peer = new SnmpPeer(remote);

peer.setPort(161);

peer.setTimeout(5000);

peer.setRetries(1); // it is actually number of tries

SnmpParameters parms = peer.getParameters();

parms.setVersion(SnmpSMI.SNMPV2);

parms.setReadCommunity("public");

final SnmpSession session = new SnmpSession(peer);

session.setDefaultHandler(new SnmpGet());

SnmpVarBind[] vblist = { new SnmpVarBind(oid) };

SnmpPduRequest pdu = new SnmpPduRequest(

oid.endsWith(".0") ? SnmpPduPacket.GET : SnmpPduPacket.GETNEXT,

vblist);

pdu.setRequestId(1);

try {

synchronized (session) {

session.send(pdu);

session.wait();

}

} catch (InterruptedException e) {

// do nothing

} finally {

session.close();

}

return value;

}

2.3创建SnmpParameters对象

创建一个SnmpPeer对象,需定义:

l read community string (defaults to public)

l write community string (defaults to null)

l SNMP version to use (defaults to SNMPV1)

l AsnEncoder to use (defaults to BER)

SnmpParameters parms = peer.getParameters();

parms.setVersion(SnmpSMI.SNMPV2);

parms.setReadCommunity("public");

2.4创建SnmpSession对象,发送PDU

SnmpPeer创建一个SnmpSession对象,这样就创建一个“SnmpPortal”线程,此线程用来接受来自远程Agent的响应,也可以创建一个Quene来处理所有的SNMP请求。

final SnmpSession session = new SnmpSession(peer);

session.setDefaultHandler(new SnmpGet());

SnmpVarBind[] vblist = { new SnmpVarBind(oid) };

SnmpPduRequest pdu = new SnmpPduRequest(

oid.endsWith(".0") ? SnmpPduPacket.GET : SnmpPduPacket.GETNEXT,

vblist);

pdu.setRequestId(1);

try {

synchronized (session) {

session.send(pdu);

session.wait();

}

} catch (InterruptedException e) {

// do nothing

} finally {

session.close();

}

l 通过调用session.send(pdu)发送PDU请求到远程的Agent,开启一个新的线程发送请求和处理重试或超时。

l 调用session.wait()进行线程等待。

l SNMP session线程收到来自Agent的响应后会调用snmpTimeoutError方法,如果Agent没有在超时时间内响应,SNMP session线程将调用snmpTimeoutError方法,如果是内部发生了问题,则调用snmpInternalError方法。

l 线程唤醒,并继续处理。

2.5关闭Session

session.close();

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics