Hi Frank,
Hope you are well. I implemented SNMPv3 GET using snmp4j but the same SNMP initialization, usmUser, and userTarget found no success for SNMPv3 SET. Here is my error messages:
**ErrorStatusText:Authorization error **
**ErrorIndex:0 **
ErrorStatus:16
Based on what I found online, it seemed to be that the SNMP manager might not have the same priv/auth level or passphrase as the SNMP agent. However, I’ve tried to initialize SNMP request before every SET request to ensure SNMP communication setting are the same. Don’t know if I miss something???
Here is my code snippets:
public class OIDEntryV3{
// snmpV3 preset: user name, password, delay... etc
public static int pduOutlet_num = 8;
public static String securityName = "V3user1";
public static String authPassphrase = "HelloWorld";
public static String privPassphrase = "Qwert12345";
public static String single_oid = "00000";
public static String setNum = "3";
public static int requestDelay = 3;
public static int delayOn = 1;
public static int delayOff = 2;
public static String init_contextName = "OHHHYeah";
public UsmUser usmUser = new UsmUser(new OctetString(securityName),
AuthMD5.ID, new OctetString(authPassphrase),
PrivDES.ID, new OctetString(privPassphrase));
public Snmp snmp;
public USM usm;
public static Target<Address> userTarget = new UserTarget<>();
private static boolean snmpv3SetCommSetup = false;
private static boolean snmpv3GetCommSetup = false;
private String udpAddressInfo;
private int timeIndex = requestDelay;
private String contextName = init_contextName;
private String [] oids;
private ScopedPDU setScopedPDU, getScopedPDU;
private int attempt_num = 1; // how many time the for loop to do snmpV3 comm
//constructor of OIDEntryV3 input
public OIDEntryV3(String udpAddressInfo, int timeIndex, String contextName, String... oids)
{
this.udpAddressInfo = udpAddressInfo;
this.timeIndex = timeIndex;
this.contextName = contextName;
this.oids = oids;
}
public OIDEntryV3(String udpAddressInfo, String... oids)
{
this.udpAddressInfo = udpAddressInfo;
this.oids = oids;
}
private static Logger logger = LoggerFactory.getLogger(OIDEntryV3.class);
// initialize SNMPV3 communication
public void initSnmpV3() throws IOException {
snmp = new Snmp();
snmp.getMessageDispatcher().addCommandResponder(new CommandResponder() {
@Override
public <A extends Address> void processPdu(CommandResponderEvent<A> commandResponderEvent) {
}
});
// Very important to add snmp as command responder which will finally process the PDU:
snmp.getMessageDispatcher().addCommandResponder(snmp);
snmp.addTransportMapping(new DefaultUdpTransportMapping(new UdpAddress(0)));
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthMD5());
SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthSHA());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivDES());
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES128());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES192());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES256());
OctetString localEngineID = new OctetString(MPv3.createLocalEngineID());
usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3(usm.getLocalEngineID().getValue()));
snmp.listen();
usm.addUser(usmUser);
Address targetAddress = GenericAddress.parse(udpAddressInfo);
userTarget.setAddress(targetAddress);
userTarget.setVersion(SnmpConstants.version3);
userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
userTarget.setSecurityName(usmUser.getSecurityName());
userTarget.setRetries(3);
userTarget.setTimeout(500);
}
//SCOPED PDU for SNMP GET
public ScopedPDU getScopedPDU(){
List<VariableBinding> oidList = new ArrayList<>(oids.length);
// only need to assign ScopedPDU once
if(getScopedPDU == null){
getScopedPDU = new ScopedPDU();
for (String objectID : oids){
oidList.add(new VariableBinding(new OID(objectID)));
}
getScopedPDU.addAll(oidList);
getScopedPDU.setType(PDU.GET);
}
return getScopedPDU;
}
// ScopedPDU for snmpV3 SET
public ScopedPDU setScopedPDU(){
List<VariableBinding> oidList = new ArrayList<>(oids.length);
// only need to assign ScopedPDU once
if(setScopedPDU == null){
setScopedPDU = new ScopedPDU();
for (String objectID : oids){
oidList.add(new VariableBinding( new OID(objectID), new Integer32(timeIndex) ));
}
setScopedPDU.addAll(oidList);
//set port name etc...
setScopedPDU.setContextName(new OctetString(contextName));
setScopedPDU.setType(PDU.SET);
}
return setScopedPDU;
}
private String getVal;
public String getSnmpV3Req()throws IOException {
if(!snmpv3GetCommSetup)
{
try
{
initSnmpV3();
//snmpv3GetCommSetup = true;
}
catch(IOException e)
{
System.err.println("SNMPV3 GET initial comm setup fail");
throw e;
}
}
// initialize v3 get scopedPDU
getScopedPDU();
// A ResponseListener object is created to handle the response from the SNMP agent.
// The onResponse method is implemented to extract the variable bindings from the response
// and print the values to the console.
// attempts for snmpv3 get
for (int i = 0; i < attempt_num ; i++)
{
getVal = "Waiting for get value";
try{
//System.out.println("*** for loop i = "+i);
ResponseListener responseListener = new ResponseListener()
{
@Override
// The synchronized block is used to ensure that the responseListener object is not notified
// before it has finished processing the response.
public synchronized <A extends Address> void onResponse(ResponseEvent<A> responseEvent)
{
// cancel the pending SNMP request that was associated with the ResponseEvent object responseEvent,
// and informs the object (this) that was listening for the response that the request has been cancelled
snmp.cancel(responseEvent.getRequest(), this);
// Process response here: gotta format the output values nicely
List<? extends VariableBinding> vBindings = responseEvent.getResponse().getVariableBindings();
System.out.println("----- variable Binding = "+vBindings);
for (VariableBinding vb:vBindings)
{
if (vb.getVariable() != null)
{
getVal = vb.getVariable().toString();
//System.out.println("----- V3 get value = "+vb.getVariable().toString());
}
else
{
//getSNMPCommError = true;
if(responseEvent.getError() != null)
{
System.err.println("Error: "+responseEvent.getError());
}
else
{
System.err.println("Timed out.");
}
}
}
notify();
}
};
synchronized (responseListener)
{
// send snmpv3 get request, using responseListener to catch the response
snmp.get(getScopedPDU, userTarget, null, responseListener);
System.out.println("~~~ ResponseListener = "+responseListener);
try{
responseListener.wait(500000);
}
catch(InterruptedException eee)
{
eee.printStackTrace();
}
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
System.err.println("OIDEntryV3.java: IOException occurred during SNMPv3 GET Communication: " + ioe.getMessage());
try {Thread.sleep(2000);}
catch (InterruptedException e1)
{
e1.printStackTrace();
System.err.println("OIDEntryV3.java: InterruptedException occurred during SNMPv3 GET Communication: " + e1.getMessage());
throw ioe;
}
}
}
/*
if(getSNMPCommError)
{
e.printStackTrace();
throw e;
}*/
return getVal;
}
// set snmpV3 requests
public void setSnmpV3Req() throws IOException
{
//IOException e = null;
//setSNMPCommError = false;
if(!snmpv3SetCommSetup)
{
try
{
initSnmpV3();
//snmpv3SetCommSetup = true;
}
catch(IOException e)
{
System.err.println("SNMPV3 SET initial comm setup fail");
throw e;
}
}
// initialize v3 set scopedPDU
setScopedPDU();
// attempts for snmpv3 set
for (int i = 0; i < attempt_num ; i++)
{
System.out.println("***** setset ");
try
{
ResponseEvent<Address> responseEvent = snmp.send(setScopedPDU, userTarget);
PDU response = responseEvent.getResponse();
List<? extends VariableBinding> response_msg = response.getVariableBindings();
if (response != null)
{
if (response.getErrorStatus() == PDU.noError)
{
//System.out.println("***** set req = " +response_msg);
System.err.println("***** OID command = " +response_msg.get(0).getOid());
System.err.println("***** set command time = " +response_msg.get(0).getVariable());
}
else
{
System.err.println("ErrorStatusText:" + response.getErrorStatusText());
System.err.println("ErrorIndex:" + response.getErrorIndex());
System.err.println("ErrorStatus:" + response.getErrorStatus());
}
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
System.err.println("OIDEntryV3.java: IOException occurred during SNMPv3 SET Communication: " + ioe.getMessage());
try {Thread.sleep(2000);}
catch (InterruptedException e1)
{
e1.printStackTrace();
System.err.println("OIDEntryV3.java: InterruptedException occurred during SNMPv3 SET Communication: " + e1.getMessage());
throw ioe;
}
}
}
/*if(setSNMPCommError)
{
catch(IOException e)
{
System.err.println("OIDEntryV3.java: IOException occurred during SNMPv3 SET Communication: " + e.getMessage());
throw e;
}
}*/
}
}
Sorry for the messy code alignments. Looking forward for your suggestions about this matter. Thank you so much!!
Chester