[SNMP4J] random problem sending command over TCP
Brice Fines
bfines at sermepa.es
Thu Nov 5 11:32:37 CET 2009
Hi Frank,
No, it seems we are not using
TransportStateListener.connectionStateChanged (I could not find any
reference to TransportStateListener in the whole code).
We use SNMP4J in a straight forward way: configure and init an SNMP object
for the whole application life, use it to send commands.
Please find enclosed the source for the class we use (to send a command we
call the "sendCommand" method, that's where the application hangs (but
only a few times, it works ok 99% of the time)
(I still have to check with version 1.10.2, hope to be able to do it soon)
Thanks
import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.CounterListener;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.CounterSupport;
import org.snmp4j.mp.DefaultCounterListener;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import aaa.bbbbbb.xxxxx.business.channel.ControlChannel;
import aaa.bbbbbb.xxxxx.business.dialog.ComandosResolver;
import aaa.bbbbbb.xxxxx.commands.Comando;
import aaa.bbbbbb.xxxxx.exceptions.AccesoDenegadoException;
import aaa.bbbbbb.xxxxx.exceptions.ClientUnreachableException;
import aaa.bbbbbb.xxxxx.exceptions.CommandNotFoundException;
import aaa.bbbbbb.xxxxx.exceptions.InternalErrorException;
import aaa.bbbbbb.xxxxx.exceptions.RespuestaErrorGenerico;
import aaa.bbbbbb.xxxxx.exceptions.RespuestaInvalidaException;
import aaa.bbbbbb.xxxxx.exceptions.SintaxisIncorrectaException;
import aaa.bbbbbb.xxxxx.model.Client;
import aaa.bbbbbb.xxxxx.util.log4j.SourcesLogger;
public class SnmpChannel implements ControlChannel {
private SourcesLogger logger = new SourcesLogger(getClass());
private String commandPort = "/161";
public void setCommandPort(String commandPort) {
this.commandPort = commandPort;
}
private int timeout = 10 * 1000;
public void setTimeout(int timeout) {
this.timeout = timeout * 1000;
}
private int retries = 3;
public void setRetries(int retries) {
this.retries = retries;
}
private String community = "ppp";
public void setCommunity(String community) {
this.community = community;
}
private boolean soportaVersion3 = false;
public void setV3(boolean soportaVersion3) {
this.soportaVersion3 = soportaVersion3;
}
private String securityName = "";
public void setSecurityName(String securityName) {
this.securityName = securityName;
}
private String authProtocol = "";
public void setAuthProtocol(String authProtocol) {
this.authProtocol = authProtocol;
}
private String authPassphrase = "";
public void setAuthPassphrase(String authPassphrase) {
this.authPassphrase = authPassphrase;
}
private String privProtocol = "";
public void setPrivProtocol(String privProtocol) {
this.privProtocol = privProtocol;
}
private String privPassphrase = "";
public void setPrivPassphrase(String privPassphrase) {
this.privPassphrase = privPassphrase;
}
private Control2SNMP snmpConversionService;
public void setControl2SNMP(Control2SNMP snmpConversionService) {
this.snmpConversionService = snmpConversionService;
}
private ComandosResolver theComandosResolver;
public void setComandosResolver(ComandosResolver
comandosResolver){
theComandosResolver = comandosResolver;
}
private Snmp snmp;
private final CounterListener counterListener = new
DefaultCounterListener();
private TransportMapping transportMapping;
public boolean startup() {
try {
logger.getLogger().warn(
logger.fromServer("Starting
SNMP"));
CounterSupport.getInstance().addCounterListener(counterListener);
snmp = createSnmpSession();
snmp.listen();
logger
.getLogger()
.warn(
logger
.fromServer("SNMP started"));
return true;
} catch (Exception exception) {
logger.getLogger().error(logger.fromServer(exception.toString()));
exception.printStackTrace();
return false;
}
}
public void shutdown() {
try {
logger.getLogger().warn(
logger.fromServer("closing
SNMP"));
CounterSupport.getInstance().removeCounterListener(counterListener);
snmp.close();
} catch (Exception exception) {
logger.getLogger().warn(logger.fromServer(exception.toString()));
exception.printStackTrace();
}
}
public Comando sendCommand(Client client, Comando comando)
throws ClientUnreachableException,
AccesoDenegadoException,
SintaxisIncorrectaException,
RespuestaInvalidaException, CommandNotFoundException,
RespuestaErrorGenerico, InternalErrorException
{
final ResponseEvent responseEvent ;
try {
final PDU pdu = comando2PDU(comando);
if(pdu == null){
throw new InternalErrorException("PDU not
found");
}
final String ip = client.getIp();
final Target target = createTarget(ip);
responseEvent = snmp.send(pdu, target);
} catch (Exception e) {
throw new InternalErrorException("Exception with
command: " + e + " " + e.getMessage());
}
if (responseEvent == null) {
throw new ClientUnreachableException("Answer
null");
}
if (responseEvent.getResponse() == null) {
throw new ClientUnreachableException("Answer
null");
}
final PDU pduResponse = responseEvent.getResponse();
if(pduResponse.getType() != PDU.REPORT
&& pduResponse.getType() != PDU.RESPONSE){
throw new RespuestaInvalidaException("Unknown
answer: pduResponse.getType()= " +
pduResponse.getType());
}
if (pduResponse.getType() == PDU.REPORT) {
throw new AccesoDenegadoException("SNMP REPORT: "
+ pduResponse.toString());
}
if (pduResponse.getErrorStatus() != PDU.noError) {
if (pduResponse.getErrorStatus() ==
PDU.authorizationError) {
throw new AccesoDenegadoException("SNMP
answer: autorizationError status");
}
if(pduResponse.getErrorStatus() == PDU.badValue){
throw new
SintaxisIncorrectaException("SNMP answer: badValue status");
}
if(pduResponse.getErrorStatus() == PDU.noSuchName
|| pduResponse.getErrorStatus() ==
PDU.readOnly){
throw new CommandNotFoundException("SNMP
answer: noSuchName/readOnly status");
}
boolean posibleMsgError =
pduResponse.getErrorStatus() == PDU.genErr && !comando.isGet()? true :
false;
throw new RespuestaErrorGenerico(posibleMsgError,
"SNMP answer: " +
pduResponse.getErrorStatusText());
}
if (pduResponse.getVariableBindings().size() == 0) {
throw new RespuestaInvalidaException("SNMP answer
with no varBind");
}
try{
final VariableBinding variableBinding =
pduResponse.get(0);
String res =
snmpConversionService.getStringValue(variableBinding);
comando.setResultado(res);
return comando;
}catch(Exception e){
throw new RespuestaInvalidaException("Exception
parsing answer: "+ e + " " +e.getMessage());
}
}
private Snmp createSnmpSession() throws IOException {
logger.getLogger().debug(logger.fromServer("Creating SNMP
session"));
transportMapping = new DefaultTcpTransportMapping();
final Snmp snmp = new Snmp(transportMapping);
if (soportaVersion3) {
final USM usm = new
USM(SecurityProtocols.getInstance(),
new
OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
addUsmUser(snmp);
logger.getLogger().debug(
logger.fromServer("SNMP session
created"));
}
return snmp;
}
private void addUsmUser(Snmp snmp) {
logger.getLogger().debug(
logger.fromServer("Creating SNMP user " +
securityName
+ ", Protocolo " +
authProtocol));
snmp.getUSM().addUser(
new OctetString(securityName),
new UsmUser(new OctetString(securityName),
authProtocol
.equals("MD5") ?
AuthMD5.ID : AuthSHA.ID,
authPassphrase.length() !=
0 ? new OctetString(
authPassphrase) : null,
privProtocol.length() != 0
? PrivDES.ID : null,
privPassphrase.length() !=
0 ? new OctetString(
privPassphrase) : null));
}
private Target createTarget(String ip) {
Target target = null;
if (soportaVersion3) {
target = createSecuredUserTarget(ip);
} else {
target = createCommunityTarget(ip);
}
target.setTimeout(timeout);
target.setRetries(retries);
return target;
}
private Target createSecuredUserTarget(String ip) {
final UserTarget userTarget = new UserTarget();
if (authPassphrase != null && authPassphrase.length() !=
0) {
if (privPassphrase != null &&
privPassphrase.length() != 0) {
userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
} else {
userTarget.setSecurityLevel(SecurityLevel.AUTH_NOPRIV);
}
} else {
userTarget.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
}
userTarget.setSecurityName(new OctetString(securityName));
userTarget.setVersion(SnmpConstants.version3);
userTarget.setAddress(new TcpAddress(ip + commandPort));
return userTarget;
}
private Target createCommunityTarget(String ip) {
final CommunityTarget communityTarget = new
CommunityTarget();
communityTarget.setCommunity(new OctetString(community));
communityTarget.setAddress(new TcpAddress(ip +
commandPort));
return communityTarget;
}
private PDU comando2PDU(Comando cmd) {
final PDU pdu = soportaVersion3 ? new ScopedPDU() : new
PDU();
pdu.setType(cmd.isGet() ? PDU.GET : PDU.SET);
final String mibId =
theComandosResolver.getMibIdFromDBCodigo(cmd.getCodigoComando());
if(mibId == null){
return null;
}
final OID oid = snmpConversionService.findOID(mibId);
if(oid == null){
return null;
}
final VariableBinding variableBinding = new
VariableBinding(oid);
if (cmd.isGet() == false) {
variableBinding.setVariable(snmpConversionService
.createSNMPVariable(cmd.getParam()));
}
pdu.add(variableBinding);
return pdu;
}
}
More information about the SNMP4J
mailing list