JAVA项目使用SNMP v3 协议控制设备

419 阅读2分钟

snmp4j的版本从3.0.0开始使用的是JDK9作为Java编译版本。 引入最新的依赖,需要运行环境的JDK版本最低为JDK9。

org.snmp4j snmp4j 3.7.7

使用snmpv3协议增加了安全、加密校验,需要提供用户,用户密钥,加密密钥三个信息。

调用参数示例 snmpSet("udp:ip/port","","admin","pwd","priv","1.1.1.12.14","1")

代码示例通过snmp协议向设备发送set信息,, 向设备发送GET请求,需要将PDU的type设备为get类型。 `public boolean snmpSet(String address, String contextName, String securityName,
String authPassphrase, String privPassphrase, String oid, String value) {

SnmpBuilder snmpBuilder = new SnmpBuilder();
Snmp snmp=null;
try {
snmp = snmpBuilder.udp().v3().usm().threads(2).build();
// snmp.listen();

Address targetAddress = GenericAddress.parse(address);
byte[] targetEngineID = snmp.discoverAuthoritativeEngineID(targetAddress, 1000);
if (targetEngineID == null) {
log.error("SNMP协议 {} 连接超时", address);
return false;
}
TargetBuilder targetBuilder = snmpBuilder.target(targetAddress); Target userTarget = targetBuilder
.user(securityName, targetEngineID)
//此处设置 认证协议 .auth(TargetBuilder.AuthProtocol.hmac384sha512).authPassphrase(authPassphrase)
//此处设置 密钥私有协议 .priv(TargetBuilder.PrivProtocol.aes256).privPassphrase(privPassphrase)
.done()
.timeout(500).retries(1)
.build();

//type 为PDU.SET PDU pdu = targetBuilder.pdu().type(PDU.SET).vb(new OID(oid), new OctetString(value)).contextName(contextName).build();
SnmpCompletableFuture snmpRequestFuture = SnmpCompletableFuture.send(snmp, userTarget, pdu);

if (snmpRequestFuture.getResponseEvent().getResponse() == null) {
log.info("SNMP协议 set PUD 执行异常");
return false;
}
log.info("SNMP协议 set PUD Received:{}", snmpRequestFuture.getResponseEvent().getResponse());

List vbs = snmpRequestFuture.get().getAll();
if (CollectionUtils.isEmpty(vbs)) {
log.info("SNMP协议 set PUD 未获取到执行结果");
return false;
}
for (VariableBinding vb : vbs) {
log.info("SNMP协议 set PUD 执行结果 oid: {}, value:{} ",vb.getOid().format(),vb.getVariable().toString());
}
return true;
} catch (Exception e) {
log.error("SNMP协议 set PUD 执行异常,地址:{}", address, e);
return false;
} finally {
if(snmp !=null){
try {
snmp.close();
} catch (IOException e) {
log.error("SNMP协议 snmp 关闭异常,地址:{}", address, e);
}
}
}
}`

如果运行环境使用JDK8,引入以下依赖。
org.snmp4j
snmp4j
2.8.18

`public boolean snmpSet(String address, String contextName, String securityName,
String authPassphrase, String privPassphrase, String oid, String value) {
Snmp snmp = null;
try {
MessageDispatcher messageDispatcher = new MessageDispatcherImpl();
//创建 用户安全模型 USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), new OctetString(MPv3.createLocalEngineID()), 0);
//添加 安全用户,指定用户名,认证协议,密钥协议 usm.addUser(new OctetString(securityName), new UsmUser(new OctetString(securityName),
AuthHMAC384SHA512.ID, new OctetString(authPassphrase), PrivAES256.ID, new OctetString(privPassphrase)));

//添加消息安全模型 messageDispatcher.addMessageProcessingModel(new MPv3(usm));

// 创建UDP传输映射
TransportMapping<? extends Address> transport = new DefaultUdpTransportMapping();
// 创建SNMP对象
snmp = new Snmp(messageDispatcher,transport);
snmp.listen();

log.info("SNMP协议 {}",snmp);
// 创建目标设备
UserTarget target = new UserTarget();
target.setSecurityName(new OctetString(securityName));
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setAddress(GenericAddress.parse(address));
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version3);

// 创建PDU snmpv3协议 需要创建ScopedPDU对象,不能直接创建PDU对象, PDU pdu = new ScopedPDU();
pdu.setType(PDU.SET);
pdu.add(new VariableBinding(new OID(oid), new Integer32(Integer.parseInt(value)))); // 添加请求的OID
log.info("SNMP协议 set PUD : {}", pdu.toString());

// 发送请求
ResponseEvent event = snmp.send(pdu, target);

// 处理响应
if (event != null && event.getResponse() != null) {
PDU response = event.getResponse();
if (response.getErrorStatus() == PDU.noError) {
// 获取响应的变量绑定列表
for (VariableBinding vb : response.getVariableBindings()) {
System.out.println(vb.getOid() + " = " + vb.getVariable());
log.info("SNMP协议 set PUD 执行结果 oid: {}, value:{} ", vb.getOid().format(), vb.getVariable().toString());
}
return true;

} else {
log.info("SNMP协议 set PUD 执行结果失败, 错误码:{}, 描述:{}",response.getErrorStatus(),response.getErrorStatusText());
return false;
}
} else {
log.info("SNMP协议 set PUD 执行结果未返回");
return false;
}
} catch (Exception e) {
log.error("SNMP协议 set PUD 执行异常,地址:{}", address, e);
return false;
} finally {
if (snmp != null) {
try {
snmp.close();
} catch (IOException e) {
log.error("SNMP协议 snmp 关闭异常,地址:{}", address, e);
}
}
}
}`