I'm trying to create a standalone java application to send SNMP v3 Traps along with engineId.
I'm using snmp4j 2.5.3 and Java 1.8
Below is the code snippet which I am using.
When I provide engineId while addUser, it throws "Message processing model 3 returned error: Unknown security name".
When I remove, it works fine. But, my SNMP manager not recognizing the Trap.
// Sample code snippet
Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/" + port);
TransportMapping<?> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(),
new OctetString(MPv3.createLocalEngineID(new OctetString(engineId))), 0);
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES192());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES256());
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
SecurityModels.getInstance().addSecurityModel(usm);
switch (securityLevel) {
case SecurityLevel.NOAUTH_NOPRIV:
snmp.getUSM().addUser(new OctetString(username), new OctetString(engineId), new UsmUser(new OctetString(username), null,
null, null, null));
break;
case SecurityLevel.AUTH_NOPRIV:
snmp.getUSM().addUser(new OctetString(username), new OctetString(engineId), new UsmUser(new OctetString(username), auth,
new OctetString(authpassPhrase), null, null));
break;
case SecurityLevel.AUTH_PRIV:
snmp.getUSM().addUser(new OctetString(username), new OctetString(engineId), new UsmUser(new OctetString(username), auth,
new OctetString(authpassPhrase), privacy, new OctetString(privacypassPhrase)));
break;
default:
System.err.println("Undefined Security level for SNMP v3");
System.exit(1);
}
UserTarget target = new UserTarget();
target.setAddress(targetAddress);
target.setRetries(1);
target.setTimeout(5000);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(securityLevel);
target.setSecurityName(new OctetString(username));
ScopedPDU pdu = new ScopedPDU();
pdu.setType(ScopedPDU.NOTIFICATION);
pdu.setRequestID(new Integer32(1234));
pdu.add(new VariableBinding(SnmpConstants.sysUpTime));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, SnmpConstants.linkDown));
pdu.add(new VariableBinding(new OID(Oid), new Integer32(123)));
snmp.send(pdu, target);
System.out.println("Sending Trap to (IP:Port)=> " + ipAddress + ":" + port);
snmp.close();
I expect the SNMP Manager should recognize the Trap and it should be received at SNMP Manager.
What am I missing here?
Thanks in advance.
I had the same issue. I was using snmp4j 2.5.3 and Java 1.7. You can use a higher version of snmp4j lib with Java 1.8.
So when you add a user to USM with an engine id and send the Pdu, this engine id is not actually used to extract the UsmUserEntry from the userTable. In fact the localEngineID is used to extract the UsmUserEntry. Hence the UsmUserEntry object becomes null and you get an exception as "Message processing model 3 returned error: Unknown security name".
So you need to provide the same engine id to local engine id as well.
Try the following.
Let's say your engine id is "12345".
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
//Add engine id while addinf user
snmp.getUSM().addUser(new OctetString(username), new OctetString("12345"),
new UsmUser(new OctetString(username), AuthSHA.ID, new OctetString(authpassphrase), PrivAES192.ID, new OctetString(privacypassphrase)));
//set the same engine to localEngineId
snmp.setLocalEngine(new OctetString("12345").getValue(),0,0);
Good luck!