You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2747 lines
89 KiB
2747 lines
89 KiB
/*
|
|
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
package com.sun.jmx.snmp.daemon;
|
|
|
|
|
|
// java imports
|
|
//
|
|
import java.util.Vector;
|
|
import java.util.Enumeration;
|
|
import java.util.logging.Level;
|
|
import java.net.DatagramSocket;
|
|
import java.net.DatagramPacket;
|
|
import java.net.InetAddress;
|
|
import java.net.SocketException;
|
|
import java.net.UnknownHostException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InterruptedIOException;
|
|
|
|
|
|
// jmx imports
|
|
//
|
|
import javax.management.MBeanServer;
|
|
import javax.management.MBeanRegistration;
|
|
import javax.management.ObjectName;
|
|
import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
|
|
import com.sun.jmx.snmp.SnmpIpAddress;
|
|
import com.sun.jmx.snmp.SnmpMessage;
|
|
import com.sun.jmx.snmp.SnmpOid;
|
|
import com.sun.jmx.snmp.SnmpPduFactory;
|
|
import com.sun.jmx.snmp.SnmpPduPacket;
|
|
import com.sun.jmx.snmp.SnmpPduRequest;
|
|
import com.sun.jmx.snmp.SnmpPduTrap;
|
|
import com.sun.jmx.snmp.SnmpTimeticks;
|
|
import com.sun.jmx.snmp.SnmpVarBind;
|
|
import com.sun.jmx.snmp.SnmpVarBindList;
|
|
import com.sun.jmx.snmp.SnmpDefinitions;
|
|
import com.sun.jmx.snmp.SnmpStatusException;
|
|
import com.sun.jmx.snmp.SnmpTooBigException;
|
|
import com.sun.jmx.snmp.InetAddressAcl;
|
|
import com.sun.jmx.snmp.SnmpPeer;
|
|
import com.sun.jmx.snmp.SnmpParameters;
|
|
// SNMP Runtime imports
|
|
//
|
|
import com.sun.jmx.snmp.SnmpPduFactoryBER;
|
|
import com.sun.jmx.snmp.agent.SnmpMibAgent;
|
|
import com.sun.jmx.snmp.agent.SnmpMibHandler;
|
|
import com.sun.jmx.snmp.agent.SnmpUserDataFactory;
|
|
import com.sun.jmx.snmp.agent.SnmpErrorHandlerAgent;
|
|
|
|
import com.sun.jmx.snmp.IPAcl.SnmpAcl;
|
|
|
|
import com.sun.jmx.snmp.tasks.ThreadService;
|
|
|
|
/**
|
|
* Implements an adaptor on top of the SNMP protocol.
|
|
* <P>
|
|
* When this SNMP protocol adaptor is started it creates a datagram socket
|
|
* and is able to receive requests and send traps or inform requests.
|
|
* When it is stopped, the socket is closed and neither requests
|
|
* and nor traps/inform request are processed.
|
|
* <P>
|
|
* The default port number of the socket is 161. This default value can be
|
|
* changed by specifying a port number:
|
|
* <UL>
|
|
* <LI>in the object constructor</LI>
|
|
* <LI>using the {@link com.sun.jmx.snmp.daemon.CommunicatorServer#setPort
|
|
* setPort} method before starting the adaptor</LI>
|
|
* </UL>
|
|
* The default object name is defined by {@link
|
|
* com.sun.jmx.snmp.ServiceName#DOMAIN com.sun.jmx.snmp.ServiceName.DOMAIN}
|
|
* and {@link com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
|
|
* com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
|
|
* <P>
|
|
* The SNMP protocol adaptor supports versions 1 and 2 of the SNMP protocol
|
|
* in a stateless way: when it receives a v1 request, it replies with a v1
|
|
* response, when it receives a v2 request it replies with a v2 response.
|
|
* <BR>The method {@link #snmpV1Trap snmpV1Trap} sends traps using SNMP v1
|
|
* format.
|
|
* The method {@link #snmpV2Trap snmpV2Trap} sends traps using SNMP v2 format.
|
|
* The method {@link #snmpInformRequest snmpInformRequest} sends inform
|
|
* requests using SNMP v2 format.
|
|
* <P>
|
|
* To receive data packets, the SNMP protocol adaptor uses a buffer
|
|
* which size can be configured using the property <CODE>bufferSize</CODE>
|
|
* (default value is 1024).
|
|
* Packets which do not fit into the buffer are rejected.
|
|
* Increasing <CODE>bufferSize</CODE> allows the exchange of bigger packets.
|
|
* However, the underlying networking system may impose a limit on the size
|
|
* of UDP packets.
|
|
* Packets which size exceed this limit will be rejected, no matter what
|
|
* the value of <CODE>bufferSize</CODE> actually is.
|
|
* <P>
|
|
* An SNMP protocol adaptor may serve several managers concurrently. The
|
|
* number of concurrent managers can be limited using the property
|
|
* <CODE>maxActiveClientCount</CODE>.
|
|
* <p>
|
|
* The SNMP protocol adaptor specifies a default value (10) for the
|
|
* <CODE>maxActiveClientCount</CODE> property. When the adaptor is stopped,
|
|
* the active requests are interrupted and an error result is sent to
|
|
* the managers.
|
|
* <p><b>This API is a Sun Microsystems internal API and is subject
|
|
* to change without notice.</b></p>
|
|
*/
|
|
|
|
public class SnmpAdaptorServer extends CommunicatorServer
|
|
implements SnmpAdaptorServerMBean, MBeanRegistration, SnmpDefinitions,
|
|
SnmpMibHandler {
|
|
|
|
// PRIVATE VARIABLES
|
|
//------------------
|
|
|
|
/**
|
|
* Port number for sending SNMP traps.
|
|
* <BR>The default value is 162.
|
|
*/
|
|
private int trapPort = 162;
|
|
|
|
/**
|
|
* Port number for sending SNMP inform requests.
|
|
* <BR>The default value is 162.
|
|
*/
|
|
private int informPort = 162;
|
|
|
|
/**
|
|
* The <CODE>InetAddress</CODE> used when creating the datagram socket.
|
|
* <BR>It is specified when creating the SNMP protocol adaptor.
|
|
* If not specified, the local host machine is used.
|
|
*/
|
|
InetAddress address = null;
|
|
|
|
/**
|
|
* The IP address based ACL used by this SNMP protocol adaptor.
|
|
*/
|
|
private InetAddressAcl ipacl = null;
|
|
|
|
/**
|
|
* The factory object.
|
|
*/
|
|
private SnmpPduFactory pduFactory = null;
|
|
|
|
/**
|
|
* The user-data factory object.
|
|
*/
|
|
private SnmpUserDataFactory userDataFactory = null;
|
|
|
|
/**
|
|
* Indicates if the SNMP protocol adaptor sends a response in case
|
|
* of authentication failure
|
|
*/
|
|
private boolean authRespEnabled = true;
|
|
|
|
/**
|
|
* Indicates if authentication traps are enabled.
|
|
*/
|
|
private boolean authTrapEnabled = true;
|
|
|
|
/**
|
|
* The enterprise OID.
|
|
* <BR>The default value is "1.3.6.1.4.1.42".
|
|
*/
|
|
private SnmpOid enterpriseOid = new SnmpOid("1.3.6.1.4.1.42");
|
|
|
|
/**
|
|
* The buffer size of the SNMP protocol adaptor.
|
|
* This buffer size is used for both incoming request and outgoing
|
|
* inform requests.
|
|
* <BR>The default value is 1024.
|
|
*/
|
|
int bufferSize = 1024;
|
|
|
|
private transient long startUpTime = 0;
|
|
private transient DatagramSocket socket = null;
|
|
transient DatagramSocket trapSocket = null;
|
|
private transient SnmpSession informSession = null;
|
|
private transient DatagramPacket packet = null;
|
|
transient Vector<SnmpMibAgent> mibs = new Vector<>();
|
|
private transient SnmpMibTree root;
|
|
|
|
/**
|
|
* Whether ACL must be used.
|
|
*/
|
|
private transient boolean useAcl = true;
|
|
|
|
|
|
// SENDING SNMP INFORMS STUFF
|
|
//---------------------------
|
|
|
|
/**
|
|
* Number of times to try an inform request before giving up.
|
|
* The default number is 3.
|
|
*/
|
|
private int maxTries = 3 ;
|
|
|
|
/**
|
|
* The amount of time to wait for an inform response from the manager.
|
|
* The default amount of time is 3000 millisec.
|
|
*/
|
|
private int timeout = 3 * 1000 ;
|
|
|
|
// VARIABLES REQUIRED FOR IMPLEMENTING SNMP GROUP (MIBII)
|
|
//-------------------------------------------------------
|
|
|
|
/**
|
|
* The <CODE>snmpOutTraps</CODE> value defined in MIB-II.
|
|
*/
|
|
int snmpOutTraps=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpOutGetResponses=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpOutGenErrs=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpOutBadValues=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpOutNoSuchNames=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpOutTooBigs=0;
|
|
|
|
/**
|
|
* The <CODE>snmpOutPkts</CODE> value defined in MIB-II.
|
|
*/
|
|
int snmpOutPkts=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInASNParseErrs=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInBadCommunityUses=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInBadCommunityNames</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInBadCommunityNames=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInBadVersions=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInGetRequests=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInGetNexts=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInSetRequests=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInPkts</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInPkts=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInTotalReqVars=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
|
|
*/
|
|
private int snmpInTotalSetVars=0;
|
|
|
|
/**
|
|
* The <CODE>snmpInTotalSetVars</CODE> value defined in rfc 1907 MIB-II.
|
|
*/
|
|
private int snmpSilentDrops=0;
|
|
|
|
private static final String InterruptSysCallMsg =
|
|
"Interrupted system call";
|
|
static final SnmpOid sysUpTimeOid = new SnmpOid("1.3.6.1.2.1.1.3.0") ;
|
|
static final SnmpOid snmpTrapOidOid = new SnmpOid("1.3.6.1.6.3.1.1.4.1.0");
|
|
|
|
private ThreadService threadService;
|
|
|
|
private static int threadNumber = 6;
|
|
|
|
static {
|
|
String s = System.getProperty("com.sun.jmx.snmp.threadnumber");
|
|
|
|
if (s != null) {
|
|
try {
|
|
threadNumber = Integer.parseInt(System.getProperty(s));
|
|
} catch (Exception e) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER,
|
|
SnmpAdaptorServer.class.getName(),
|
|
"<static init>",
|
|
"Got wrong value for com.sun.jmx.snmp.threadnumber: " +
|
|
s + ". Use the default value: " + threadNumber);
|
|
}
|
|
}
|
|
}
|
|
|
|
// PUBLIC CONSTRUCTORS
|
|
//--------------------
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the default port (161).
|
|
* Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
|
|
* implementation of the <CODE>InetAddressAcl</CODE> interface.
|
|
*/
|
|
public SnmpAdaptorServer() {
|
|
this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
|
|
null) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified port.
|
|
* Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
|
|
* implementation of the <CODE>InetAddressAcl</CODE> interface.
|
|
*
|
|
* @param port The port number for sending SNMP responses.
|
|
*/
|
|
public SnmpAdaptorServer(int port) {
|
|
this(true, null, port, null) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the default port (161)
|
|
* and the specified IP address based ACL implementation.
|
|
*
|
|
* @param acl The <CODE>InetAddressAcl</CODE> implementation.
|
|
* <code>null</code> means no ACL - everybody is authorized.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public SnmpAdaptorServer(InetAddressAcl acl) {
|
|
this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
|
|
null) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the default port (161)
|
|
* and the
|
|
* specified <CODE>InetAddress</CODE>.
|
|
* Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
|
|
* implementation of the <CODE>InetAddressAcl</CODE> interface.
|
|
*
|
|
* @param addr The IP address to bind.
|
|
*/
|
|
public SnmpAdaptorServer(InetAddress addr) {
|
|
this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
|
|
addr) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified port and the
|
|
* specified IP address based ACL implementation.
|
|
*
|
|
* @param acl The <CODE>InetAddressAcl</CODE> implementation.
|
|
* <code>null</code> means no ACL - everybody is authorized.
|
|
* @param port The port number for sending SNMP responses.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public SnmpAdaptorServer(InetAddressAcl acl, int port) {
|
|
this(false, acl, port, null) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified port and the
|
|
* specified <CODE>InetAddress</CODE>.
|
|
* Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
|
|
* implementation of the <CODE>InetAddressAcl</CODE> interface.
|
|
*
|
|
* @param port The port number for sending SNMP responses.
|
|
* @param addr The IP address to bind.
|
|
*/
|
|
public SnmpAdaptorServer(int port, InetAddress addr) {
|
|
this(true, null, port, addr) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified IP
|
|
* address based ACL implementation and the specified
|
|
* <CODE>InetAddress</CODE>.
|
|
*
|
|
* @param acl The <CODE>InetAddressAcl</CODE> implementation.
|
|
* @param addr The IP address to bind.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public SnmpAdaptorServer(InetAddressAcl acl, InetAddress addr) {
|
|
this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
|
|
addr) ;
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified port, the
|
|
* specified address based ACL implementation and the specified
|
|
* <CODE>InetAddress</CODE>.
|
|
*
|
|
* @param acl The <CODE>InetAddressAcl</CODE> implementation.
|
|
* @param port The port number for sending SNMP responses.
|
|
* @param addr The IP address to bind.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public SnmpAdaptorServer(InetAddressAcl acl, int port, InetAddress addr) {
|
|
this(false, acl, port, addr);
|
|
}
|
|
|
|
/**
|
|
* Initializes this SNMP protocol adaptor using the specified port and the
|
|
* specified <CODE>InetAddress</CODE>.
|
|
* This constructor allows to initialize an SNMP adaptor without using
|
|
* the ACL mechanism (by setting the <CODE>useAcl</CODE> parameter to
|
|
* false).
|
|
* <br>This constructor must be used in particular with a platform that
|
|
* does not support the <CODE>java.security.acl</CODE> package like pJava.
|
|
*
|
|
* @param useAcl Specifies if this new SNMP adaptor uses the ACL mechanism.
|
|
* If the specified parameter is set to <CODE>true</CODE>, this
|
|
* constructor is equivalent to
|
|
* <CODE>SnmpAdaptorServer((int)port,(InetAddress)addr)</CODE>.
|
|
* @param port The port number for sending SNMP responses.
|
|
* @param addr The IP address to bind.
|
|
*/
|
|
public SnmpAdaptorServer(boolean useAcl, int port, InetAddress addr) {
|
|
this(useAcl,null,port,addr);
|
|
}
|
|
|
|
// If forceAcl is `true' and InetAddressAcl is null, then a default
|
|
// SnmpAcl object is created.
|
|
//
|
|
private SnmpAdaptorServer(boolean forceAcl, InetAddressAcl acl,
|
|
int port, InetAddress addr) {
|
|
super(CommunicatorServer.SNMP_TYPE) ;
|
|
|
|
|
|
// Initialize the ACL implementation.
|
|
//
|
|
if (acl == null && forceAcl) {
|
|
try {
|
|
acl = new SnmpAcl("SNMP protocol adaptor IP ACL");
|
|
} catch (UnknownHostException e) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"constructor", "UnknowHostException when creating ACL",e);
|
|
}
|
|
}
|
|
} else {
|
|
this.useAcl = (acl!=null) || forceAcl;
|
|
}
|
|
|
|
init(acl, port, addr) ;
|
|
}
|
|
|
|
// GETTERS AND SETTERS
|
|
//--------------------
|
|
|
|
/**
|
|
* Gets the number of managers that have been processed by this
|
|
* SNMP protocol adaptor since its creation.
|
|
*
|
|
* @return The number of managers handled by this SNMP protocol adaptor
|
|
* since its creation. This counter is not reset by the <CODE>stop</CODE>
|
|
* method.
|
|
*/
|
|
@Override
|
|
public int getServedClientCount() {
|
|
return super.getServedClientCount();
|
|
}
|
|
|
|
/**
|
|
* Gets the number of managers currently being processed by this
|
|
* SNMP protocol adaptor.
|
|
*
|
|
* @return The number of managers currently being processed by this
|
|
* SNMP protocol adaptor.
|
|
*/
|
|
@Override
|
|
public int getActiveClientCount() {
|
|
return super.getActiveClientCount();
|
|
}
|
|
|
|
/**
|
|
* Gets the maximum number of managers that this SNMP protocol adaptor can
|
|
* process concurrently.
|
|
*
|
|
* @return The maximum number of managers that this SNMP protocol adaptor
|
|
* can process concurrently.
|
|
*/
|
|
@Override
|
|
public int getMaxActiveClientCount() {
|
|
return super.getMaxActiveClientCount();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of managers this SNMP protocol adaptor can
|
|
* process concurrently.
|
|
*
|
|
* @param c The number of managers.
|
|
*
|
|
* @exception java.lang.IllegalStateException This method has been invoked
|
|
* while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
|
|
*/
|
|
@Override
|
|
public void setMaxActiveClientCount(int c)
|
|
throws java.lang.IllegalStateException {
|
|
super.setMaxActiveClientCount(c);
|
|
}
|
|
|
|
/**
|
|
* Returns the Ip address based ACL used by this SNMP protocol adaptor.
|
|
* @return The <CODE>InetAddressAcl</CODE> implementation.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public InetAddressAcl getInetAddressAcl() {
|
|
return ipacl;
|
|
}
|
|
|
|
/**
|
|
* Returns the port used by this SNMP protocol adaptor for sending traps.
|
|
* By default, port 162 is used.
|
|
*
|
|
* @return The port number for sending SNMP traps.
|
|
*/
|
|
@Override
|
|
public Integer getTrapPort() {
|
|
return new Integer(trapPort) ;
|
|
}
|
|
|
|
/**
|
|
* Sets the port used by this SNMP protocol adaptor for sending traps.
|
|
*
|
|
* @param port The port number for sending SNMP traps.
|
|
*/
|
|
@Override
|
|
public void setTrapPort(Integer port) {
|
|
setTrapPort(port.intValue());
|
|
}
|
|
|
|
/**
|
|
* Sets the port used by this SNMP protocol adaptor for sending traps.
|
|
*
|
|
* @param port The port number for sending SNMP traps.
|
|
*/
|
|
public void setTrapPort(int port) {
|
|
int val= port ;
|
|
if (val < 0) throw new
|
|
IllegalArgumentException("Trap port cannot be a negative value");
|
|
trapPort= val ;
|
|
}
|
|
|
|
/**
|
|
* Returns the port used by this SNMP protocol adaptor for sending
|
|
* inform requests. By default, port 162 is used.
|
|
*
|
|
* @return The port number for sending SNMP inform requests.
|
|
*/
|
|
@Override
|
|
public int getInformPort() {
|
|
return informPort;
|
|
}
|
|
|
|
/**
|
|
* Sets the port used by this SNMP protocol adaptor for sending
|
|
* inform requests.
|
|
*
|
|
* @param port The port number for sending SNMP inform requests.
|
|
*/
|
|
@Override
|
|
public void setInformPort(int port) {
|
|
if (port < 0)
|
|
throw new IllegalArgumentException("Inform request port "+
|
|
"cannot be a negative value");
|
|
informPort= port ;
|
|
}
|
|
|
|
/**
|
|
* Returns the protocol of this SNMP protocol adaptor.
|
|
*
|
|
* @return The string "snmp".
|
|
*/
|
|
@Override
|
|
public String getProtocol() {
|
|
return "snmp";
|
|
}
|
|
|
|
/**
|
|
* Returns the buffer size of this SNMP protocol adaptor.
|
|
* This buffer size is used for both incoming request and outgoing
|
|
* inform requests.
|
|
* By default, buffer size 1024 is used.
|
|
*
|
|
* @return The buffer size.
|
|
*/
|
|
@Override
|
|
public Integer getBufferSize() {
|
|
return new Integer(bufferSize) ;
|
|
}
|
|
|
|
/**
|
|
* Sets the buffer size of this SNMP protocol adaptor.
|
|
* This buffer size is used for both incoming request and outgoing
|
|
* inform requests.
|
|
*
|
|
* @param s The buffer size.
|
|
*
|
|
* @exception java.lang.IllegalStateException This method has been invoked
|
|
* while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
|
|
*/
|
|
@Override
|
|
public void setBufferSize(Integer s)
|
|
throws java.lang.IllegalStateException {
|
|
if ((state == ONLINE) || (state == STARTING)) {
|
|
throw new IllegalStateException("Stop server before carrying out"+
|
|
" this operation");
|
|
}
|
|
bufferSize = s.intValue() ;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of times to try sending an inform request before
|
|
* giving up.
|
|
* By default, a maximum of 3 tries is used.
|
|
* @return The maximun number of tries.
|
|
*/
|
|
@Override
|
|
final public int getMaxTries() {
|
|
return maxTries;
|
|
}
|
|
|
|
/**
|
|
* Changes the maximun number of times to try sending an inform
|
|
* request before giving up.
|
|
* @param newMaxTries The maximun number of tries.
|
|
*/
|
|
@Override
|
|
final public synchronized void setMaxTries(int newMaxTries) {
|
|
if (newMaxTries < 0)
|
|
throw new IllegalArgumentException();
|
|
maxTries = newMaxTries;
|
|
}
|
|
|
|
/**
|
|
* Gets the timeout to wait for an inform response from the manager.
|
|
* By default, a timeout of 3 seconds is used.
|
|
* @return The value of the timeout property.
|
|
*/
|
|
@Override
|
|
final public int getTimeout() {
|
|
return timeout;
|
|
}
|
|
|
|
/**
|
|
* Changes the timeout to wait for an inform response from the manager.
|
|
* @param newTimeout The timeout (in milliseconds).
|
|
*/
|
|
@Override
|
|
final public synchronized void setTimeout(int newTimeout) {
|
|
if (newTimeout < 0)
|
|
throw new IllegalArgumentException();
|
|
timeout= newTimeout;
|
|
}
|
|
|
|
/**
|
|
* Returns the message factory of this SNMP protocol adaptor.
|
|
*
|
|
* @return The factory object.
|
|
*/
|
|
@Override
|
|
public SnmpPduFactory getPduFactory() {
|
|
return pduFactory ;
|
|
}
|
|
|
|
/**
|
|
* Sets the message factory of this SNMP protocol adaptor.
|
|
*
|
|
* @param factory The factory object (null means the default factory).
|
|
*/
|
|
@Override
|
|
public void setPduFactory(SnmpPduFactory factory) {
|
|
if (factory == null)
|
|
pduFactory = new SnmpPduFactoryBER() ;
|
|
else
|
|
pduFactory = factory ;
|
|
}
|
|
|
|
/**
|
|
* Set the user-data factory of this SNMP protocol adaptor.
|
|
*
|
|
* @param factory The factory object (null means no factory).
|
|
* @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
|
|
*/
|
|
@Override
|
|
public void setUserDataFactory(SnmpUserDataFactory factory) {
|
|
userDataFactory = factory ;
|
|
}
|
|
|
|
/**
|
|
* Get the user-data factory associated with this SNMP protocol adaptor.
|
|
*
|
|
* @return The factory object (null means no factory).
|
|
* @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
|
|
*/
|
|
@Override
|
|
public SnmpUserDataFactory getUserDataFactory() {
|
|
return userDataFactory;
|
|
}
|
|
|
|
/**
|
|
* Returns <CODE>true</CODE> if authentication traps are enabled.
|
|
* <P>
|
|
* When this feature is enabled, the SNMP protocol adaptor sends
|
|
* an <CODE>authenticationFailure</CODE> trap each time an
|
|
* authentication fails.
|
|
* <P>
|
|
* The default behaviour is to send authentication traps.
|
|
*
|
|
* @return <CODE>true</CODE> if authentication traps are enabled,
|
|
* <CODE>false</CODE> otherwise.
|
|
*/
|
|
@Override
|
|
public boolean getAuthTrapEnabled() {
|
|
return authTrapEnabled ;
|
|
}
|
|
|
|
/**
|
|
* Sets the flag indicating if traps need to be sent in case of
|
|
* authentication failure.
|
|
*
|
|
* @param enabled Flag indicating if traps need to be sent.
|
|
*/
|
|
@Override
|
|
public void setAuthTrapEnabled(boolean enabled) {
|
|
authTrapEnabled = enabled ;
|
|
}
|
|
|
|
/**
|
|
* Returns <code>true</code> if this SNMP protocol adaptor sends a
|
|
* response in case of authentication failure.
|
|
* <P>
|
|
* When this feature is enabled, the SNMP protocol adaptor sends a
|
|
* response with <CODE>noSuchName</CODE> or <CODE>readOnly</CODE> when
|
|
* the authentication failed. If the flag is disabled, the
|
|
* SNMP protocol adaptor trashes the PDU silently.
|
|
* <P>
|
|
* The default behavior is to send responses.
|
|
*
|
|
* @return <CODE>true</CODE> if responses are sent.
|
|
*/
|
|
@Override
|
|
public boolean getAuthRespEnabled() {
|
|
return authRespEnabled ;
|
|
}
|
|
|
|
/**
|
|
* Sets the flag indicating if responses need to be sent in case of
|
|
* authentication failure.
|
|
*
|
|
* @param enabled Flag indicating if responses need to be sent.
|
|
*/
|
|
@Override
|
|
public void setAuthRespEnabled(boolean enabled) {
|
|
authRespEnabled = enabled ;
|
|
}
|
|
|
|
/**
|
|
* Returns the enterprise OID. It is used by
|
|
* {@link #snmpV1Trap snmpV1Trap} to fill the 'enterprise' field of the
|
|
* trap request.
|
|
*
|
|
* @return The OID in string format "x.x.x.x".
|
|
*/
|
|
@Override
|
|
public String getEnterpriseOid() {
|
|
return enterpriseOid.toString() ;
|
|
}
|
|
|
|
/**
|
|
* Sets the enterprise OID.
|
|
*
|
|
* @param oid The OID in string format "x.x.x.x".
|
|
*
|
|
* @exception IllegalArgumentException The string format is incorrect
|
|
*/
|
|
@Override
|
|
public void setEnterpriseOid(String oid) throws IllegalArgumentException {
|
|
enterpriseOid = new SnmpOid(oid) ;
|
|
}
|
|
|
|
/**
|
|
* Returns the names of the MIBs available in this SNMP protocol adaptor.
|
|
*
|
|
* @return An array of MIB names.
|
|
*/
|
|
@Override
|
|
public String[] getMibs() {
|
|
String[] result = new String[mibs.size()] ;
|
|
int i = 0 ;
|
|
for (Enumeration<SnmpMibAgent> e = mibs.elements() ; e.hasMoreElements() ;) {
|
|
SnmpMibAgent mib = e.nextElement() ;
|
|
result[i++] = mib.getMibName();
|
|
}
|
|
return result ;
|
|
}
|
|
|
|
// GETTERS FOR SNMP GROUP (MIBII)
|
|
//-------------------------------
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutTraps</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutTraps</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutTraps() {
|
|
return new Long(snmpOutTraps);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutGetResponses</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutGetResponses() {
|
|
return new Long(snmpOutGetResponses);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutGenErrs</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutGenErrs() {
|
|
return new Long(snmpOutGenErrs);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutBadValues</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutBadValues() {
|
|
return new Long(snmpOutBadValues);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutNoSuchNames</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutNoSuchNames() {
|
|
return new Long(snmpOutNoSuchNames);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutTooBigs</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutTooBigs() {
|
|
return new Long(snmpOutTooBigs);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInASNParseErrs</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInASNParseErrs() {
|
|
return new Long(snmpInASNParseErrs);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInBadCommunityUses</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInBadCommunityUses() {
|
|
return new Long(snmpInBadCommunityUses);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInBadCommunityNames</CODE> value defined in
|
|
* MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInBadCommunityNames</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInBadCommunityNames() {
|
|
return new Long(snmpInBadCommunityNames);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInBadVersions</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInBadVersions() {
|
|
return new Long(snmpInBadVersions);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpOutPkts</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpOutPkts</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpOutPkts() {
|
|
return new Long(snmpOutPkts);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInPkts</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInPkts</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInPkts() {
|
|
return new Long(snmpInPkts);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInGetRequests</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInGetRequests() {
|
|
return new Long(snmpInGetRequests);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInGetNexts</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInGetNexts() {
|
|
return new Long(snmpInGetNexts);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInSetRequests</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInSetRequests() {
|
|
return new Long(snmpInSetRequests);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInTotalSetVars</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInTotalSetVars() {
|
|
return new Long(snmpInTotalSetVars);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
|
|
*
|
|
* @return The <CODE>snmpInTotalReqVars</CODE> value.
|
|
*/
|
|
@Override
|
|
public Long getSnmpInTotalReqVars() {
|
|
return new Long(snmpInTotalReqVars);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpSilentDrops</CODE> value defined in RFC
|
|
* 1907 NMPv2-MIB .
|
|
*
|
|
* @return The <CODE>snmpSilentDrops</CODE> value.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public Long getSnmpSilentDrops() {
|
|
return new Long(snmpSilentDrops);
|
|
}
|
|
|
|
/**
|
|
* Returns the <CODE>snmpProxyDrops</CODE> value defined in RFC
|
|
* 1907 NMPv2-MIB .
|
|
*
|
|
* @return The <CODE>snmpProxyDrops</CODE> value.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public Long getSnmpProxyDrops() {
|
|
return new Long(0);
|
|
}
|
|
|
|
|
|
// PUBLIC METHODS
|
|
//---------------
|
|
|
|
/**
|
|
* Allows the MBean to perform any operations it needs before being
|
|
* registered in the MBean server.
|
|
* If the name of the SNMP protocol adaptor MBean is not specified,
|
|
* it is initialized with the default value:
|
|
* {@link com.sun.jmx.snmp.ServiceName#DOMAIN
|
|
* com.sun.jmx.snmp.ServiceName.DOMAIN}:{@link
|
|
* com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
|
|
* com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
|
|
* If any exception is raised, the SNMP protocol adaptor MBean will
|
|
* not be registered in the MBean server.
|
|
*
|
|
* @param server The MBean server to register the service with.
|
|
* @param name The object name.
|
|
*
|
|
* @return The name of the SNMP protocol adaptor registered.
|
|
*
|
|
* @exception java.lang.Exception
|
|
*/
|
|
@Override
|
|
public ObjectName preRegister(MBeanServer server, ObjectName name)
|
|
throws java.lang.Exception {
|
|
|
|
if (name == null) {
|
|
name = new ObjectName(server.getDefaultDomain() + ":" +
|
|
com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER);
|
|
}
|
|
return (super.preRegister(server, name));
|
|
}
|
|
|
|
/**
|
|
* Not used in this context.
|
|
*/
|
|
@Override
|
|
public void postRegister (Boolean registrationDone) {
|
|
super.postRegister(registrationDone);
|
|
}
|
|
|
|
/**
|
|
* Not used in this context.
|
|
*/
|
|
@Override
|
|
public void preDeregister() throws java.lang.Exception {
|
|
super.preDeregister();
|
|
}
|
|
|
|
/**
|
|
* Not used in this context.
|
|
*/
|
|
@Override
|
|
public void postDeregister() {
|
|
super.postDeregister();
|
|
}
|
|
|
|
/**
|
|
* Adds a new MIB in the SNMP MIB handler.
|
|
*
|
|
* @param mib The MIB to add.
|
|
*
|
|
* @return A reference to the SNMP MIB handler.
|
|
*
|
|
* @exception IllegalArgumentException If the parameter is null.
|
|
*/
|
|
@Override
|
|
public SnmpMibHandler addMib(SnmpMibAgent mib)
|
|
throws IllegalArgumentException {
|
|
if (mib == null) {
|
|
throw new IllegalArgumentException() ;
|
|
}
|
|
|
|
if(!mibs.contains(mib))
|
|
mibs.addElement(mib);
|
|
|
|
root.register(mib);
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a new MIB in the SNMP MIB handler.
|
|
* This method is to be called to set a specific agent to a specific OID.
|
|
* This can be useful when dealing with MIB overlapping.
|
|
* Some OID can be implemented in more than one MIB. In this case,
|
|
* the OID nearer agent will be used on SNMP operations.
|
|
*
|
|
* @param mib The MIB to add.
|
|
* @param oids The set of OIDs this agent implements.
|
|
*
|
|
* @return A reference to the SNMP MIB handler.
|
|
*
|
|
* @exception IllegalArgumentException If the parameter is null.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public SnmpMibHandler addMib(SnmpMibAgent mib, SnmpOid[] oids)
|
|
throws IllegalArgumentException {
|
|
if (mib == null) {
|
|
throw new IllegalArgumentException() ;
|
|
}
|
|
|
|
//If null oid array, just add it to the mib.
|
|
if(oids == null)
|
|
return addMib(mib);
|
|
|
|
if(!mibs.contains(mib))
|
|
mibs.addElement(mib);
|
|
|
|
for (int i = 0; i < oids.length; i++) {
|
|
root.register(mib, oids[i].longValue());
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
|
|
* <CODE>contextName</CODE> is useless and this method
|
|
* is equivalent to <CODE>addMib(SnmpMibAgent mib)</CODE>.
|
|
*
|
|
* @param mib The MIB to add.
|
|
* @param contextName The MIB context name.
|
|
* @return A reference on the SNMP MIB handler.
|
|
*
|
|
* @exception IllegalArgumentException If the parameter is null.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public SnmpMibHandler addMib(SnmpMibAgent mib, String contextName)
|
|
throws IllegalArgumentException {
|
|
return addMib(mib);
|
|
}
|
|
|
|
/**
|
|
* Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
|
|
* <CODE>contextName</CODE> is useless and this method
|
|
* is equivalent to <CODE>addMib(SnmpMibAgent mib, SnmpOid[] oids)</CODE>.
|
|
*
|
|
* @param mib The MIB to add.
|
|
* @param contextName The MIB context. If null is passed, will be
|
|
* registered in the default context.
|
|
* @param oids The set of OIDs this agent implements.
|
|
*
|
|
* @return A reference to the SNMP MIB handler.
|
|
*
|
|
* @exception IllegalArgumentException If the parameter is null.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public SnmpMibHandler addMib(SnmpMibAgent mib,
|
|
String contextName,
|
|
SnmpOid[] oids)
|
|
throws IllegalArgumentException {
|
|
|
|
return addMib(mib, oids);
|
|
}
|
|
|
|
/**
|
|
* Removes the specified MIB from the SNMP protocol adaptor.
|
|
* In SNMP V1 and V2 the <CODE>contextName</CODE> is useless and this
|
|
* method is equivalent to <CODE>removeMib(SnmpMibAgent mib)</CODE>.
|
|
*
|
|
* @param mib The MIB to be removed.
|
|
* @param contextName The context name used at registration time.
|
|
*
|
|
* @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
|
|
* a MIB included in the SNMP MIB handler, <CODE>false</CODE>
|
|
* otherwise.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public boolean removeMib(SnmpMibAgent mib, String contextName) {
|
|
return removeMib(mib);
|
|
}
|
|
|
|
/**
|
|
* Removes the specified MIB from the SNMP protocol adaptor.
|
|
*
|
|
* @param mib The MIB to be removed.
|
|
*
|
|
* @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was a MIB
|
|
* included in the SNMP MIB handler, <CODE>false</CODE> otherwise.
|
|
*/
|
|
@Override
|
|
public boolean removeMib(SnmpMibAgent mib) {
|
|
root.unregister(mib);
|
|
return (mibs.removeElement(mib)) ;
|
|
}
|
|
|
|
/**
|
|
* Removes the specified MIB from the SNMP protocol adaptor.
|
|
*
|
|
* @param mib The MIB to be removed.
|
|
* @param oids The oid the MIB was previously registered for.
|
|
* @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
|
|
* a MIB included in the SNMP MIB handler, <CODE>false</CODE>
|
|
* otherwise.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public boolean removeMib(SnmpMibAgent mib, SnmpOid[] oids) {
|
|
root.unregister(mib, oids);
|
|
return (mibs.removeElement(mib)) ;
|
|
}
|
|
|
|
/**
|
|
* Removes the specified MIB from the SNMP protocol adaptor.
|
|
*
|
|
* @param mib The MIB to be removed.
|
|
* @param contextName The context name used at registration time.
|
|
* @param oids The oid the MIB was previously registered for.
|
|
* @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
|
|
* a MIB included in the SNMP MIB handler, <CODE>false</CODE>
|
|
* otherwise.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public boolean removeMib(SnmpMibAgent mib,
|
|
String contextName,
|
|
SnmpOid[] oids) {
|
|
return removeMib(mib, oids);
|
|
}
|
|
|
|
// SUBCLASSING OF COMMUNICATOR SERVER
|
|
//-----------------------------------
|
|
|
|
/**
|
|
* Creates the datagram socket.
|
|
*/
|
|
@Override
|
|
protected void doBind()
|
|
throws CommunicationException, InterruptedException {
|
|
|
|
try {
|
|
synchronized (this) {
|
|
socket = new DatagramSocket(port, address) ;
|
|
}
|
|
dbgTag = makeDebugTag();
|
|
} catch (SocketException e) {
|
|
if (e.getMessage().equals(InterruptSysCallMsg))
|
|
throw new InterruptedException(e.toString()) ;
|
|
else {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"doBind", "cannot bind on port " + port);
|
|
}
|
|
throw new CommunicationException(e) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the actual port to which the adaptor is bound.
|
|
* Can be different from the port given at construction time if
|
|
* that port number was 0.
|
|
* @return the actual port to which the adaptor is bound.
|
|
**/
|
|
@Override
|
|
public int getPort() {
|
|
synchronized (this) {
|
|
if (socket != null) return socket.getLocalPort();
|
|
}
|
|
return super.getPort();
|
|
}
|
|
|
|
/**
|
|
* Closes the datagram socket.
|
|
*/
|
|
@Override
|
|
protected void doUnbind()
|
|
throws CommunicationException, InterruptedException {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"doUnbind","Finally close the socket");
|
|
}
|
|
synchronized (this) {
|
|
if (socket != null) {
|
|
socket.close() ;
|
|
socket = null ;
|
|
// Important to inform finalize() that the socket is closed...
|
|
}
|
|
}
|
|
closeTrapSocketIfNeeded() ;
|
|
closeInformSocketIfNeeded() ;
|
|
}
|
|
|
|
private void createSnmpRequestHandler(SnmpAdaptorServer server,
|
|
int id,
|
|
DatagramSocket s,
|
|
DatagramPacket p,
|
|
SnmpMibTree tree,
|
|
Vector<SnmpMibAgent> m,
|
|
InetAddressAcl a,
|
|
SnmpPduFactory factory,
|
|
SnmpUserDataFactory dataFactory,
|
|
MBeanServer f,
|
|
ObjectName n) {
|
|
final SnmpRequestHandler handler =
|
|
new SnmpRequestHandler(this, id, s, p, tree, m, a, factory,
|
|
dataFactory, f, n);
|
|
threadService.submitTask(handler);
|
|
}
|
|
|
|
/**
|
|
* Reads a packet from the datagram socket and creates a request
|
|
* handler which decodes and processes the request.
|
|
*/
|
|
@Override
|
|
protected void doReceive()
|
|
throws CommunicationException, InterruptedException {
|
|
|
|
// Let's wait for something to be received.
|
|
//
|
|
try {
|
|
packet = new DatagramPacket(new byte[bufferSize], bufferSize) ;
|
|
socket.receive(packet);
|
|
int state = getState();
|
|
|
|
if(state != ONLINE) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"doReceive","received a message but state not online, returning.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
createSnmpRequestHandler(this, servedClientCount, socket,
|
|
packet, root, mibs, ipacl, pduFactory,
|
|
userDataFactory, topMBS, objectName);
|
|
} catch (SocketException e) {
|
|
// Let's check if we have been interrupted by stop().
|
|
//
|
|
if (e.getMessage().equals(InterruptSysCallMsg))
|
|
throw new InterruptedException(e.toString()) ;
|
|
else
|
|
throw new CommunicationException(e) ;
|
|
} catch (InterruptedIOException e) {
|
|
throw new InterruptedException(e.toString()) ;
|
|
} catch (CommunicationException e) {
|
|
throw e ;
|
|
} catch (Exception e) {
|
|
throw new CommunicationException(e) ;
|
|
}
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"doReceive", "received a message");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void doError(Exception e) throws CommunicationException {
|
|
}
|
|
|
|
/**
|
|
* Not used in this context.
|
|
*/
|
|
@Override
|
|
protected void doProcess()
|
|
throws CommunicationException, InterruptedException {
|
|
}
|
|
|
|
|
|
/**
|
|
* The number of times the communicator server will attempt
|
|
* to bind before giving up.
|
|
* We attempt only once...
|
|
* @return 1
|
|
**/
|
|
@Override
|
|
protected int getBindTries() {
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Stops this SNMP protocol adaptor.
|
|
* Closes the datagram socket.
|
|
* <p>
|
|
* Has no effect if this SNMP protocol adaptor is <CODE>OFFLINE</CODE> or
|
|
* <CODE>STOPPING</CODE>.
|
|
*/
|
|
@Override
|
|
public void stop(){
|
|
|
|
final int port = getPort();
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"stop", "Stopping: using port " + port);
|
|
}
|
|
if ((state == ONLINE) || (state == STARTING)){
|
|
super.stop();
|
|
try {
|
|
DatagramSocket sn = new DatagramSocket(0);
|
|
try {
|
|
byte[] ob = new byte[1];
|
|
|
|
DatagramPacket pk;
|
|
if (address != null)
|
|
pk = new DatagramPacket(ob , 1, address, port);
|
|
else
|
|
pk = new DatagramPacket(ob , 1,
|
|
java.net.InetAddress.getLocalHost(), port);
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"stop", "Sending: using port " + port);
|
|
}
|
|
sn.send(pk);
|
|
} finally {
|
|
sn.close();
|
|
}
|
|
} catch (Throwable e){
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"stop", "Got unexpected Throwable", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// SENDING SNMP TRAPS STUFF
|
|
//-------------------------
|
|
|
|
/**
|
|
* Sends a trap using SNMP V1 trap format.
|
|
* <BR>The trap is sent to each destination defined in the ACL file
|
|
* (if available).
|
|
* If no ACL file or no destinations are available, the trap is sent
|
|
* to the local host.
|
|
*
|
|
* @param generic The generic number of the trap.
|
|
* @param specific The specific number of the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit defined
|
|
* by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public void snmpV1Trap(int generic, int specific,
|
|
SnmpVarBindList varBindList)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV1Trap", "generic=" + generic +
|
|
", specific=" + specific);
|
|
}
|
|
|
|
// First, make an SNMP V1 trap pdu
|
|
//
|
|
SnmpPduTrap pdu = new SnmpPduTrap() ;
|
|
pdu.address = null ;
|
|
pdu.port = trapPort ;
|
|
pdu.type = pduV1TrapPdu ;
|
|
pdu.version = snmpVersionOne ;
|
|
pdu.community = null ;
|
|
pdu.enterprise = enterpriseOid ;
|
|
pdu.genericTrap = generic ;
|
|
pdu.specificTrap = specific ;
|
|
pdu.timeStamp = getSysUpTime();
|
|
|
|
if (varBindList != null) {
|
|
pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
|
|
varBindList.copyInto(pdu.varBindList);
|
|
}
|
|
else
|
|
pdu.varBindList = null ;
|
|
|
|
// If the local host cannot be determined, we put 0.0.0.0 in agentAddr
|
|
try {
|
|
if (address != null)
|
|
pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
|
|
else pdu.agentAddr =
|
|
handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
|
|
} catch (UnknownHostException e) {
|
|
byte[] zeroedAddr = new byte[4];
|
|
pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
|
|
}
|
|
|
|
// Next, send the pdu to all destinations defined in ACL
|
|
//
|
|
sendTrapPdu(pdu) ;
|
|
}
|
|
|
|
private SnmpIpAddress handleMultipleIpVersion(byte[] address) {
|
|
if(address.length == 4)
|
|
return new SnmpIpAddress(address);
|
|
else {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"handleMultipleIPVersion",
|
|
"Not an IPv4 address, return null");
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V1 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
|
|
* destination using the specified community string (and the ACL file
|
|
* is not used).
|
|
*
|
|
* @param addr The <CODE>InetAddress</CODE> destination of the trap.
|
|
* @param cs The community string to be used for the trap.
|
|
* @param generic The generic number of the trap.
|
|
* @param specific The specific number of the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit defined
|
|
* by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public void snmpV1Trap(InetAddress addr, String cs, int generic,
|
|
int specific, SnmpVarBindList varBindList)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV1Trap", "generic=" + generic + ", specific=" +
|
|
specific);
|
|
}
|
|
|
|
// First, make an SNMP V1 trap pdu
|
|
//
|
|
SnmpPduTrap pdu = new SnmpPduTrap() ;
|
|
pdu.address = null ;
|
|
pdu.port = trapPort ;
|
|
pdu.type = pduV1TrapPdu ;
|
|
pdu.version = snmpVersionOne ;
|
|
|
|
if(cs != null)
|
|
pdu.community = cs.getBytes();
|
|
else
|
|
pdu.community = null ;
|
|
|
|
pdu.enterprise = enterpriseOid ;
|
|
pdu.genericTrap = generic ;
|
|
pdu.specificTrap = specific ;
|
|
pdu.timeStamp = getSysUpTime();
|
|
|
|
if (varBindList != null) {
|
|
pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
|
|
varBindList.copyInto(pdu.varBindList);
|
|
}
|
|
else
|
|
pdu.varBindList = null ;
|
|
|
|
// If the local host cannot be determined, we put 0.0.0.0 in agentAddr
|
|
try {
|
|
if (address != null)
|
|
pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
|
|
else pdu.agentAddr =
|
|
handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
|
|
} catch (UnknownHostException e) {
|
|
byte[] zeroedAddr = new byte[4];
|
|
pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
|
|
}
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
if(addr != null)
|
|
sendTrapPdu(addr, pdu) ;
|
|
else
|
|
sendTrapPdu(pdu);
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V1 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
|
|
* destination using the specified parameters (and the ACL file is not
|
|
* used).
|
|
* Note that if the specified <CODE>InetAddress</CODE> destination is null,
|
|
* then the ACL file mechanism is used.
|
|
*
|
|
* @param addr The <CODE>InetAddress</CODE> destination of the trap.
|
|
* @param agentAddr The agent address to be used for the trap.
|
|
* @param cs The community string to be used for the trap.
|
|
* @param enterpOid The enterprise OID to be used for the trap.
|
|
* @param generic The generic number of the trap.
|
|
* @param specific The specific number of the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
* @param time The time stamp (overwrite the current time).
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit defined
|
|
* by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public void snmpV1Trap(InetAddress addr,
|
|
SnmpIpAddress agentAddr,
|
|
String cs,
|
|
SnmpOid enterpOid,
|
|
int generic,
|
|
int specific,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
snmpV1Trap(addr,
|
|
trapPort,
|
|
agentAddr,
|
|
cs,
|
|
enterpOid,
|
|
generic,
|
|
specific,
|
|
varBindList,
|
|
time);
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V1 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
|
|
* The community string used is the one located in the
|
|
* <CODE>SnmpPeer</CODE> parameters
|
|
* (<CODE>SnmpParameters.getRdCommunity() </CODE>).
|
|
*
|
|
* @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
|
|
* @param agentAddr The agent address to be used for the trap.
|
|
* @param enterpOid The enterprise OID to be used for the trap.
|
|
* @param generic The generic number of the trap.
|
|
* @param specific The specific number of the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
* @param time The time stamp (overwrite the current time).
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit
|
|
* defined by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public void snmpV1Trap(SnmpPeer peer,
|
|
SnmpIpAddress agentAddr,
|
|
SnmpOid enterpOid,
|
|
int generic,
|
|
int specific,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
SnmpParameters p = (SnmpParameters) peer.getParams();
|
|
snmpV1Trap(peer.getDestAddr(),
|
|
peer.getDestPort(),
|
|
agentAddr,
|
|
p.getRdCommunity(),
|
|
enterpOid,
|
|
generic,
|
|
specific,
|
|
varBindList,
|
|
time);
|
|
}
|
|
|
|
private void snmpV1Trap(InetAddress addr,
|
|
int port,
|
|
SnmpIpAddress agentAddr,
|
|
String cs,
|
|
SnmpOid enterpOid,
|
|
int generic,
|
|
int specific,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV1Trap", "generic=" + generic + ", specific=" +
|
|
specific);
|
|
}
|
|
|
|
// First, make an SNMP V1 trap pdu
|
|
//
|
|
SnmpPduTrap pdu = new SnmpPduTrap() ;
|
|
pdu.address = null ;
|
|
pdu.port = port ;
|
|
pdu.type = pduV1TrapPdu ;
|
|
pdu.version = snmpVersionOne ;
|
|
|
|
//Diff start
|
|
if(cs != null)
|
|
pdu.community = cs.getBytes();
|
|
else
|
|
pdu.community = null ;
|
|
//Diff end
|
|
|
|
// Diff start
|
|
if(enterpOid != null)
|
|
pdu.enterprise = enterpOid;
|
|
else
|
|
pdu.enterprise = enterpriseOid ;
|
|
//Diff end
|
|
pdu.genericTrap = generic ;
|
|
pdu.specificTrap = specific ;
|
|
//Diff start
|
|
if(time != null)
|
|
pdu.timeStamp = time.longValue();
|
|
else
|
|
pdu.timeStamp = getSysUpTime();
|
|
//Diff end
|
|
|
|
if (varBindList != null) {
|
|
pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
|
|
varBindList.copyInto(pdu.varBindList);
|
|
}
|
|
else
|
|
pdu.varBindList = null ;
|
|
|
|
if (agentAddr == null) {
|
|
// If the local host cannot be determined,
|
|
// we put 0.0.0.0 in agentAddr
|
|
try {
|
|
final InetAddress inetAddr =
|
|
(address!=null)?address:InetAddress.getLocalHost();
|
|
agentAddr = handleMultipleIpVersion(inetAddr.getAddress());
|
|
} catch (UnknownHostException e) {
|
|
byte[] zeroedAddr = new byte[4];
|
|
agentAddr = handleMultipleIpVersion(zeroedAddr);
|
|
}
|
|
}
|
|
|
|
pdu.agentAddr = agentAddr;
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
// Diff start
|
|
if(addr != null)
|
|
sendTrapPdu(addr, pdu) ;
|
|
else
|
|
sendTrapPdu(pdu);
|
|
|
|
//End diff
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V2 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
|
|
* <BR>The community string used is the one located in the
|
|
* <CODE>SnmpPeer</CODE> parameters
|
|
* (<CODE>SnmpParameters.getRdCommunity() </CODE>).
|
|
* <BR>The variable list included in the outgoing trap is composed of
|
|
* the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with the value specified by
|
|
* <CODE>time</CODE></LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
*
|
|
* @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
* @param time The time stamp (overwrite the current time).
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit
|
|
* defined by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public void snmpV2Trap(SnmpPeer peer,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
SnmpParameters p = (SnmpParameters) peer.getParams();
|
|
snmpV2Trap(peer.getDestAddr(),
|
|
peer.getDestPort(),
|
|
p.getRdCommunity(),
|
|
trapOid,
|
|
varBindList,
|
|
time);
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V2 trap format.
|
|
* <BR>The trap is sent to each destination defined in the ACL file
|
|
* (if available). If no ACL file or no destinations are available,
|
|
* the trap is sent to the local host.
|
|
* <BR>The variable list included in the outgoing trap is composed of
|
|
* the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
*
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit defined
|
|
* by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public void snmpV2Trap(SnmpOid trapOid, SnmpVarBindList varBindList)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV2Trap", "trapOid=" + trapOid);
|
|
}
|
|
|
|
// First, make an SNMP V2 trap pdu
|
|
// We clone varBindList and insert sysUpTime and snmpTrapOid
|
|
//
|
|
SnmpPduRequest pdu = new SnmpPduRequest() ;
|
|
pdu.address = null ;
|
|
pdu.port = trapPort ;
|
|
pdu.type = pduV2TrapPdu ;
|
|
pdu.version = snmpVersionTwo ;
|
|
pdu.community = null ;
|
|
|
|
SnmpVarBindList fullVbl ;
|
|
if (varBindList != null)
|
|
fullVbl = varBindList.clone() ;
|
|
else
|
|
fullVbl = new SnmpVarBindList(2) ;
|
|
SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
|
|
0);
|
|
pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
|
|
fullVbl.copyInto(pdu.varBindList) ;
|
|
|
|
// Next, send the pdu to all destinations defined in ACL
|
|
//
|
|
sendTrapPdu(pdu) ;
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V2 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
|
|
* destination using the specified community string (and the ACL file
|
|
* is not used).
|
|
* <BR>The variable list included in the outgoing trap is composed of
|
|
* the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
*
|
|
* @param addr The <CODE>InetAddress</CODE> destination of the trap.
|
|
* @param cs The community string to be used for the trap.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit
|
|
* defined by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public void snmpV2Trap(InetAddress addr, String cs, SnmpOid trapOid,
|
|
SnmpVarBindList varBindList)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV2Trap", "trapOid=" + trapOid);
|
|
}
|
|
|
|
// First, make an SNMP V2 trap pdu
|
|
// We clone varBindList and insert sysUpTime and snmpTrapOid
|
|
//
|
|
SnmpPduRequest pdu = new SnmpPduRequest() ;
|
|
pdu.address = null ;
|
|
pdu.port = trapPort ;
|
|
pdu.type = pduV2TrapPdu ;
|
|
pdu.version = snmpVersionTwo ;
|
|
|
|
if(cs != null)
|
|
pdu.community = cs.getBytes();
|
|
else
|
|
pdu.community = null;
|
|
|
|
SnmpVarBindList fullVbl ;
|
|
if (varBindList != null)
|
|
fullVbl = varBindList.clone() ;
|
|
else
|
|
fullVbl = new SnmpVarBindList(2) ;
|
|
SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
|
|
0);
|
|
pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
|
|
fullVbl.copyInto(pdu.varBindList) ;
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
if(addr != null)
|
|
sendTrapPdu(addr, pdu);
|
|
else
|
|
sendTrapPdu(pdu);
|
|
}
|
|
|
|
/**
|
|
* Sends a trap using SNMP V2 trap format.
|
|
* <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
|
|
* destination using the specified parameters (and the ACL file is not
|
|
* used).
|
|
* Note that if the specified <CODE>InetAddress</CODE> destination is null,
|
|
* then the ACL file mechanism is used.
|
|
* <BR>The variable list included in the outgoing trap is composed of the
|
|
* following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with the value specified by
|
|
* <CODE>time</CODE></LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
*
|
|
* @param addr The <CODE>InetAddress</CODE> destination of the trap.
|
|
* @param cs The community string to be used for the trap.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
* @param time The time stamp (overwrite the current time).
|
|
*
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit
|
|
* defined by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public void snmpV2Trap(InetAddress addr,
|
|
String cs,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
snmpV2Trap(addr,
|
|
trapPort,
|
|
cs,
|
|
trapOid,
|
|
varBindList,
|
|
time);
|
|
}
|
|
|
|
private void snmpV2Trap(InetAddress addr,
|
|
int port,
|
|
String cs,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList,
|
|
SnmpTimeticks time)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
final StringBuilder strb = new StringBuilder()
|
|
.append("trapOid=").append(trapOid)
|
|
.append("\ncommunity=").append(cs)
|
|
.append("\naddr=").append(addr)
|
|
.append("\nvarBindList=").append(varBindList)
|
|
.append("\ntime=").append(time)
|
|
.append("\ntrapPort=").append(port);
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpV2Trap", strb.toString());
|
|
}
|
|
|
|
// First, make an SNMP V2 trap pdu
|
|
// We clone varBindList and insert sysUpTime and snmpTrapOid
|
|
//
|
|
SnmpPduRequest pdu = new SnmpPduRequest() ;
|
|
pdu.address = null ;
|
|
pdu.port = port ;
|
|
pdu.type = pduV2TrapPdu ;
|
|
pdu.version = snmpVersionTwo ;
|
|
|
|
if(cs != null)
|
|
pdu.community = cs.getBytes();
|
|
else
|
|
pdu.community = null;
|
|
|
|
SnmpVarBindList fullVbl ;
|
|
if (varBindList != null)
|
|
fullVbl = varBindList.clone() ;
|
|
else
|
|
fullVbl = new SnmpVarBindList(2) ;
|
|
|
|
// Only difference with other
|
|
SnmpTimeticks sysUpTimeValue;
|
|
if(time != null)
|
|
sysUpTimeValue = time;
|
|
else
|
|
sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
|
|
//End of diff
|
|
|
|
fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
|
|
0);
|
|
pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
|
|
fullVbl.copyInto(pdu.varBindList) ;
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
// Diff start
|
|
if(addr != null)
|
|
sendTrapPdu(addr, pdu) ;
|
|
else
|
|
sendTrapPdu(pdu);
|
|
//End diff
|
|
}
|
|
|
|
/**
|
|
* Send the specified trap PDU to the passed <CODE>InetAddress</CODE>.
|
|
* @param address The destination address.
|
|
* @param pdu The pdu to send.
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit
|
|
* defined by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public void snmpPduTrap(InetAddress address, SnmpPduPacket pdu)
|
|
throws IOException, SnmpStatusException {
|
|
|
|
if(address != null)
|
|
sendTrapPdu(address, pdu);
|
|
else
|
|
sendTrapPdu(pdu);
|
|
}
|
|
|
|
/**
|
|
* Send the specified trap PDU to the passed <CODE>SnmpPeer</CODE>.
|
|
* @param peer The destination peer. The Read community string is used of
|
|
* <CODE>SnmpParameters</CODE> is used as the trap community string.
|
|
* @param pdu The pdu to send.
|
|
* @exception IOException An I/O error occurred while sending the trap.
|
|
* @exception SnmpStatusException If the trap exceeds the limit defined
|
|
* by <CODE>bufferSize</CODE>.
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public void snmpPduTrap(SnmpPeer peer,
|
|
SnmpPduPacket pdu)
|
|
throws IOException, SnmpStatusException {
|
|
if(peer != null) {
|
|
pdu.port = peer.getDestPort();
|
|
sendTrapPdu(peer.getDestAddr(), pdu);
|
|
}
|
|
else {
|
|
pdu.port = getTrapPort().intValue();
|
|
sendTrapPdu(pdu);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send the specified trap PDU to every destinations from the ACL file.
|
|
*/
|
|
private void sendTrapPdu(SnmpPduPacket pdu)
|
|
throws SnmpStatusException, IOException {
|
|
|
|
// Make an SNMP message from the pdu
|
|
//
|
|
SnmpMessage msg = null ;
|
|
try {
|
|
msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
|
|
if (msg == null) {
|
|
throw new SnmpStatusException(
|
|
SnmpDefinitions.snmpRspAuthorizationError) ;
|
|
}
|
|
}
|
|
catch (SnmpTooBigException x) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent to anyone" );
|
|
}
|
|
throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
|
|
// FIXME: is the right exception to throw ?
|
|
// We could simply forward SnmpTooBigException ?
|
|
}
|
|
|
|
// Now send the SNMP message to each destination
|
|
//
|
|
int sendingCount = 0 ;
|
|
openTrapSocketIfNeeded() ;
|
|
if (ipacl != null) {
|
|
Enumeration<InetAddress> ed = ipacl.getTrapDestinations() ;
|
|
while (ed.hasMoreElements()) {
|
|
msg.address = ed.nextElement() ;
|
|
Enumeration<String> ec = ipacl.getTrapCommunities(msg.address) ;
|
|
while (ec.hasMoreElements()) {
|
|
msg.community = ec.nextElement().getBytes() ;
|
|
try {
|
|
sendTrapMessage(msg) ;
|
|
sendingCount++ ;
|
|
}
|
|
catch (SnmpTooBigException x) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent to "+msg.address);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there is no destination defined or if everything has failed
|
|
// we tried to send the trap to the local host (as suggested by
|
|
// mister Olivier Reisacher).
|
|
//
|
|
if (sendingCount == 0) {
|
|
try {
|
|
msg.address = InetAddress.getLocalHost() ;
|
|
sendTrapMessage(msg) ;
|
|
} catch (SnmpTooBigException x) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent.");
|
|
}
|
|
} catch (UnknownHostException e) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent.");
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTrapSocketIfNeeded() ;
|
|
}
|
|
|
|
/**
|
|
* Send the specified trap PDU to the specified destination.
|
|
*/
|
|
private void sendTrapPdu(InetAddress addr, SnmpPduPacket pdu)
|
|
throws SnmpStatusException, IOException {
|
|
|
|
// Make an SNMP message from the pdu
|
|
//
|
|
SnmpMessage msg = null ;
|
|
try {
|
|
msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
|
|
if (msg == null) {
|
|
throw new SnmpStatusException(
|
|
SnmpDefinitions.snmpRspAuthorizationError) ;
|
|
}
|
|
} catch (SnmpTooBigException x) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent to the specified host.");
|
|
}
|
|
throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
|
|
// FIXME: is the right exception to throw ?
|
|
// We could simply forward SnmpTooBigException ?
|
|
}
|
|
|
|
// Now send the SNMP message to specified destination
|
|
//
|
|
openTrapSocketIfNeeded() ;
|
|
if (addr != null) {
|
|
msg.address = addr;
|
|
try {
|
|
sendTrapMessage(msg) ;
|
|
} catch (SnmpTooBigException x) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
|
|
"sendTrapPdu", "Trap pdu is too big. " +
|
|
"Trap hasn't been sent to " + msg.address);
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTrapSocketIfNeeded() ;
|
|
}
|
|
|
|
/**
|
|
* Send the specified message on trapSocket.
|
|
*/
|
|
private void sendTrapMessage(SnmpMessage msg)
|
|
throws IOException, SnmpTooBigException {
|
|
|
|
byte[] buffer = new byte[bufferSize] ;
|
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length) ;
|
|
int encodingLength = msg.encodeMessage(buffer) ;
|
|
packet.setLength(encodingLength) ;
|
|
packet.setAddress(msg.address) ;
|
|
packet.setPort(msg.port) ;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"sendTrapMessage", "sending trap to " + msg.address + ":" +
|
|
msg.port);
|
|
}
|
|
trapSocket.send(packet) ;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"sendTrapMessage", "sent to " + msg.address + ":" +
|
|
msg.port);
|
|
}
|
|
snmpOutTraps++;
|
|
snmpOutPkts++;
|
|
}
|
|
|
|
/**
|
|
* Open trapSocket if it's not already done.
|
|
*/
|
|
synchronized void openTrapSocketIfNeeded() throws SocketException {
|
|
if (trapSocket == null) {
|
|
trapSocket = new DatagramSocket(0, address) ;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"openTrapSocketIfNeeded", "using port " +
|
|
trapSocket.getLocalPort() + " to send traps");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close trapSocket if the SNMP protocol adaptor is not ONLINE.
|
|
*/
|
|
synchronized void closeTrapSocketIfNeeded() {
|
|
if ((trapSocket != null) && (state != ONLINE)) {
|
|
trapSocket.close() ;
|
|
trapSocket = null ;
|
|
}
|
|
}
|
|
|
|
// SENDING SNMP INFORMS STUFF
|
|
//---------------------------
|
|
|
|
/**
|
|
* Sends an inform using SNMP V2 inform request format.
|
|
* <BR>The inform request is sent to each destination defined in the ACL
|
|
* file (if available).
|
|
* If no ACL file or no destinations are available, the inform request is
|
|
* sent to the local host.
|
|
* <BR>The variable list included in the outgoing inform is composed of
|
|
* the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
* To send an inform request, the SNMP adaptor server must be active.
|
|
*
|
|
* @param cb The callback that is invoked when a request is complete.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @return A vector of {@link com.sun.jmx.snmp.daemon.SnmpInformRequest}
|
|
* objects.
|
|
* <P>If there is no destination host for this inform request,
|
|
* the returned vector will be empty.
|
|
*
|
|
* @exception IllegalStateException This method has been invoked while
|
|
* the SNMP adaptor server was not active.
|
|
* @exception IOException An I/O error occurred while sending the
|
|
* inform request.
|
|
* @exception SnmpStatusException If the inform request exceeds the
|
|
* limit defined by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public Vector<SnmpInformRequest> snmpInformRequest(SnmpInformHandler cb,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList)
|
|
throws IllegalStateException, IOException, SnmpStatusException {
|
|
|
|
if (!isActive()) {
|
|
throw new IllegalStateException(
|
|
"Start SNMP adaptor server before carrying out this operation");
|
|
}
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpInformRequest", "trapOid=" + trapOid);
|
|
}
|
|
|
|
// First, make an SNMP inform pdu:
|
|
// We clone varBindList and insert sysUpTime and snmpTrapOid variables.
|
|
//
|
|
SnmpVarBindList fullVbl ;
|
|
if (varBindList != null)
|
|
fullVbl = varBindList.clone() ;
|
|
else
|
|
fullVbl = new SnmpVarBindList(2) ;
|
|
SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
|
|
0);
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
openInformSocketIfNeeded() ;
|
|
|
|
// Now send the SNMP message to each destination
|
|
//
|
|
Vector<SnmpInformRequest> informReqList = new Vector<>();
|
|
InetAddress addr;
|
|
String cs;
|
|
if (ipacl != null) {
|
|
Enumeration<InetAddress> ed = ipacl.getInformDestinations() ;
|
|
while (ed.hasMoreElements()) {
|
|
addr = ed.nextElement() ;
|
|
Enumeration<String> ec = ipacl.getInformCommunities(addr) ;
|
|
while (ec.hasMoreElements()) {
|
|
cs = ec.nextElement() ;
|
|
informReqList.addElement(
|
|
informSession.makeAsyncRequest(addr, cs, cb,
|
|
fullVbl,getInformPort())) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return informReqList ;
|
|
}
|
|
|
|
/**
|
|
* Sends an inform using SNMP V2 inform request format.
|
|
* <BR>The inform is sent to the specified <CODE>InetAddress</CODE>
|
|
* destination
|
|
* using the specified community string.
|
|
* <BR>The variable list included in the outgoing inform is composed
|
|
* of the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
* To send an inform request, the SNMP adaptor server must be active.
|
|
*
|
|
* @param addr The <CODE>InetAddress</CODE> destination for this inform
|
|
* request.
|
|
* @param cs The community string to be used for the inform request.
|
|
* @param cb The callback that is invoked when a request is complete.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @return The inform request object.
|
|
*
|
|
* @exception IllegalStateException This method has been invoked
|
|
* while the SNMP adaptor server was not active.
|
|
* @exception IOException An I/O error occurred while sending the
|
|
* inform request.
|
|
* @exception SnmpStatusException If the inform request exceeds the
|
|
* limit defined by <CODE>bufferSize</CODE>.
|
|
*/
|
|
@Override
|
|
public SnmpInformRequest snmpInformRequest(InetAddress addr,
|
|
String cs,
|
|
SnmpInformHandler cb,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList)
|
|
throws IllegalStateException, IOException, SnmpStatusException {
|
|
|
|
return snmpInformRequest(addr,
|
|
getInformPort(),
|
|
cs,
|
|
cb,
|
|
trapOid,
|
|
varBindList);
|
|
}
|
|
|
|
/**
|
|
* Sends an inform using SNMP V2 inform request format.
|
|
* <BR>The inform is sent to the specified <CODE>SnmpPeer</CODE>
|
|
* destination.
|
|
* <BR>The community string used is the one located in the
|
|
* <CODE>SnmpPeer</CODE> parameters
|
|
* (<CODE>SnmpParameters.getInformCommunity() </CODE>).
|
|
* <BR>The variable list included in the outgoing inform is composed
|
|
* of the following items:
|
|
* <UL>
|
|
* <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
|
|
* <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
|
|
* <CODE>trapOid</CODE></LI>
|
|
* <LI><CODE>all the (oid,values)</CODE> from the specified
|
|
* <CODE>varBindList</CODE></LI>
|
|
* </UL>
|
|
* To send an inform request, the SNMP adaptor server must be active.
|
|
*
|
|
* @param peer The <CODE>SnmpPeer</CODE> destination for this inform
|
|
* request.
|
|
* @param cb The callback that is invoked when a request is complete.
|
|
* @param trapOid The OID identifying the trap.
|
|
* @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
|
|
*
|
|
* @return The inform request object.
|
|
*
|
|
* @exception IllegalStateException This method has been invoked while
|
|
* the SNMP adaptor server was not active.
|
|
* @exception IOException An I/O error occurred while sending the
|
|
* inform request.
|
|
* @exception SnmpStatusException If the inform request exceeds the
|
|
* limit defined by <CODE>bufferSize</CODE>.
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
@Override
|
|
public SnmpInformRequest snmpInformRequest(SnmpPeer peer,
|
|
SnmpInformHandler cb,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList)
|
|
throws IllegalStateException, IOException, SnmpStatusException {
|
|
|
|
SnmpParameters p = (SnmpParameters) peer.getParams();
|
|
return snmpInformRequest(peer.getDestAddr(),
|
|
peer.getDestPort(),
|
|
p.getInformCommunity(),
|
|
cb,
|
|
trapOid,
|
|
varBindList);
|
|
}
|
|
|
|
/**
|
|
* Method that maps an SNMP error status in the passed protocolVersion
|
|
* according to the provided pdu type.
|
|
* @param errorStatus The error status to convert.
|
|
* @param protocolVersion The protocol version.
|
|
* @param reqPduType The pdu type.
|
|
*/
|
|
public static int mapErrorStatus(int errorStatus,
|
|
int protocolVersion,
|
|
int reqPduType) {
|
|
return SnmpSubRequestHandler.mapErrorStatus(errorStatus,
|
|
protocolVersion,
|
|
reqPduType);
|
|
}
|
|
|
|
private SnmpInformRequest snmpInformRequest(InetAddress addr,
|
|
int port,
|
|
String cs,
|
|
SnmpInformHandler cb,
|
|
SnmpOid trapOid,
|
|
SnmpVarBindList varBindList)
|
|
throws IllegalStateException, IOException, SnmpStatusException {
|
|
|
|
if (!isActive()) {
|
|
throw new IllegalStateException(
|
|
"Start SNMP adaptor server before carrying out this operation");
|
|
}
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"snmpInformRequest", "trapOid=" + trapOid);
|
|
}
|
|
|
|
// First, make an SNMP inform pdu:
|
|
// We clone varBindList and insert sysUpTime and snmpTrapOid variables.
|
|
//
|
|
SnmpVarBindList fullVbl ;
|
|
if (varBindList != null)
|
|
fullVbl = varBindList.clone() ;
|
|
else
|
|
fullVbl = new SnmpVarBindList(2) ;
|
|
SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
|
|
fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
|
|
0);
|
|
|
|
// Next, send the pdu to the specified destination
|
|
//
|
|
openInformSocketIfNeeded() ;
|
|
return informSession.makeAsyncRequest(addr, cs, cb, fullVbl, port) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* Open informSocket if it's not already done.
|
|
*/
|
|
synchronized void openInformSocketIfNeeded() throws SocketException {
|
|
if (informSession == null) {
|
|
informSession = new SnmpSession(this) ;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"openInformSocketIfNeeded",
|
|
"to send inform requests and receive inform responses");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close informSocket if the SNMP protocol adaptor is not ONLINE.
|
|
*/
|
|
synchronized void closeInformSocketIfNeeded() {
|
|
if ((informSession != null) && (state != ONLINE)) {
|
|
informSession.destroySession() ;
|
|
informSession = null ;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the IP address to bind.
|
|
* This getter is used to initialize the DatagramSocket in the
|
|
* SnmpSocket object created for the inform request stuff.
|
|
*/
|
|
InetAddress getAddress() {
|
|
return address;
|
|
}
|
|
|
|
|
|
// PROTECTED METHODS
|
|
//------------------
|
|
|
|
/**
|
|
* Finalizer of the SNMP protocol adaptor objects.
|
|
* This method is called by the garbage collector on an object
|
|
* when garbage collection determines that there are no more
|
|
* references to the object.
|
|
* <P>Closes the datagram socket associated to this SNMP protocol adaptor.
|
|
*/
|
|
@Override
|
|
protected void finalize() {
|
|
try {
|
|
if (socket != null) {
|
|
socket.close() ;
|
|
socket = null ;
|
|
}
|
|
|
|
threadService.terminate();
|
|
} catch (Exception e) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
|
|
"finalize", "Exception in finalizer", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
// PACKAGE METHODS
|
|
//----------------
|
|
|
|
/**
|
|
* Returns the string used in debug traces.
|
|
*/
|
|
@Override
|
|
String makeDebugTag() {
|
|
return "SnmpAdaptorServer["+ getProtocol() + ":" + getPort() + "]";
|
|
}
|
|
|
|
void updateRequestCounters(int pduType) {
|
|
switch(pduType) {
|
|
|
|
case pduGetRequestPdu:
|
|
snmpInGetRequests++;
|
|
break;
|
|
case pduGetNextRequestPdu:
|
|
snmpInGetNexts++;
|
|
break;
|
|
case pduSetRequestPdu:
|
|
snmpInSetRequests++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
snmpInPkts++ ;
|
|
}
|
|
|
|
void updateErrorCounters(int errorStatus) {
|
|
switch(errorStatus) {
|
|
|
|
case snmpRspNoError:
|
|
snmpOutGetResponses++;
|
|
break;
|
|
case snmpRspGenErr:
|
|
snmpOutGenErrs++;
|
|
break;
|
|
case snmpRspBadValue:
|
|
snmpOutBadValues++;
|
|
break;
|
|
case snmpRspNoSuchName:
|
|
snmpOutNoSuchNames++;
|
|
break;
|
|
case snmpRspTooBig:
|
|
snmpOutTooBigs++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
snmpOutPkts++ ;
|
|
}
|
|
|
|
void updateVarCounters(int pduType, int n) {
|
|
switch(pduType) {
|
|
|
|
case pduGetRequestPdu:
|
|
case pduGetNextRequestPdu:
|
|
case pduGetBulkRequestPdu:
|
|
snmpInTotalReqVars += n ;
|
|
break ;
|
|
case pduSetRequestPdu:
|
|
snmpInTotalSetVars += n ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
void incSnmpInASNParseErrs(int n) {
|
|
snmpInASNParseErrs += n ;
|
|
}
|
|
|
|
void incSnmpInBadVersions(int n) {
|
|
snmpInBadVersions += n ;
|
|
}
|
|
|
|
void incSnmpInBadCommunityUses(int n) {
|
|
snmpInBadCommunityUses += n ;
|
|
}
|
|
|
|
void incSnmpInBadCommunityNames(int n) {
|
|
snmpInBadCommunityNames += n ;
|
|
}
|
|
|
|
void incSnmpSilentDrops(int n) {
|
|
snmpSilentDrops += n ;
|
|
}
|
|
// PRIVATE METHODS
|
|
//----------------
|
|
|
|
/**
|
|
* Returns the time (in hundreths of second) elapsed since the SNMP
|
|
* protocol adaptor startup.
|
|
*/
|
|
long getSysUpTime() {
|
|
return (System.currentTimeMillis() - startUpTime) / 10 ;
|
|
}
|
|
|
|
/**
|
|
* Control the way the SnmpAdaptorServer service is deserialized.
|
|
*/
|
|
private void readObject(ObjectInputStream stream)
|
|
throws IOException, ClassNotFoundException {
|
|
|
|
// Call the default deserialization of the object.
|
|
//
|
|
stream.defaultReadObject();
|
|
|
|
// Call the specific initialization for the SnmpAdaptorServer service.
|
|
// This is for transient structures to be initialized to specific
|
|
// default values.
|
|
//
|
|
mibs = new Vector<>() ;
|
|
}
|
|
|
|
/**
|
|
* Common initializations.
|
|
*/
|
|
private void init(InetAddressAcl acl, int p, InetAddress a) {
|
|
|
|
root= new SnmpMibTree();
|
|
|
|
// The default Agent is initialized with a SnmpErrorHandlerAgent agent.
|
|
root.setDefaultAgent(new SnmpErrorHandlerAgent());
|
|
|
|
// For the trap time, use the time the agent started ...
|
|
//
|
|
startUpTime= java.lang.System.currentTimeMillis();
|
|
maxActiveClientCount = 10;
|
|
|
|
// Create the default message factory
|
|
pduFactory = new SnmpPduFactoryBER() ;
|
|
|
|
port = p ;
|
|
ipacl = acl ;
|
|
address = a ;
|
|
|
|
if ((ipacl == null) && (useAcl == true))
|
|
throw new IllegalArgumentException("ACL object cannot be null") ;
|
|
|
|
threadService = new ThreadService(threadNumber);
|
|
}
|
|
|
|
SnmpMibAgent getAgentMib(SnmpOid oid) {
|
|
return root.getAgentMib(oid);
|
|
}
|
|
|
|
@Override
|
|
protected Thread createMainThread() {
|
|
final Thread t = super.createMainThread();
|
|
t.setDaemon(true);
|
|
return t;
|
|
}
|
|
|
|
}
|