java - 如何使用 snmp4j-2.7.0 在 snmpv3 中获取系统信息
问题描述
我正在尝试创建小型应用程序来管理 snmp 设备,并且首先我想获取系统信息。
我使用的是 snmp4j 版本 2.7.0、java 1.8,设备使用 snmpv3。首先,我想同步获取数据。我尝试以两种方式做到这一点,但我一直在抽空
这是我的代码
//Normal request
public class SynchronouslySnmp
{
protected String PORT="/161";
protected String PROTOCOL="udp:";
protected SnmpData snmpData;
protected Snmp snmp;
public SynchronouslySnmp(SnmpData snmpData)
{
this.snmpData=snmpData;
}
public void start()
{
createSNMPsession();
addSnmpUser();
sendSnmp();
}
private void sendSnmp()
{
// send the PDU
ResponseEvent response;
try
{
response = snmp.send(getPDU(), getTarget());
// extract the response PDU (could be null if timed out)
PDU responsePDU = response.getResponse();
// extract the address used by the agent to send the response:
if(responsePDU == null)
{
System.out.println("ERROR: table OID [" + SnmpContants.system + "] time out" );
}
else
{
Address peerAddress = response.getPeerAddress();
System.out.println("pdu: "+responsePDU.toString());
System.out.println("Address: "+peerAddress.toString());
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
snmp.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
protected void createSNMPsession()
{
TransportMapping<? extends Address> transport;
try
{
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();
//snmp.listen();
}
catch (IOException e)
{
e.printStackTrace();
}
}
protected void addSnmpUser()
{
// add user to the USM
snmp.getUSM().addUser(new OctetString(snmpData.getUsmUser()),
new UsmUser(new OctetString(snmpData.getUsmUser()),
snmpData.getAuthProtocol(),
new OctetString(snmpData.getAuthPassword()),
snmpData.getPrivProtocol(),
new OctetString(snmpData.getPrivPassword())));
}
protected Target getTarget()
{
// create the target
UserTarget target = new UserTarget();
Address targetAddress = GenericAddress.parse(PROTOCOL+snmpData.getIpAddress()+PORT);
target.setAddress(targetAddress);
target.setRetries(snmpData.getRetryTimes());
target.setTimeout(snmpData.getTimeout());
target.setVersion(snmpData.getSnmpVersion());
target.setSecurityLevel(snmpData.getSecurityLevel());
target.setSecurityName(new OctetString(snmpData.getUsmUser()));
return target;
}
protected PDU getPDU()
{
// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(SnmpConstants.system));
pdu.setType(PDU.GETBULK);
return pdu;
}
}
我尝试使用treeUtil,但得到与正常请求相同的错误,以下是我的代码
public class SynchronouslySnmpUsingTree extends SynchronouslySnmp
{
private OID tableOid;
private LinkedHashMap<String, List<VariableBinding>> resultMap;
public SynchronouslySnmpUsingTree(SnmpData snmpData)
{
super(snmpData);
resultMap = new LinkedHashMap<String, List<VariableBinding>>();
tableOid=new OID(".1.3.6.1.2.1.1");
createSNMPsession();
addSnmpUser();
sendSnmp();
}
private void sendSnmp()
{
try
{
TreeUtils treeUtils = new TreeUtils(snmp, new PDUFactory()
{
@Override
public PDU createPDU(MessageProcessingModel arg0) {
return getPDU();
}
@Override
public PDU createPDU(Target arg0) {
return getPDU();
}
});
List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
if (events == null || events.size() == 0)
{
System.out.println("Error: Unable to read table...");
return;
}
for (TreeEvent event : events)
{
if (event != null && !event.isError())
{
VariableBinding[] varBindings = event.getVariableBindings();
if (varBindings != null && varBindings.length != 0)
{
for (VariableBinding varBinding : varBindings)
{
if (varBinding != null)
{
OID oid = varBinding.getOid();
List<VariableBinding> binds = resultMap.get(oid.toString());
if( binds == null)
{
binds = new ArrayList<VariableBinding>();
resultMap.put(oid.toString(), binds);
}
binds.add(varBinding);
}
}
}
}
else
{
System.out.println("Error: table OID [" + tableOid + "] " + event.getErrorMessage());
continue;
}
}
}
catch(Throwable t)
{
System.out.println("Failed operation: getMibTableWithNext");
t.printStackTrace();
}
finally
{
try
{
snmp.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
主功能
public static void main(String[] args){
SynchronouslySnmp synchronouslySnmp =new SynchronouslySnmp (new SnmpData());
synchronouslySnmp.start();
SynchronouslySnmpUsingTree synchronouslySnmpUsingTree = new SynchronouslySnmpUsingTree(new SnmpData());
}
运行程序的结果
Error: table OID [1.3.6.1.2.1.1] time out); <---nurmal
Error: table OID [1.3.6.1.2.1.1] Request time out); <---tree
我看https://www.snmp4j.org/html/faq.html
为什么我在发送请求时总是超时(响应 == null)?
可能您在发送请求之前忘记调用TransportMapping(一次)或Snmp 类的listen() 方法。
但是我在 createSNMPsession() 方法中这样做了,那我做错了什么?谢谢。:)
解决方案
因此,在我绞尽脑汁一整天之后,任何需要知道如何将 SNMPV3 与 SNMP4J 一起使用的人都可以得到答案。
让我们从正常的请求开始。问题是我使用带有 GETBULK 的 PDU,但我没有设置最大重复次数,所以默认值为 0,我得到了空的 VBS
修复它只需使用:
protected PDU getPDU()
{
// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(SnmpConstants.system));
pdu.setType(PDU.GETBULK);
pdu.setMaxRepetitions(10);//or any number you wish
return pdu;
}
对于树问题,无需定义最大重复次数,这是 getSubTree 的全部要点。所以问题是我将timeOut in sec设置为30而不是millisec设置为30000愚蠢的错误。但后来我得到更大的错误“代理没有按字典顺序返回变量绑定”。我用墙来修复它:
treeUtils.setIgnoreLexicographicOrder(true);
List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
if (events == null || events.size() == 0)
{
System.out.println("Error: Unable to read table...");
return;
}
.
.
.
if( binds == null)
{
binds = new ArrayList<VariableBinding>();
binds.add(varBinding);
resultMap.put(oid.toString(), binds);
}
推荐阅读
- javascript - 自定义 vue.js 复选框绑定数组引发“避免直接改变道具......”我应该如何实现这个?
- c++ - 在 Ubuntu 中使用 C++ 将网络摄像头与 OpenCV 和 OpenGL 集成?
- c# - 是否可以从 GitHub 为基于 .NET Core Angular 模板的 Web 应用程序在 Azure 中设置持续集成?
- python - 在 python 中更改 URL 中的日期以获取请求
- java - 观看 /zookeeper/config 更改以更新馆长连接字符串是个好主意吗?
- azure - 如何将 X509 pfx 证书作为证书上传到 azure keyvault?
- bash - 如何通过 for 循环使用所有内核
- docker - 在 docker 容器上设置 awslogs 日志驱动程序
- postgresql - 如何开放对部署在 okteto 上的 postgresql 的公共访问?
- r - 将持续时间拆分为年度部分