我正在尝试使用现有的snmp4j库开发能够模拟SNMP设备的SNMPAgent。
public class SNMPAgent extends BaseAgent {
private String address;
/**
*
* @param address
* @throws IOException
*/
public SNMPAgent(String address) throws IOException {
/**
* Creates a base agent with boot-counter, config file, and a
* CommandProcessor for processing SNMP requests. Parameters:
* "bootCounterFile" - a file with serialized boot-counter information
* (read/write). If the file does not exist it is created on shutdown of
* the agent. "configFile" - a file with serialized configuration
* information (read/write). If the file does not exist it is created on
* shutdown of the agent. "commandProcessor" - the CommandProcessor
* instance that handles the SNMP requests.
*/
super(new File("./conf.agent"), new File("./bootCounter.agent"),
new CommandProcessor(
new OctetString(MPv3.createLocalEngineID())));
this.address = address;
}
/**
* Adds community to security name mappings needed for SNMPv1 and SNMPv2c.
*/
@Override
public void addCommunities(SnmpCommunityMIB communityMIB) {
Variable[] com2sec = new Variable[] { new OctetString("public"),
new OctetString("cpublic"), // security name
getAgent().getContextEngineID(), // local engine ID
new OctetString("public"), // default context name
new OctetString(), // transport tag
new Integer32(StorageType.nonVolatile), // storage type
new Integer32(RowStatus.active) // row status
};
MOTableRow row = communityMIB.getSnmpCommunityEntry().createRow(
new OctetString("public2public").toSubIndex(true), com2sec);
communityMIB.getSnmpCommunityEntry().addRow((SnmpCommunityMIB.SnmpCommunityEntryRow) row);
}
/**
* Adds initial notification targets and filters.
*/
@Override
protected void addNotificationTargets(SnmpTargetMIB arg0,
SnmpNotificationMIB arg1) {
// TODO Auto-generated method stub
}
/**
* Adds all the necessary initial users to the USM.
*/
@Override
protected void addUsmUser(USM arg0) {
// TODO Auto-generated method stub
}
/**
* Adds initial VACM configuration.
*/
@Override
public void addViews(VacmMIB vacm) {
vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c, new OctetString(
"cpublic"), new OctetString("v1v2group"),
StorageType.nonVolatile);
vacm.addAccess(new OctetString("v1v2group"), new OctetString("public"),
SecurityModel.SECURITY_MODEL_ANY, SecurityLevel.NOAUTH_NOPRIV,
MutableVACM.VACM_MATCH_EXACT, new OctetString("fullReadView"),
new OctetString("fullWriteView"), new OctetString(
"fullNotifyView"), StorageType.nonVolatile);
vacm.addViewTreeFamily(new OctetString("fullReadView"), new OID("1.3"),
new OctetString(), VacmMIB.vacmViewIncluded,
StorageType.nonVolatile);
}
/**
* Unregister the basic MIB modules from the agent's MOServer.
*/
@Override
protected void unregisterManagedObjects() {
// TODO Auto-generated method stub
}
/**
* Register additional managed objects at the agent's server.
*/
@Override
protected void registerManagedObjects() {
// TODO Auto-generated method stub
}
protected void initTransportMappings() throws IOException {
transportMappings = new TransportMapping[1];
Address addr = GenericAddress.parse(address);
TransportMapping tm = TransportMappings.getInstance()
.createTransportMapping(addr);
transportMappings[0] = tm;
}
/**
* Start method invokes some initialization methods needed to start the
* agent
*
* @throws IOException
*/
public void start() throws IOException {
init();
// This method reads some old config from a file and causes
// unexpected behavior.
// loadConfig(ImportModes.REPLACE_CREATE);
addShutdownHook();
getServer().addContext(new OctetString("public"));
finishInit();
run();
sendColdStartNotification();
}
/**
* Clients can register the MO they need
*/
public void registerManagedObject(ManagedObject mo) {
try {
server.register(mo, null);
} catch (DuplicateRegistrationException ex) {
throw new RuntimeException(ex);
}
}
public void unregisterManagedObject(MOGroup moGroup) {
moGroup.unregisterMOs(server, getContext(moGroup));
}
}
当我尝试注册具有给定值
的新oid时,它当前有效 SNMPAgent testAgent = new SNMPAgent(ip+"/"+port);
testAgent.start();
testAgent.unregisterManagedObject(testAgent.getSnmpv2MIB());
MOScalar editableScalar = MOCreator.createScalarEditable(new OID(oidval), new Integer32(48));
testAgent.registerManagedObject(editableScalar);
以及当我想查询相同(并已注册)的oid
时 Optional<PDU> get = sender.sendGet(community, ip, port, "1.3.6.1.4.1.2011.2.1.2.1", 2, 1000L);
我的麻烦是设置功能应该覆盖oid中的现有值,但不起作用。我正在使用它如下:
Integer32 intVal = new Integer32(28);
Optional<PDU> set = sender.sendSet(community, ip, port, "1.3.6.1.4.1.2011.2.1.2.1", intVal, 2, 1000L);
发件人对象是从SNMPSender类实例化的。 sendSet方法的关键部分如下:
CommunityTarget comtarget = new CommunityTarget();
comtarget.setCommunity(new OctetString(community));
comtarget.setVersion(snmpVersion);
comtarget.setAddress(new UdpAddress(ipAddress + "/" + port));
comtarget.setRetries(retries);
comtarget.setTimeout(timeoutMillis);
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(oidValue),setValue));
pdu.setType(PDU.SET);
ResponseEvent response = snmp.set(pdu, comtarget);
最后,snmp是来自calmp Snmp的对象。 .set方法有什么作用?
public ResponseEvent set(PDU pdu, Target target) throws IOException {
pdu.setType(PDU.SET);
return send(pdu, target);
}
它调用执行get时调用的相同send方法,即使使用深度调试,我也无法弄清楚如何使其工作。
我们在一个真实的节点上尝试过SNMPSender并且它有效,所以我假设SNMPAgent一定有问题。此外,在检查ResponseEvent响应对象时,响应参数为null