snmp4j - SNMP4J:无法让 SNMPv3 与多个目标一起工作
问题描述
我正在尝试使用 SNMP4J (v2.6.2) 一次查询 (snmpget) 两台不同的目标机器。我尝试了两种方法,它总是只收到第一个目标的响应。无论我第二次查询哪个都不会得到回应。(我可以从命令行很好地查询两台机器,包括单独和同时查询。)我尝试的一种方法使用 one Snmp
、 oneTransport
和 two UserTarget
s。另一种方法使用两个Snmp
s、两个Transport
s和两个
UserTarget
s。它们的行为相同。如果我发送一个请求,等到那个请求完成,然后发送第二个请求,我也会得到相同的效果。
我写了一个最小的例子并将其粘贴在下面。也许有人可以提示我做错了什么。谢谢!
package snmpclienttext;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.TSM;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class SNMPClientTest {
static class MySNMP {
TransportMapping<? extends Address> transport;
Snmp snmp;
OctetString securityName;
static String password = "temppassword";
UserTarget target;
void setup(String ip) throws IOException {
DefaultUdpTransportMapping d = new DefaultUdpTransportMapping();
d.setReceiveBufferSize(65536);
transport = d;
System.out.println("Listen address: " +
transport.getListenAddress());
transport.listen();
snmp = new Snmp(transport);
OctetString localEngineId = new
OctetString(MPv3.createLocalEngineID());
USM usm = new USM(SecurityProtocols.getInstance(),
localEngineId, 0);
SecurityModels.getInstance().addSecurityModel(usm);
securityName = new OctetString("SHA");
OID authProtocol = AuthSHA.ID;
OID privProtocol = org.snmp4j.security.PrivAES128.ID;
System.out.println("snmpv3password: " + password);
OctetString authPassphrase = new OctetString(password);
OctetString privPassphrase = new OctetString(password);
snmp.getUSM().addUser(securityName, new
UsmUser(securityName, authProtocol, authPassphrase, privProtocol,
privPassphrase));
SecurityModels.getInstance().addSecurityModel(new
TSM(localEngineId, false));
target = new UserTarget();
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(securityName);
target.setAddress(GenericAddress.parse(String.format("udp:%s/%s",
ip, "161")));
target.setVersion(SnmpConstants.version3);
target.setRetries(0);
target.setTimeout(60000);
}
public void readRequest(String oid) throws IOException {
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(new OID(oid)));
pdu.setType(PDU.GET);
try {
System.out.println("snmp get for " + target.getAddress());
snmp.get(pdu, target, null, listener);
} catch (IOException ex) {
System.out.println("SNMP Fail");
return;
}
}
}
static ResponseListener listener = new ResponseListener() {
@Override
public void onResponse(ResponseEvent event) {
if (event != null) {
Address addr = event.getPeerAddress();
if (addr == null) {
System.out.println("Null address");
return;
}
System.out.println("Peer Address = " + addr);
PDU rpdu = event.getResponse();
if (rpdu != null) {
if (rpdu.getErrorStatus() == PDU.noError) {
for (VariableBinding vb : rpdu.getVariableBindings()) {
OID oid = vb.getOid();
org.snmp4j.smi.Variable var = vb.getVariable();
String val = var.toString();
if (var.isException()) val = "";
System.out.println("Binding for " + oid +
" has " + vb.toString().length() + " characters, var has " +
val.length() + " characters");
}
} else {
System.out.println("Snmp Get Unsuccessful.");
}
} else {
System.out.println("Snmp response is null.");
}
} else {
System.out.println("SNMP event null.");
}
}
};
public static void main(String[] args) throws IOException,
InterruptedException {
MySNMP a = new MySNMP();
MySNMP b = new MySNMP();
a.setup("10.1.2.78");
b.setup("10.1.2.135");
a.readRequest("1.3.6.1.4.1.6713.1.3.1.2.1.1.50");
Thread.sleep(10000);
b.readRequest("1.3.6.1.4.1.6713.1.3.1.2.1.1.50");
Thread.sleep(10000);
}
}
解决方案
问题的根源在于对两个 SNMP 实体“a”和“b”使用相同的引擎 ID。确保始终使用具有 SNMPv3 的唯一引擎 ID。
推荐阅读
- reactjs - 然而,存储文件被替换,firebase 数据库链接没有更新 React Native
- java - 崩溃后如何将内存转储保存在 kubernetes 集群中?
- flask - 为什么 render_template 一直显示烧瓶表单的旧值?
- reactjs - npm 运行构建命令“未安装包”中的错误
- asp.net - Asp.net WebApi - CORS 策略
- angular - “元素”类型上不存在属性“元素” ANGULAR
- android - 绑定适配器 - 在回收站视图中找不到 LiveData 变量的设置器
- python - Pythonw批处理文件仍然显示控制台
- javascript - 如何在nodejs中使用knexjs onConflict和merge方法插入
- node.js - Mongodb将嵌套数组字段填充为对象