jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp/daemon/SnmpAdaptorServer.java
changeset 27214 d9f500808d8a
parent 27213 957656314d82
parent 27202 a489e57ccf52
child 27220 315d620f5726
equal deleted inserted replaced
27213:957656314d82 27214:d9f500808d8a
     1 /*
       
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 
       
    27 package com.sun.jmx.snmp.daemon;
       
    28 
       
    29 
       
    30 // java imports
       
    31 //
       
    32 import java.util.Vector;
       
    33 import java.util.Enumeration;
       
    34 import java.util.logging.Level;
       
    35 import java.net.DatagramSocket;
       
    36 import java.net.DatagramPacket;
       
    37 import java.net.InetAddress;
       
    38 import java.net.SocketException;
       
    39 import java.net.UnknownHostException;
       
    40 import java.io.ObjectInputStream;
       
    41 import java.io.IOException;
       
    42 import java.io.InterruptedIOException;
       
    43 
       
    44 
       
    45 // jmx imports
       
    46 //
       
    47 import javax.management.MBeanServer;
       
    48 import javax.management.MBeanRegistration;
       
    49 import javax.management.ObjectName;
       
    50 import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
       
    51 import com.sun.jmx.snmp.SnmpIpAddress;
       
    52 import com.sun.jmx.snmp.SnmpMessage;
       
    53 import com.sun.jmx.snmp.SnmpOid;
       
    54 import com.sun.jmx.snmp.SnmpPduFactory;
       
    55 import com.sun.jmx.snmp.SnmpPduPacket;
       
    56 import com.sun.jmx.snmp.SnmpPduRequest;
       
    57 import com.sun.jmx.snmp.SnmpPduTrap;
       
    58 import com.sun.jmx.snmp.SnmpTimeticks;
       
    59 import com.sun.jmx.snmp.SnmpVarBind;
       
    60 import com.sun.jmx.snmp.SnmpVarBindList;
       
    61 import com.sun.jmx.snmp.SnmpDefinitions;
       
    62 import com.sun.jmx.snmp.SnmpStatusException;
       
    63 import com.sun.jmx.snmp.SnmpTooBigException;
       
    64 import com.sun.jmx.snmp.InetAddressAcl;
       
    65 import com.sun.jmx.snmp.SnmpPeer;
       
    66 import com.sun.jmx.snmp.SnmpParameters;
       
    67 // SNMP Runtime imports
       
    68 //
       
    69 import com.sun.jmx.snmp.SnmpPduFactoryBER;
       
    70 import com.sun.jmx.snmp.agent.SnmpMibAgent;
       
    71 import com.sun.jmx.snmp.agent.SnmpMibHandler;
       
    72 import com.sun.jmx.snmp.agent.SnmpUserDataFactory;
       
    73 import com.sun.jmx.snmp.agent.SnmpErrorHandlerAgent;
       
    74 
       
    75 import com.sun.jmx.snmp.IPAcl.SnmpAcl;
       
    76 
       
    77 import com.sun.jmx.snmp.tasks.ThreadService;
       
    78 
       
    79 /**
       
    80  * Implements an adaptor on top of the SNMP protocol.
       
    81  * <P>
       
    82  * When this SNMP protocol adaptor is started it creates a datagram socket
       
    83  * and is able to receive requests and send traps or inform requests.
       
    84  * When it is stopped, the socket is closed and neither requests
       
    85  * and nor traps/inform request are processed.
       
    86  * <P>
       
    87  * The default port number of the socket is 161. This default value can be
       
    88  * changed by specifying a port number:
       
    89  * <UL>
       
    90  * <LI>in the object constructor</LI>
       
    91  * <LI>using the {@link com.sun.jmx.snmp.daemon.CommunicatorServer#setPort
       
    92  *     setPort} method before starting the adaptor</LI>
       
    93  * </UL>
       
    94  * The default object name is defined by {@link
       
    95  * com.sun.jmx.snmp.ServiceName#DOMAIN com.sun.jmx.snmp.ServiceName.DOMAIN}
       
    96  * and {@link com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
       
    97  * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
       
    98  * <P>
       
    99  * The SNMP protocol adaptor supports versions 1 and 2 of the SNMP protocol
       
   100  * in a stateless way: when it receives a v1 request, it replies with a v1
       
   101  * response, when it receives a v2 request it replies with a v2 response.
       
   102  * <BR>The method {@link #snmpV1Trap snmpV1Trap} sends traps using SNMP v1
       
   103  * format.
       
   104  * The method {@link #snmpV2Trap snmpV2Trap} sends traps using SNMP v2 format.
       
   105  * The method {@link #snmpInformRequest snmpInformRequest} sends inform
       
   106  * requests using SNMP v2 format.
       
   107  * <P>
       
   108  * To receive data packets, the SNMP protocol adaptor uses a buffer
       
   109  * which size can be configured using the property <CODE>bufferSize</CODE>
       
   110  * (default value is 1024).
       
   111  * Packets which do not fit into the buffer are rejected.
       
   112  * Increasing <CODE>bufferSize</CODE> allows the exchange of bigger packets.
       
   113  * However, the underlying networking system may impose a limit on the size
       
   114  * of UDP packets.
       
   115  * Packets which size exceed this limit will be rejected, no matter what
       
   116  * the value of <CODE>bufferSize</CODE> actually is.
       
   117  * <P>
       
   118  * An SNMP protocol adaptor may serve several managers concurrently. The
       
   119  * number of concurrent managers can be limited using the property
       
   120  * <CODE>maxActiveClientCount</CODE>.
       
   121  * <p>
       
   122  * The SNMP protocol adaptor specifies a default value (10) for the
       
   123  * <CODE>maxActiveClientCount</CODE> property. When the adaptor is stopped,
       
   124  * the active requests are interrupted and an error result is sent to
       
   125  * the managers.
       
   126  * <p><b>This API is a Sun Microsystems internal API  and is subject
       
   127  * to change without notice.</b></p>
       
   128  */
       
   129 
       
   130 public class SnmpAdaptorServer extends CommunicatorServer
       
   131     implements SnmpAdaptorServerMBean, MBeanRegistration, SnmpDefinitions,
       
   132                SnmpMibHandler {
       
   133 
       
   134     // PRIVATE VARIABLES
       
   135     //------------------
       
   136 
       
   137     /**
       
   138      * Port number for sending SNMP traps.
       
   139      * <BR>The default value is 162.
       
   140      */
       
   141     private int                 trapPort = 162;
       
   142 
       
   143     /**
       
   144      * Port number for sending SNMP inform requests.
       
   145      * <BR>The default value is 162.
       
   146      */
       
   147     private int                 informPort = 162;
       
   148 
       
   149     /**
       
   150      * The <CODE>InetAddress</CODE> used when creating the datagram socket.
       
   151      * <BR>It is specified when creating the SNMP protocol adaptor.
       
   152      * If not specified, the local host machine is used.
       
   153      */
       
   154     InetAddress address = null;
       
   155 
       
   156     /**
       
   157      * The IP address based ACL used by this SNMP protocol adaptor.
       
   158      */
       
   159     private InetAddressAcl ipacl = null;
       
   160 
       
   161     /**
       
   162      * The factory object.
       
   163      */
       
   164     private SnmpPduFactory pduFactory = null;
       
   165 
       
   166     /**
       
   167      * The user-data factory object.
       
   168      */
       
   169     private SnmpUserDataFactory userDataFactory = null;
       
   170 
       
   171     /**
       
   172      * Indicates if the SNMP protocol adaptor sends a response in case
       
   173      * of authentication failure
       
   174      */
       
   175     private boolean authRespEnabled = true;
       
   176 
       
   177     /**
       
   178      * Indicates if authentication traps are enabled.
       
   179      */
       
   180     private boolean authTrapEnabled = true;
       
   181 
       
   182     /**
       
   183      * The enterprise OID.
       
   184      * <BR>The default value is "1.3.6.1.4.1.42".
       
   185      */
       
   186     private SnmpOid enterpriseOid = new SnmpOid("1.3.6.1.4.1.42");
       
   187 
       
   188     /**
       
   189      * The buffer size of the SNMP protocol adaptor.
       
   190      * This buffer size is used for both incoming request and outgoing
       
   191      * inform requests.
       
   192      * <BR>The default value is 1024.
       
   193      */
       
   194     int bufferSize = 1024;
       
   195 
       
   196     private transient long            startUpTime     = 0;
       
   197     private transient DatagramSocket  socket          = null;
       
   198     transient DatagramSocket          trapSocket      = null;
       
   199     private transient SnmpSession     informSession   = null;
       
   200     private transient DatagramPacket  packet          = null;
       
   201     transient Vector<SnmpMibAgent>    mibs            = new Vector<>();
       
   202     private transient SnmpMibTree     root;
       
   203 
       
   204     /**
       
   205      * Whether ACL must be used.
       
   206      */
       
   207     private transient boolean         useAcl = true;
       
   208 
       
   209 
       
   210     // SENDING SNMP INFORMS STUFF
       
   211     //---------------------------
       
   212 
       
   213     /**
       
   214      * Number of times to try an inform request before giving up.
       
   215      * The default number is 3.
       
   216      */
       
   217     private int maxTries = 3 ;
       
   218 
       
   219     /**
       
   220      * The amount of time to wait for an inform response from the manager.
       
   221      * The default amount of time is 3000 millisec.
       
   222      */
       
   223     private int timeout = 3 * 1000 ;
       
   224 
       
   225     // VARIABLES REQUIRED FOR IMPLEMENTING SNMP GROUP (MIBII)
       
   226     //-------------------------------------------------------
       
   227 
       
   228     /**
       
   229      * The <CODE>snmpOutTraps</CODE> value defined in MIB-II.
       
   230      */
       
   231     int snmpOutTraps=0;
       
   232 
       
   233     /**
       
   234      * The <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
       
   235      */
       
   236     private int snmpOutGetResponses=0;
       
   237 
       
   238     /**
       
   239      * The <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
       
   240      */
       
   241     private int snmpOutGenErrs=0;
       
   242 
       
   243     /**
       
   244      * The <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
       
   245      */
       
   246     private int snmpOutBadValues=0;
       
   247 
       
   248     /**
       
   249      * The <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
       
   250      */
       
   251     private int snmpOutNoSuchNames=0;
       
   252 
       
   253     /**
       
   254      * The <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
       
   255      */
       
   256     private int snmpOutTooBigs=0;
       
   257 
       
   258     /**
       
   259      * The <CODE>snmpOutPkts</CODE> value defined in MIB-II.
       
   260      */
       
   261     int snmpOutPkts=0;
       
   262 
       
   263     /**
       
   264      * The <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
       
   265      */
       
   266     private int snmpInASNParseErrs=0;
       
   267 
       
   268     /**
       
   269      * The <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
       
   270      */
       
   271     private int snmpInBadCommunityUses=0;
       
   272 
       
   273     /**
       
   274      * The <CODE>snmpInBadCommunityNames</CODE> value defined in MIB-II.
       
   275      */
       
   276     private int snmpInBadCommunityNames=0;
       
   277 
       
   278     /**
       
   279      * The <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
       
   280      */
       
   281     private int snmpInBadVersions=0;
       
   282 
       
   283     /**
       
   284      * The <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
       
   285      */
       
   286     private int snmpInGetRequests=0;
       
   287 
       
   288     /**
       
   289      * The <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
       
   290      */
       
   291     private int snmpInGetNexts=0;
       
   292 
       
   293     /**
       
   294      * The <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
       
   295      */
       
   296     private int snmpInSetRequests=0;
       
   297 
       
   298     /**
       
   299      * The <CODE>snmpInPkts</CODE> value defined in MIB-II.
       
   300      */
       
   301     private int snmpInPkts=0;
       
   302 
       
   303     /**
       
   304      * The <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
       
   305      */
       
   306     private int snmpInTotalReqVars=0;
       
   307 
       
   308     /**
       
   309      * The <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
       
   310      */
       
   311     private int snmpInTotalSetVars=0;
       
   312 
       
   313     /**
       
   314      * The <CODE>snmpInTotalSetVars</CODE> value defined in rfc 1907 MIB-II.
       
   315      */
       
   316     private int snmpSilentDrops=0;
       
   317 
       
   318     private static final String InterruptSysCallMsg =
       
   319         "Interrupted system call";
       
   320     static final SnmpOid sysUpTimeOid = new SnmpOid("1.3.6.1.2.1.1.3.0") ;
       
   321     static final SnmpOid snmpTrapOidOid = new SnmpOid("1.3.6.1.6.3.1.1.4.1.0");
       
   322 
       
   323     private ThreadService threadService;
       
   324 
       
   325     private static int threadNumber = 6;
       
   326 
       
   327     static {
       
   328         String s = System.getProperty("com.sun.jmx.snmp.threadnumber");
       
   329 
       
   330         if (s != null) {
       
   331             try {
       
   332                 threadNumber = Integer.parseInt(System.getProperty(s));
       
   333             } catch (Exception e) {
       
   334                 SNMP_ADAPTOR_LOGGER.logp(Level.FINER,
       
   335                         SnmpAdaptorServer.class.getName(),
       
   336                         "<static init>",
       
   337                         "Got wrong value for com.sun.jmx.snmp.threadnumber: " +
       
   338                         s + ". Use the default value: " + threadNumber);
       
   339             }
       
   340         }
       
   341     }
       
   342 
       
   343     // PUBLIC CONSTRUCTORS
       
   344     //--------------------
       
   345 
       
   346     /**
       
   347      * Initializes this SNMP protocol adaptor using the default port (161).
       
   348      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
       
   349      * implementation of the <CODE>InetAddressAcl</CODE> interface.
       
   350      */
       
   351     public SnmpAdaptorServer() {
       
   352         this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
       
   353              null) ;
       
   354     }
       
   355 
       
   356     /**
       
   357      * Initializes this SNMP protocol adaptor using the specified port.
       
   358      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
       
   359      * implementation of the <CODE>InetAddressAcl</CODE> interface.
       
   360      *
       
   361      * @param port The port number for sending SNMP responses.
       
   362      */
       
   363     public SnmpAdaptorServer(int port) {
       
   364         this(true, null, port, null) ;
       
   365     }
       
   366 
       
   367     /**
       
   368      * Initializes this SNMP protocol adaptor using the default port (161)
       
   369      * and the specified IP address based ACL implementation.
       
   370      *
       
   371      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
       
   372      *        <code>null</code> means no ACL - everybody is authorized.
       
   373      *
       
   374      * @since 1.5
       
   375      */
       
   376     public SnmpAdaptorServer(InetAddressAcl acl) {
       
   377         this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
       
   378              null) ;
       
   379     }
       
   380 
       
   381     /**
       
   382      * Initializes this SNMP protocol adaptor using the default port (161)
       
   383      * and the
       
   384      * specified <CODE>InetAddress</CODE>.
       
   385      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
       
   386      * implementation of the <CODE>InetAddressAcl</CODE> interface.
       
   387      *
       
   388      * @param addr The IP address to bind.
       
   389      */
       
   390     public SnmpAdaptorServer(InetAddress addr) {
       
   391         this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
       
   392              addr) ;
       
   393     }
       
   394 
       
   395     /**
       
   396      * Initializes this SNMP protocol adaptor using the specified port and the
       
   397      * specified IP address based ACL implementation.
       
   398      *
       
   399      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
       
   400      *        <code>null</code> means no ACL - everybody is authorized.
       
   401      * @param port The port number for sending SNMP responses.
       
   402      *
       
   403      * @since 1.5
       
   404      */
       
   405     public SnmpAdaptorServer(InetAddressAcl acl, int port) {
       
   406         this(false, acl, port, null) ;
       
   407     }
       
   408 
       
   409     /**
       
   410      * Initializes this SNMP protocol adaptor using the specified port and the
       
   411      * specified <CODE>InetAddress</CODE>.
       
   412      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
       
   413      * implementation of the <CODE>InetAddressAcl</CODE> interface.
       
   414      *
       
   415      * @param port The port number for sending SNMP responses.
       
   416      * @param addr The IP address to bind.
       
   417      */
       
   418     public SnmpAdaptorServer(int port, InetAddress addr) {
       
   419         this(true, null, port, addr) ;
       
   420     }
       
   421 
       
   422     /**
       
   423      * Initializes this SNMP protocol adaptor using the specified IP
       
   424      * address based ACL implementation and the specified
       
   425      * <CODE>InetAddress</CODE>.
       
   426      *
       
   427      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
       
   428      * @param addr The IP address to bind.
       
   429      *
       
   430      * @since 1.5
       
   431      */
       
   432     public SnmpAdaptorServer(InetAddressAcl acl, InetAddress addr) {
       
   433         this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
       
   434              addr) ;
       
   435     }
       
   436 
       
   437     /**
       
   438      * Initializes this SNMP protocol adaptor using the specified port, the
       
   439      * specified  address based ACL implementation and the specified
       
   440      * <CODE>InetAddress</CODE>.
       
   441      *
       
   442      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
       
   443      * @param port The port number for sending SNMP responses.
       
   444      * @param addr The IP address to bind.
       
   445      *
       
   446      * @since 1.5
       
   447      */
       
   448     public SnmpAdaptorServer(InetAddressAcl acl, int port, InetAddress addr) {
       
   449         this(false, acl, port, addr);
       
   450     }
       
   451 
       
   452     /**
       
   453      * Initializes this SNMP protocol adaptor using the specified port and the
       
   454      * specified <CODE>InetAddress</CODE>.
       
   455      * This constructor allows to initialize an SNMP adaptor without using
       
   456      * the ACL mechanism (by setting the <CODE>useAcl</CODE> parameter to
       
   457      * false).
       
   458      * <br>This constructor must be used in particular with a platform that
       
   459      * does not support the <CODE>java.security.acl</CODE> package like pJava.
       
   460      *
       
   461      * @param useAcl Specifies if this new SNMP adaptor uses the ACL mechanism.
       
   462      * If the specified parameter is set to <CODE>true</CODE>, this
       
   463      * constructor is equivalent to
       
   464      * <CODE>SnmpAdaptorServer((int)port,(InetAddress)addr)</CODE>.
       
   465      * @param port The port number for sending SNMP responses.
       
   466      * @param addr The IP address to bind.
       
   467      */
       
   468     public SnmpAdaptorServer(boolean useAcl, int port, InetAddress addr) {
       
   469         this(useAcl,null,port,addr);
       
   470     }
       
   471 
       
   472     // If forceAcl is `true' and InetAddressAcl is null, then a default
       
   473     // SnmpAcl object is created.
       
   474     //
       
   475     private SnmpAdaptorServer(boolean forceAcl, InetAddressAcl acl,
       
   476                               int port, InetAddress addr) {
       
   477         super(CommunicatorServer.SNMP_TYPE) ;
       
   478 
       
   479 
       
   480         // Initialize the ACL implementation.
       
   481         //
       
   482         if (acl == null && forceAcl) {
       
   483             try {
       
   484                 acl = new SnmpAcl("SNMP protocol adaptor IP ACL");
       
   485             } catch (UnknownHostException e) {
       
   486                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   487                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
   488                         "constructor", "UnknowHostException when creating ACL",e);
       
   489                 }
       
   490             }
       
   491         } else {
       
   492             this.useAcl = (acl!=null) || forceAcl;
       
   493         }
       
   494 
       
   495         init(acl, port, addr) ;
       
   496     }
       
   497 
       
   498     // GETTERS AND SETTERS
       
   499     //--------------------
       
   500 
       
   501     /**
       
   502      * Gets the number of managers that have been processed by this
       
   503      * SNMP protocol adaptor  since its creation.
       
   504      *
       
   505      * @return The number of managers handled by this SNMP protocol adaptor
       
   506      * since its creation. This counter is not reset by the <CODE>stop</CODE>
       
   507      * method.
       
   508      */
       
   509     @Override
       
   510     public int getServedClientCount() {
       
   511         return super.getServedClientCount();
       
   512     }
       
   513 
       
   514     /**
       
   515      * Gets the number of managers currently being processed by this
       
   516      * SNMP protocol adaptor.
       
   517      *
       
   518      * @return The number of managers currently being processed by this
       
   519      * SNMP protocol adaptor.
       
   520      */
       
   521     @Override
       
   522     public int getActiveClientCount() {
       
   523         return super.getActiveClientCount();
       
   524     }
       
   525 
       
   526     /**
       
   527      * Gets the maximum number of managers that this SNMP protocol adaptor can
       
   528      * process concurrently.
       
   529      *
       
   530      * @return The maximum number of managers that this SNMP protocol adaptor
       
   531      *         can process concurrently.
       
   532      */
       
   533     @Override
       
   534     public int getMaxActiveClientCount() {
       
   535         return super.getMaxActiveClientCount();
       
   536     }
       
   537 
       
   538     /**
       
   539      * Sets the maximum number of managers this SNMP protocol adaptor can
       
   540      * process concurrently.
       
   541      *
       
   542      * @param c The number of managers.
       
   543      *
       
   544      * @exception java.lang.IllegalStateException This method has been invoked
       
   545      * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
       
   546      */
       
   547     @Override
       
   548     public void setMaxActiveClientCount(int c)
       
   549         throws java.lang.IllegalStateException {
       
   550         super.setMaxActiveClientCount(c);
       
   551     }
       
   552 
       
   553     /**
       
   554      * Returns the Ip address based ACL used by this SNMP protocol adaptor.
       
   555      * @return The <CODE>InetAddressAcl</CODE> implementation.
       
   556      *
       
   557      * @since 1.5
       
   558      */
       
   559     @Override
       
   560     public InetAddressAcl getInetAddressAcl() {
       
   561         return ipacl;
       
   562     }
       
   563 
       
   564     /**
       
   565      * Returns the port used by this SNMP protocol adaptor for sending traps.
       
   566      * By default, port 162 is used.
       
   567      *
       
   568      * @return The port number for sending SNMP traps.
       
   569      */
       
   570     @Override
       
   571     public Integer getTrapPort() {
       
   572         return trapPort;
       
   573     }
       
   574 
       
   575     /**
       
   576      * Sets the port used by this SNMP protocol adaptor for sending traps.
       
   577      *
       
   578      * @param port The port number for sending SNMP traps.
       
   579      */
       
   580     @Override
       
   581     public void setTrapPort(Integer port) {
       
   582         setTrapPort(port.intValue());
       
   583     }
       
   584 
       
   585     /**
       
   586      * Sets the port used by this SNMP protocol adaptor for sending traps.
       
   587      *
       
   588      * @param port The port number for sending SNMP traps.
       
   589      */
       
   590     public void setTrapPort(int port) {
       
   591         int val= port ;
       
   592         if (val < 0) throw new
       
   593             IllegalArgumentException("Trap port cannot be a negative value");
       
   594         trapPort= val ;
       
   595     }
       
   596 
       
   597     /**
       
   598      * Returns the port used by this SNMP protocol adaptor for sending
       
   599      * inform requests. By default, port 162 is used.
       
   600      *
       
   601      * @return The port number for sending SNMP inform requests.
       
   602      */
       
   603     @Override
       
   604     public int getInformPort() {
       
   605         return informPort;
       
   606     }
       
   607 
       
   608     /**
       
   609      * Sets the port used by this SNMP protocol adaptor for sending
       
   610      * inform requests.
       
   611      *
       
   612      * @param port The port number for sending SNMP inform requests.
       
   613      */
       
   614     @Override
       
   615     public void setInformPort(int port) {
       
   616         if (port < 0)
       
   617             throw new IllegalArgumentException("Inform request port "+
       
   618                                                "cannot be a negative value");
       
   619         informPort= port ;
       
   620     }
       
   621 
       
   622     /**
       
   623      * Returns the protocol of this SNMP protocol adaptor.
       
   624      *
       
   625      * @return The string "snmp".
       
   626      */
       
   627     @Override
       
   628     public String getProtocol() {
       
   629         return "snmp";
       
   630     }
       
   631 
       
   632     /**
       
   633      * Returns the buffer size of this SNMP protocol adaptor.
       
   634      * This buffer size is used for both incoming request and outgoing
       
   635      * inform requests.
       
   636      * By default, buffer size 1024 is used.
       
   637      *
       
   638      * @return The buffer size.
       
   639      */
       
   640     @Override
       
   641     public Integer getBufferSize() {
       
   642         return bufferSize;
       
   643     }
       
   644 
       
   645     /**
       
   646      * Sets the buffer size of this SNMP protocol adaptor.
       
   647      * This buffer size is used for both incoming request and outgoing
       
   648      * inform requests.
       
   649      *
       
   650      * @param s The buffer size.
       
   651      *
       
   652      * @exception java.lang.IllegalStateException This method has been invoked
       
   653      * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
       
   654      */
       
   655     @Override
       
   656     public void setBufferSize(Integer s)
       
   657         throws java.lang.IllegalStateException {
       
   658         if ((state == ONLINE) || (state == STARTING)) {
       
   659             throw new IllegalStateException("Stop server before carrying out"+
       
   660                                             " this operation");
       
   661         }
       
   662         bufferSize = s.intValue() ;
       
   663     }
       
   664 
       
   665     /**
       
   666      * Gets the number of times to try sending an inform request before
       
   667      * giving up.
       
   668      * By default, a maximum of 3 tries is used.
       
   669      * @return The maximun number of tries.
       
   670      */
       
   671     @Override
       
   672     final public int getMaxTries() {
       
   673         return maxTries;
       
   674     }
       
   675 
       
   676     /**
       
   677      * Changes the maximun number of times to try sending an inform
       
   678      * request before giving up.
       
   679      * @param newMaxTries The maximun number of tries.
       
   680      */
       
   681     @Override
       
   682     final public synchronized void setMaxTries(int newMaxTries) {
       
   683         if (newMaxTries < 0)
       
   684             throw new IllegalArgumentException();
       
   685         maxTries = newMaxTries;
       
   686     }
       
   687 
       
   688     /**
       
   689      * Gets the timeout to wait for an inform response from the manager.
       
   690      * By default, a timeout of 3 seconds is used.
       
   691      * @return The value of the timeout property.
       
   692      */
       
   693     @Override
       
   694     final public int getTimeout() {
       
   695         return timeout;
       
   696     }
       
   697 
       
   698     /**
       
   699      * Changes the timeout to wait for an inform response from the manager.
       
   700      * @param newTimeout The timeout (in milliseconds).
       
   701      */
       
   702     @Override
       
   703     final public synchronized void setTimeout(int newTimeout) {
       
   704         if (newTimeout < 0)
       
   705             throw new IllegalArgumentException();
       
   706         timeout= newTimeout;
       
   707     }
       
   708 
       
   709     /**
       
   710      * Returns the message factory of this SNMP protocol adaptor.
       
   711      *
       
   712      * @return The factory object.
       
   713      */
       
   714     @Override
       
   715     public SnmpPduFactory getPduFactory() {
       
   716         return pduFactory ;
       
   717     }
       
   718 
       
   719     /**
       
   720      * Sets the message factory of this SNMP protocol adaptor.
       
   721      *
       
   722      * @param factory The factory object (null means the default factory).
       
   723      */
       
   724     @Override
       
   725     public void setPduFactory(SnmpPduFactory factory) {
       
   726         if (factory == null)
       
   727             pduFactory = new SnmpPduFactoryBER() ;
       
   728         else
       
   729             pduFactory = factory ;
       
   730     }
       
   731 
       
   732     /**
       
   733      * Set the user-data factory of this SNMP protocol adaptor.
       
   734      *
       
   735      * @param factory The factory object (null means no factory).
       
   736      * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
       
   737      */
       
   738     @Override
       
   739     public void setUserDataFactory(SnmpUserDataFactory factory) {
       
   740         userDataFactory = factory ;
       
   741     }
       
   742 
       
   743     /**
       
   744      * Get the user-data factory associated with this SNMP protocol adaptor.
       
   745      *
       
   746      * @return The factory object (null means no factory).
       
   747      * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
       
   748      */
       
   749     @Override
       
   750     public SnmpUserDataFactory getUserDataFactory() {
       
   751         return userDataFactory;
       
   752     }
       
   753 
       
   754     /**
       
   755      * Returns <CODE>true</CODE> if authentication traps are enabled.
       
   756      * <P>
       
   757      * When this feature is enabled, the SNMP protocol adaptor sends
       
   758      * an <CODE>authenticationFailure</CODE> trap each time an
       
   759      * authentication fails.
       
   760      * <P>
       
   761      * The default behaviour is to send authentication traps.
       
   762      *
       
   763      * @return <CODE>true</CODE> if authentication traps are enabled,
       
   764      *         <CODE>false</CODE> otherwise.
       
   765      */
       
   766     @Override
       
   767     public boolean getAuthTrapEnabled() {
       
   768         return authTrapEnabled ;
       
   769     }
       
   770 
       
   771     /**
       
   772      * Sets the flag indicating if traps need to be sent in case of
       
   773      * authentication failure.
       
   774      *
       
   775      * @param enabled Flag indicating if traps need to be sent.
       
   776      */
       
   777     @Override
       
   778     public void setAuthTrapEnabled(boolean enabled) {
       
   779         authTrapEnabled = enabled ;
       
   780     }
       
   781 
       
   782     /**
       
   783      * Returns <code>true</code> if this SNMP protocol adaptor sends a
       
   784      * response in case of authentication failure.
       
   785      * <P>
       
   786      * When this feature is enabled, the SNMP protocol adaptor sends a
       
   787      * response with <CODE>noSuchName</CODE> or <CODE>readOnly</CODE> when
       
   788      * the authentication failed. If the flag is disabled, the
       
   789      * SNMP protocol adaptor trashes the PDU silently.
       
   790      * <P>
       
   791      * The default behavior is to send responses.
       
   792      *
       
   793      * @return <CODE>true</CODE> if responses are sent.
       
   794      */
       
   795     @Override
       
   796     public boolean getAuthRespEnabled() {
       
   797         return authRespEnabled ;
       
   798     }
       
   799 
       
   800     /**
       
   801      * Sets the flag indicating if responses need to be sent in case of
       
   802      * authentication failure.
       
   803      *
       
   804      * @param enabled Flag indicating if responses need to be sent.
       
   805      */
       
   806     @Override
       
   807     public void setAuthRespEnabled(boolean enabled) {
       
   808         authRespEnabled = enabled ;
       
   809     }
       
   810 
       
   811     /**
       
   812      * Returns the enterprise OID. It is used by
       
   813      * {@link #snmpV1Trap snmpV1Trap} to fill the 'enterprise' field of the
       
   814      * trap request.
       
   815      *
       
   816      * @return The OID in string format "x.x.x.x".
       
   817      */
       
   818     @Override
       
   819     public String getEnterpriseOid() {
       
   820         return enterpriseOid.toString() ;
       
   821     }
       
   822 
       
   823     /**
       
   824      * Sets the enterprise OID.
       
   825      *
       
   826      * @param oid The OID in string format "x.x.x.x".
       
   827      *
       
   828      * @exception IllegalArgumentException The string format is incorrect
       
   829      */
       
   830     @Override
       
   831     public void setEnterpriseOid(String oid) throws IllegalArgumentException {
       
   832         enterpriseOid = new SnmpOid(oid) ;
       
   833     }
       
   834 
       
   835     /**
       
   836      * Returns the names of the MIBs available in this SNMP protocol adaptor.
       
   837      *
       
   838      * @return An array of MIB names.
       
   839      */
       
   840     @Override
       
   841     public String[] getMibs() {
       
   842         String[] result = new String[mibs.size()] ;
       
   843         int i = 0 ;
       
   844         for (Enumeration<SnmpMibAgent> e = mibs.elements() ; e.hasMoreElements() ;) {
       
   845             SnmpMibAgent mib = e.nextElement() ;
       
   846             result[i++] = mib.getMibName();
       
   847         }
       
   848         return result ;
       
   849     }
       
   850 
       
   851     // GETTERS FOR SNMP GROUP (MIBII)
       
   852     //-------------------------------
       
   853 
       
   854     /**
       
   855      * Returns the <CODE>snmpOutTraps</CODE> value defined in MIB-II.
       
   856      *
       
   857      * @return The <CODE>snmpOutTraps</CODE> value.
       
   858      */
       
   859     @Override
       
   860     public Long getSnmpOutTraps() {
       
   861         return (long)snmpOutTraps;
       
   862     }
       
   863 
       
   864     /**
       
   865      * Returns the <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
       
   866      *
       
   867      * @return The <CODE>snmpOutGetResponses</CODE> value.
       
   868      */
       
   869     @Override
       
   870     public Long getSnmpOutGetResponses() {
       
   871         return (long)snmpOutGetResponses;
       
   872     }
       
   873 
       
   874     /**
       
   875      * Returns the <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
       
   876      *
       
   877      * @return The <CODE>snmpOutGenErrs</CODE> value.
       
   878      */
       
   879     @Override
       
   880     public Long getSnmpOutGenErrs() {
       
   881         return (long)snmpOutGenErrs;
       
   882     }
       
   883 
       
   884     /**
       
   885      * Returns the <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
       
   886      *
       
   887      * @return The <CODE>snmpOutBadValues</CODE> value.
       
   888      */
       
   889     @Override
       
   890     public Long getSnmpOutBadValues() {
       
   891         return (long)snmpOutBadValues;
       
   892     }
       
   893 
       
   894     /**
       
   895      * Returns the <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
       
   896      *
       
   897      * @return The <CODE>snmpOutNoSuchNames</CODE> value.
       
   898      */
       
   899     @Override
       
   900     public Long getSnmpOutNoSuchNames() {
       
   901         return (long)snmpOutNoSuchNames;
       
   902     }
       
   903 
       
   904     /**
       
   905      * Returns the <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
       
   906      *
       
   907      * @return The <CODE>snmpOutTooBigs</CODE> value.
       
   908      */
       
   909     @Override
       
   910     public Long getSnmpOutTooBigs() {
       
   911         return (long)snmpOutTooBigs;
       
   912     }
       
   913 
       
   914     /**
       
   915      * Returns the <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
       
   916      *
       
   917      * @return The <CODE>snmpInASNParseErrs</CODE> value.
       
   918      */
       
   919     @Override
       
   920     public Long getSnmpInASNParseErrs() {
       
   921         return (long)snmpInASNParseErrs;
       
   922     }
       
   923 
       
   924     /**
       
   925      * Returns the <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
       
   926      *
       
   927      * @return The <CODE>snmpInBadCommunityUses</CODE> value.
       
   928      */
       
   929     @Override
       
   930     public Long getSnmpInBadCommunityUses() {
       
   931         return (long)snmpInBadCommunityUses;
       
   932     }
       
   933 
       
   934     /**
       
   935      * Returns the <CODE>snmpInBadCommunityNames</CODE> value defined in
       
   936      * MIB-II.
       
   937      *
       
   938      * @return The <CODE>snmpInBadCommunityNames</CODE> value.
       
   939      */
       
   940     @Override
       
   941     public Long getSnmpInBadCommunityNames() {
       
   942         return (long)snmpInBadCommunityNames;
       
   943     }
       
   944 
       
   945     /**
       
   946      * Returns the <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
       
   947      *
       
   948      * @return The <CODE>snmpInBadVersions</CODE> value.
       
   949      */
       
   950     @Override
       
   951     public Long getSnmpInBadVersions() {
       
   952         return (long)snmpInBadVersions;
       
   953     }
       
   954 
       
   955     /**
       
   956      * Returns the <CODE>snmpOutPkts</CODE> value defined in MIB-II.
       
   957      *
       
   958      * @return The <CODE>snmpOutPkts</CODE> value.
       
   959      */
       
   960     @Override
       
   961     public Long getSnmpOutPkts() {
       
   962         return (long)snmpOutPkts;
       
   963     }
       
   964 
       
   965     /**
       
   966      * Returns the <CODE>snmpInPkts</CODE> value defined in MIB-II.
       
   967      *
       
   968      * @return The <CODE>snmpInPkts</CODE> value.
       
   969      */
       
   970     @Override
       
   971     public Long getSnmpInPkts() {
       
   972         return (long)snmpInPkts;
       
   973     }
       
   974 
       
   975     /**
       
   976      * Returns the <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
       
   977      *
       
   978      * @return The <CODE>snmpInGetRequests</CODE> value.
       
   979      */
       
   980     @Override
       
   981     public Long getSnmpInGetRequests() {
       
   982         return (long)snmpInGetRequests;
       
   983     }
       
   984 
       
   985     /**
       
   986      * Returns the <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
       
   987      *
       
   988      * @return The <CODE>snmpInGetNexts</CODE> value.
       
   989      */
       
   990     @Override
       
   991     public Long getSnmpInGetNexts() {
       
   992         return (long)snmpInGetNexts;
       
   993     }
       
   994 
       
   995     /**
       
   996      * Returns the <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
       
   997      *
       
   998      * @return The <CODE>snmpInSetRequests</CODE> value.
       
   999      */
       
  1000     @Override
       
  1001     public Long getSnmpInSetRequests() {
       
  1002         return (long)snmpInSetRequests;
       
  1003     }
       
  1004 
       
  1005     /**
       
  1006      * Returns the <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
       
  1007      *
       
  1008      * @return The <CODE>snmpInTotalSetVars</CODE> value.
       
  1009      */
       
  1010     @Override
       
  1011     public Long getSnmpInTotalSetVars() {
       
  1012         return (long)snmpInTotalSetVars;
       
  1013     }
       
  1014 
       
  1015     /**
       
  1016      * Returns the <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
       
  1017      *
       
  1018      * @return The <CODE>snmpInTotalReqVars</CODE> value.
       
  1019      */
       
  1020     @Override
       
  1021     public Long getSnmpInTotalReqVars() {
       
  1022         return (long)snmpInTotalReqVars;
       
  1023     }
       
  1024 
       
  1025     /**
       
  1026      * Returns the <CODE>snmpSilentDrops</CODE> value defined in RFC
       
  1027      * 1907 NMPv2-MIB .
       
  1028      *
       
  1029      * @return The <CODE>snmpSilentDrops</CODE> value.
       
  1030      *
       
  1031      * @since 1.5
       
  1032      */
       
  1033     @Override
       
  1034     public Long getSnmpSilentDrops() {
       
  1035         return (long)snmpSilentDrops;
       
  1036     }
       
  1037 
       
  1038     /**
       
  1039      * Returns the <CODE>snmpProxyDrops</CODE> value defined in RFC
       
  1040      * 1907 NMPv2-MIB .
       
  1041      *
       
  1042      * @return The <CODE>snmpProxyDrops</CODE> value.
       
  1043      *
       
  1044      * @since 1.5
       
  1045      */
       
  1046     @Override
       
  1047     public Long getSnmpProxyDrops() {
       
  1048         return 0L;
       
  1049     }
       
  1050 
       
  1051 
       
  1052     // PUBLIC METHODS
       
  1053     //---------------
       
  1054 
       
  1055     /**
       
  1056      * Allows the MBean to perform any operations it needs before being
       
  1057      * registered in the MBean server.
       
  1058      * If the name of the SNMP protocol adaptor MBean is not specified,
       
  1059      * it is initialized with the default value:
       
  1060      * {@link com.sun.jmx.snmp.ServiceName#DOMAIN
       
  1061      *   com.sun.jmx.snmp.ServiceName.DOMAIN}:{@link
       
  1062      * com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
       
  1063      * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
       
  1064      * If any exception is raised, the SNMP protocol adaptor MBean will
       
  1065      * not be registered in the MBean server.
       
  1066      *
       
  1067      * @param server The MBean server to register the service with.
       
  1068      * @param name The object name.
       
  1069      *
       
  1070      * @return The name of the SNMP protocol adaptor registered.
       
  1071      *
       
  1072      * @exception java.lang.Exception
       
  1073      */
       
  1074     @Override
       
  1075     public ObjectName preRegister(MBeanServer server, ObjectName name)
       
  1076         throws java.lang.Exception {
       
  1077 
       
  1078         if (name == null) {
       
  1079             name = new ObjectName(server.getDefaultDomain() + ":" +
       
  1080                              com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER);
       
  1081         }
       
  1082         return (super.preRegister(server, name));
       
  1083     }
       
  1084 
       
  1085     /**
       
  1086      * Not used in this context.
       
  1087      */
       
  1088     @Override
       
  1089     public void postRegister (Boolean registrationDone) {
       
  1090         super.postRegister(registrationDone);
       
  1091     }
       
  1092 
       
  1093     /**
       
  1094      * Not used in this context.
       
  1095      */
       
  1096     @Override
       
  1097     public void preDeregister() throws java.lang.Exception {
       
  1098         super.preDeregister();
       
  1099     }
       
  1100 
       
  1101     /**
       
  1102      * Not used in this context.
       
  1103      */
       
  1104     @Override
       
  1105     public void postDeregister() {
       
  1106         super.postDeregister();
       
  1107     }
       
  1108 
       
  1109     /**
       
  1110      * Adds a new MIB in the SNMP MIB handler.
       
  1111      *
       
  1112      * @param mib The MIB to add.
       
  1113      *
       
  1114      * @return A reference to the SNMP MIB handler.
       
  1115      *
       
  1116      * @exception IllegalArgumentException If the parameter is null.
       
  1117      */
       
  1118     @Override
       
  1119     public SnmpMibHandler addMib(SnmpMibAgent mib)
       
  1120         throws IllegalArgumentException {
       
  1121         if (mib == null) {
       
  1122             throw new IllegalArgumentException() ;
       
  1123         }
       
  1124 
       
  1125         if(!mibs.contains(mib))
       
  1126             mibs.addElement(mib);
       
  1127 
       
  1128         root.register(mib);
       
  1129 
       
  1130         return this;
       
  1131     }
       
  1132 
       
  1133     /**
       
  1134      * Adds a new MIB in the SNMP MIB handler.
       
  1135      * This method is to be called to set a specific agent to a specific OID.
       
  1136      * This can be useful when dealing with MIB overlapping.
       
  1137      * Some OID can be implemented in more than one MIB. In this case,
       
  1138      * the OID nearer agent will be used on SNMP operations.
       
  1139      *
       
  1140      * @param mib The MIB to add.
       
  1141      * @param oids The set of OIDs this agent implements.
       
  1142      *
       
  1143      * @return A reference to the SNMP MIB handler.
       
  1144      *
       
  1145      * @exception IllegalArgumentException If the parameter is null.
       
  1146      *
       
  1147      * @since 1.5
       
  1148      */
       
  1149     @Override
       
  1150     public SnmpMibHandler addMib(SnmpMibAgent mib, SnmpOid[] oids)
       
  1151         throws IllegalArgumentException {
       
  1152         if (mib == null) {
       
  1153             throw new IllegalArgumentException() ;
       
  1154         }
       
  1155 
       
  1156         //If null oid array, just add it to the mib.
       
  1157         if(oids == null)
       
  1158             return addMib(mib);
       
  1159 
       
  1160         if(!mibs.contains(mib))
       
  1161             mibs.addElement(mib);
       
  1162 
       
  1163         for (int i = 0; i < oids.length; i++) {
       
  1164             root.register(mib, oids[i].longValue());
       
  1165         }
       
  1166         return this;
       
  1167     }
       
  1168 
       
  1169     /**
       
  1170      * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
       
  1171      * <CODE>contextName</CODE> is useless and this method
       
  1172      * is equivalent to <CODE>addMib(SnmpMibAgent mib)</CODE>.
       
  1173      *
       
  1174      * @param mib The MIB to add.
       
  1175      * @param contextName The MIB context name.
       
  1176      * @return A reference on the SNMP MIB handler.
       
  1177      *
       
  1178      * @exception IllegalArgumentException If the parameter is null.
       
  1179      *
       
  1180      * @since 1.5
       
  1181      */
       
  1182     @Override
       
  1183     public SnmpMibHandler addMib(SnmpMibAgent mib, String contextName)
       
  1184         throws IllegalArgumentException {
       
  1185         return addMib(mib);
       
  1186     }
       
  1187 
       
  1188     /**
       
  1189      * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
       
  1190      * <CODE>contextName</CODE> is useless and this method
       
  1191      * is equivalent to <CODE>addMib(SnmpMibAgent mib, SnmpOid[] oids)</CODE>.
       
  1192      *
       
  1193      * @param mib The MIB to add.
       
  1194      * @param contextName The MIB context. If null is passed, will be
       
  1195      *        registered in the default context.
       
  1196      * @param oids The set of OIDs this agent implements.
       
  1197      *
       
  1198      * @return A reference to the SNMP MIB handler.
       
  1199      *
       
  1200      * @exception IllegalArgumentException If the parameter is null.
       
  1201      *
       
  1202      * @since 1.5
       
  1203      */
       
  1204     @Override
       
  1205     public SnmpMibHandler addMib(SnmpMibAgent mib,
       
  1206                                  String contextName,
       
  1207                                  SnmpOid[] oids)
       
  1208         throws IllegalArgumentException {
       
  1209 
       
  1210         return addMib(mib, oids);
       
  1211     }
       
  1212 
       
  1213     /**
       
  1214      * Removes the specified MIB from the SNMP protocol adaptor.
       
  1215      * In SNMP V1 and V2 the <CODE>contextName</CODE> is useless and this
       
  1216      * method is equivalent to <CODE>removeMib(SnmpMibAgent mib)</CODE>.
       
  1217      *
       
  1218      * @param mib The MIB to be removed.
       
  1219      * @param contextName The context name used at registration time.
       
  1220      *
       
  1221      * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
       
  1222      * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
       
  1223      * otherwise.
       
  1224      *
       
  1225      * @since 1.5
       
  1226      */
       
  1227     @Override
       
  1228     public boolean removeMib(SnmpMibAgent mib, String contextName) {
       
  1229         return removeMib(mib);
       
  1230     }
       
  1231 
       
  1232     /**
       
  1233      * Removes the specified MIB from the SNMP protocol adaptor.
       
  1234      *
       
  1235      * @param mib The MIB to be removed.
       
  1236      *
       
  1237      * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was a MIB
       
  1238      *         included in the SNMP MIB handler, <CODE>false</CODE> otherwise.
       
  1239      */
       
  1240     @Override
       
  1241     public boolean removeMib(SnmpMibAgent mib) {
       
  1242         root.unregister(mib);
       
  1243         return (mibs.removeElement(mib)) ;
       
  1244     }
       
  1245 
       
  1246     /**
       
  1247      * Removes the specified MIB from the SNMP protocol adaptor.
       
  1248      *
       
  1249      * @param mib The MIB to be removed.
       
  1250      * @param oids The oid the MIB was previously registered for.
       
  1251      * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
       
  1252      * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
       
  1253      * otherwise.
       
  1254      *
       
  1255      * @since 1.5
       
  1256      */
       
  1257     @Override
       
  1258     public boolean removeMib(SnmpMibAgent mib, SnmpOid[] oids) {
       
  1259         root.unregister(mib, oids);
       
  1260         return (mibs.removeElement(mib)) ;
       
  1261     }
       
  1262 
       
  1263      /**
       
  1264      * Removes the specified MIB from the SNMP protocol adaptor.
       
  1265      *
       
  1266      * @param mib The MIB to be removed.
       
  1267      * @param contextName The context name used at registration time.
       
  1268      * @param oids The oid the MIB was previously registered for.
       
  1269      * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
       
  1270      * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
       
  1271      * otherwise.
       
  1272      *
       
  1273      * @since 1.5
       
  1274      */
       
  1275     @Override
       
  1276     public boolean removeMib(SnmpMibAgent mib,
       
  1277                              String contextName,
       
  1278                              SnmpOid[] oids) {
       
  1279         return removeMib(mib, oids);
       
  1280     }
       
  1281 
       
  1282     // SUBCLASSING OF COMMUNICATOR SERVER
       
  1283     //-----------------------------------
       
  1284 
       
  1285     /**
       
  1286      * Creates the datagram socket.
       
  1287      */
       
  1288     @Override
       
  1289     protected void doBind()
       
  1290         throws CommunicationException, InterruptedException {
       
  1291 
       
  1292         try {
       
  1293             synchronized (this) {
       
  1294                 socket = new DatagramSocket(port, address) ;
       
  1295             }
       
  1296             dbgTag = makeDebugTag();
       
  1297         } catch (SocketException e) {
       
  1298             if (e.getMessage().equals(InterruptSysCallMsg))
       
  1299                 throw new InterruptedException(e.toString()) ;
       
  1300             else {
       
  1301                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  1302                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  1303                         "doBind", "cannot bind on port " + port);
       
  1304                 }
       
  1305                 throw new CommunicationException(e) ;
       
  1306             }
       
  1307         }
       
  1308     }
       
  1309 
       
  1310     /**
       
  1311      * Return the actual port to which the adaptor is bound.
       
  1312      * Can be different from the port given at construction time if
       
  1313      * that port number was 0.
       
  1314      * @return the actual port to which the adaptor is bound.
       
  1315      **/
       
  1316     @Override
       
  1317     public int getPort() {
       
  1318         synchronized (this) {
       
  1319             if (socket != null) return socket.getLocalPort();
       
  1320         }
       
  1321         return super.getPort();
       
  1322     }
       
  1323 
       
  1324     /**
       
  1325      * Closes the datagram socket.
       
  1326      */
       
  1327     @Override
       
  1328     protected void doUnbind()
       
  1329         throws CommunicationException, InterruptedException {
       
  1330         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1331             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1332                 "doUnbind","Finally close the socket");
       
  1333         }
       
  1334         synchronized (this) {
       
  1335             if (socket != null) {
       
  1336                 socket.close() ;
       
  1337                 socket = null ;
       
  1338                 // Important to inform finalize() that the socket is closed...
       
  1339             }
       
  1340         }
       
  1341         closeTrapSocketIfNeeded() ;
       
  1342         closeInformSocketIfNeeded() ;
       
  1343     }
       
  1344 
       
  1345     private void createSnmpRequestHandler(SnmpAdaptorServer server,
       
  1346                                           int id,
       
  1347                                           DatagramSocket s,
       
  1348                                           DatagramPacket p,
       
  1349                                           SnmpMibTree tree,
       
  1350                                           Vector<SnmpMibAgent> m,
       
  1351                                           InetAddressAcl a,
       
  1352                                           SnmpPduFactory factory,
       
  1353                                           SnmpUserDataFactory dataFactory,
       
  1354                                           MBeanServer f,
       
  1355                                           ObjectName n) {
       
  1356         final SnmpRequestHandler handler =
       
  1357             new SnmpRequestHandler(this, id, s, p, tree, m, a, factory,
       
  1358                                    dataFactory, f, n);
       
  1359         threadService.submitTask(handler);
       
  1360     }
       
  1361 
       
  1362     /**
       
  1363      * Reads a packet from the datagram socket and creates a request
       
  1364      * handler which decodes and processes the request.
       
  1365      */
       
  1366     @Override
       
  1367     protected void doReceive()
       
  1368         throws CommunicationException, InterruptedException {
       
  1369 
       
  1370         // Let's wait for something to be received.
       
  1371         //
       
  1372         try {
       
  1373             packet = new DatagramPacket(new byte[bufferSize], bufferSize) ;
       
  1374             socket.receive(packet);
       
  1375             int state = getState();
       
  1376 
       
  1377             if(state != ONLINE) {
       
  1378                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1379                     SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1380                         "doReceive","received a message but state not online, returning.");
       
  1381                 }
       
  1382                 return;
       
  1383             }
       
  1384 
       
  1385             createSnmpRequestHandler(this, servedClientCount, socket,
       
  1386                                      packet, root, mibs, ipacl, pduFactory,
       
  1387                                      userDataFactory, topMBS, objectName);
       
  1388         } catch (SocketException e) {
       
  1389             // Let's check if we have been interrupted by stop().
       
  1390             //
       
  1391             if (e.getMessage().equals(InterruptSysCallMsg))
       
  1392                 throw new InterruptedException(e.toString()) ;
       
  1393             else
       
  1394                 throw new CommunicationException(e) ;
       
  1395         } catch (InterruptedIOException e) {
       
  1396             throw new InterruptedException(e.toString()) ;
       
  1397         } catch (CommunicationException e) {
       
  1398             throw e ;
       
  1399         } catch (Exception e) {
       
  1400             throw new CommunicationException(e) ;
       
  1401         }
       
  1402         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1403             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1404                 "doReceive", "received a message");
       
  1405         }
       
  1406     }
       
  1407 
       
  1408     @Override
       
  1409     protected void doError(Exception e) throws CommunicationException {
       
  1410     }
       
  1411 
       
  1412     /**
       
  1413      * Not used in this context.
       
  1414      */
       
  1415     @Override
       
  1416     protected void doProcess()
       
  1417         throws CommunicationException, InterruptedException {
       
  1418     }
       
  1419 
       
  1420 
       
  1421     /**
       
  1422      * The number of times the communicator server will attempt
       
  1423      * to bind before giving up.
       
  1424      * We attempt only once...
       
  1425      * @return 1
       
  1426      **/
       
  1427     @Override
       
  1428     protected int getBindTries() {
       
  1429         return 1;
       
  1430     }
       
  1431 
       
  1432     /**
       
  1433      * Stops this SNMP protocol adaptor.
       
  1434      * Closes the datagram socket.
       
  1435      * <p>
       
  1436      * Has no effect if this SNMP protocol adaptor is <CODE>OFFLINE</CODE> or
       
  1437      * <CODE>STOPPING</CODE>.
       
  1438      */
       
  1439     @Override
       
  1440     public void stop(){
       
  1441 
       
  1442         final int port = getPort();
       
  1443         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1444             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1445                 "stop", "Stopping: using port " + port);
       
  1446         }
       
  1447         if ((state == ONLINE) || (state == STARTING)){
       
  1448             super.stop();
       
  1449             try {
       
  1450                 DatagramSocket sn = new DatagramSocket(0);
       
  1451                 try {
       
  1452                     byte[] ob = new byte[1];
       
  1453 
       
  1454                     DatagramPacket pk;
       
  1455                     if (address != null)
       
  1456                         pk = new DatagramPacket(ob , 1, address, port);
       
  1457                     else
       
  1458                         pk = new DatagramPacket(ob , 1,
       
  1459                                  java.net.InetAddress.getLocalHost(), port);
       
  1460 
       
  1461                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1462                         SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1463                             "stop", "Sending: using port " + port);
       
  1464                     }
       
  1465                     sn.send(pk);
       
  1466                 } finally {
       
  1467                     sn.close();
       
  1468                 }
       
  1469             } catch (Throwable e){
       
  1470                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  1471                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  1472                         "stop", "Got unexpected Throwable", e);
       
  1473                 }
       
  1474             }
       
  1475         }
       
  1476     }
       
  1477 
       
  1478     // SENDING SNMP TRAPS STUFF
       
  1479     //-------------------------
       
  1480 
       
  1481     /**
       
  1482      * Sends a trap using SNMP V1 trap format.
       
  1483      * <BR>The trap is sent to each destination defined in the ACL file
       
  1484      * (if available).
       
  1485      * If no ACL file or no destinations are available, the trap is sent
       
  1486      * to the local host.
       
  1487      *
       
  1488      * @param generic The generic number of the trap.
       
  1489      * @param specific The specific number of the trap.
       
  1490      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1491      *
       
  1492      * @exception IOException An I/O error occurred while sending the trap.
       
  1493      * @exception SnmpStatusException If the trap exceeds the limit defined
       
  1494      *            by <CODE>bufferSize</CODE>.
       
  1495      */
       
  1496     @Override
       
  1497     public void snmpV1Trap(int generic, int specific,
       
  1498                            SnmpVarBindList varBindList)
       
  1499         throws IOException, SnmpStatusException {
       
  1500 
       
  1501         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1502             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1503                 "snmpV1Trap", "generic=" + generic +
       
  1504                   ", specific=" + specific);
       
  1505         }
       
  1506 
       
  1507         // First, make an SNMP V1 trap pdu
       
  1508         //
       
  1509         SnmpPduTrap pdu = new SnmpPduTrap() ;
       
  1510         pdu.address = null ;
       
  1511         pdu.port = trapPort ;
       
  1512         pdu.type = pduV1TrapPdu ;
       
  1513         pdu.version = snmpVersionOne ;
       
  1514         pdu.community = null ;
       
  1515         pdu.enterprise = enterpriseOid ;
       
  1516         pdu.genericTrap = generic ;
       
  1517         pdu.specificTrap = specific ;
       
  1518         pdu.timeStamp = getSysUpTime();
       
  1519 
       
  1520         if (varBindList != null) {
       
  1521             pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
       
  1522             varBindList.copyInto(pdu.varBindList);
       
  1523         }
       
  1524         else
       
  1525             pdu.varBindList = null ;
       
  1526 
       
  1527         // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
       
  1528         try {
       
  1529             if (address != null)
       
  1530                 pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
       
  1531             else pdu.agentAddr =
       
  1532               handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
       
  1533         } catch (UnknownHostException e) {
       
  1534             byte[] zeroedAddr = new byte[4];
       
  1535             pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
       
  1536         }
       
  1537 
       
  1538         // Next, send the pdu to all destinations defined in ACL
       
  1539         //
       
  1540         sendTrapPdu(pdu) ;
       
  1541     }
       
  1542 
       
  1543     private SnmpIpAddress handleMultipleIpVersion(byte[] address) {
       
  1544         if(address.length == 4)
       
  1545           return new SnmpIpAddress(address);
       
  1546         else {
       
  1547             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  1548                 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  1549                     "handleMultipleIPVersion",
       
  1550                       "Not an IPv4 address, return null");
       
  1551             }
       
  1552             return null;
       
  1553         }
       
  1554     }
       
  1555 
       
  1556     /**
       
  1557      * Sends a trap using SNMP V1 trap format.
       
  1558      * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
       
  1559      * destination using the specified community string (and the ACL file
       
  1560      * is not used).
       
  1561      *
       
  1562      * @param addr The <CODE>InetAddress</CODE> destination of the trap.
       
  1563      * @param cs The community string to be used for the trap.
       
  1564      * @param generic The generic number of the trap.
       
  1565      * @param specific The specific number of the trap.
       
  1566      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1567      *
       
  1568      * @exception IOException An I/O error occurred while sending the trap.
       
  1569      * @exception SnmpStatusException If the trap exceeds the limit defined
       
  1570      *            by <CODE>bufferSize</CODE>.
       
  1571      */
       
  1572     @Override
       
  1573     public void snmpV1Trap(InetAddress addr, String cs, int generic,
       
  1574                            int specific, SnmpVarBindList varBindList)
       
  1575         throws IOException, SnmpStatusException {
       
  1576 
       
  1577         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1578             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1579                 "snmpV1Trap", "generic=" + generic + ", specific=" +
       
  1580                   specific);
       
  1581         }
       
  1582 
       
  1583         // First, make an SNMP V1 trap pdu
       
  1584         //
       
  1585         SnmpPduTrap pdu = new SnmpPduTrap() ;
       
  1586         pdu.address = null ;
       
  1587         pdu.port = trapPort ;
       
  1588         pdu.type = pduV1TrapPdu ;
       
  1589         pdu.version = snmpVersionOne ;
       
  1590 
       
  1591         if(cs != null)
       
  1592             pdu.community = cs.getBytes();
       
  1593         else
       
  1594             pdu.community = null ;
       
  1595 
       
  1596         pdu.enterprise = enterpriseOid ;
       
  1597         pdu.genericTrap = generic ;
       
  1598         pdu.specificTrap = specific ;
       
  1599         pdu.timeStamp = getSysUpTime();
       
  1600 
       
  1601         if (varBindList != null) {
       
  1602             pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
       
  1603             varBindList.copyInto(pdu.varBindList);
       
  1604         }
       
  1605         else
       
  1606             pdu.varBindList = null ;
       
  1607 
       
  1608         // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
       
  1609         try {
       
  1610             if (address != null)
       
  1611                 pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
       
  1612             else pdu.agentAddr =
       
  1613               handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
       
  1614         } catch (UnknownHostException e) {
       
  1615             byte[] zeroedAddr = new byte[4];
       
  1616             pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
       
  1617         }
       
  1618 
       
  1619         // Next, send the pdu to the specified destination
       
  1620         //
       
  1621         if(addr != null)
       
  1622             sendTrapPdu(addr, pdu) ;
       
  1623         else
       
  1624             sendTrapPdu(pdu);
       
  1625     }
       
  1626 
       
  1627     /**
       
  1628      * Sends a trap using SNMP V1 trap format.
       
  1629      * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
       
  1630      * destination using the specified parameters (and the ACL file is not
       
  1631      * used).
       
  1632      * Note that if the specified <CODE>InetAddress</CODE> destination is null,
       
  1633      * then the ACL file mechanism is used.
       
  1634      *
       
  1635      * @param addr The <CODE>InetAddress</CODE> destination of the trap.
       
  1636      * @param agentAddr The agent address to be used for the trap.
       
  1637      * @param cs The community string to be used for the trap.
       
  1638      * @param enterpOid The enterprise OID to be used for the trap.
       
  1639      * @param generic The generic number of the trap.
       
  1640      * @param specific The specific number of the trap.
       
  1641      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1642      * @param time The time stamp (overwrite the current time).
       
  1643      *
       
  1644      * @exception IOException An I/O error occurred while sending the trap.
       
  1645      * @exception SnmpStatusException If the trap exceeds the limit defined
       
  1646      *            by <CODE>bufferSize</CODE>.
       
  1647      *
       
  1648      * @since 1.5
       
  1649      */
       
  1650     public void snmpV1Trap(InetAddress addr,
       
  1651                            SnmpIpAddress agentAddr,
       
  1652                            String cs,
       
  1653                            SnmpOid enterpOid,
       
  1654                            int generic,
       
  1655                            int specific,
       
  1656                            SnmpVarBindList varBindList,
       
  1657                            SnmpTimeticks time)
       
  1658         throws IOException, SnmpStatusException {
       
  1659         snmpV1Trap(addr,
       
  1660                    trapPort,
       
  1661                    agentAddr,
       
  1662                    cs,
       
  1663                    enterpOid,
       
  1664                    generic,
       
  1665                    specific,
       
  1666                    varBindList,
       
  1667                    time);
       
  1668     }
       
  1669 
       
  1670     /**
       
  1671      * Sends a trap using SNMP V1 trap format.
       
  1672      * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
       
  1673      * The community string used is the one located in the
       
  1674      * <CODE>SnmpPeer</CODE> parameters
       
  1675      * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
       
  1676      *
       
  1677      * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
       
  1678      * @param agentAddr The agent address to be used for the trap.
       
  1679      * @param enterpOid The enterprise OID to be used for the trap.
       
  1680      * @param generic The generic number of the trap.
       
  1681      * @param specific The specific number of the trap.
       
  1682      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1683      * @param time The time stamp (overwrite the current time).
       
  1684      *
       
  1685      * @exception IOException An I/O error occurred while sending the trap.
       
  1686      * @exception SnmpStatusException If the trap exceeds the limit
       
  1687      * defined by <CODE>bufferSize</CODE>.
       
  1688      *
       
  1689      * @since 1.5
       
  1690      */
       
  1691     @Override
       
  1692     public void snmpV1Trap(SnmpPeer peer,
       
  1693                            SnmpIpAddress agentAddr,
       
  1694                            SnmpOid enterpOid,
       
  1695                            int generic,
       
  1696                            int specific,
       
  1697                            SnmpVarBindList varBindList,
       
  1698                            SnmpTimeticks time)
       
  1699         throws IOException, SnmpStatusException {
       
  1700 
       
  1701         SnmpParameters p = (SnmpParameters) peer.getParams();
       
  1702         snmpV1Trap(peer.getDestAddr(),
       
  1703                    peer.getDestPort(),
       
  1704                    agentAddr,
       
  1705                    p.getRdCommunity(),
       
  1706                    enterpOid,
       
  1707                    generic,
       
  1708                    specific,
       
  1709                    varBindList,
       
  1710                    time);
       
  1711     }
       
  1712 
       
  1713     private void snmpV1Trap(InetAddress addr,
       
  1714                             int port,
       
  1715                             SnmpIpAddress agentAddr,
       
  1716                             String cs,
       
  1717                             SnmpOid enterpOid,
       
  1718                             int generic,
       
  1719                             int specific,
       
  1720                             SnmpVarBindList varBindList,
       
  1721                             SnmpTimeticks time)
       
  1722         throws IOException, SnmpStatusException {
       
  1723 
       
  1724         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1725             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1726                 "snmpV1Trap", "generic=" + generic + ", specific=" +
       
  1727                   specific);
       
  1728         }
       
  1729 
       
  1730         // First, make an SNMP V1 trap pdu
       
  1731         //
       
  1732         SnmpPduTrap pdu = new SnmpPduTrap() ;
       
  1733         pdu.address = null ;
       
  1734         pdu.port = port ;
       
  1735         pdu.type = pduV1TrapPdu ;
       
  1736         pdu.version = snmpVersionOne ;
       
  1737 
       
  1738         //Diff start
       
  1739         if(cs != null)
       
  1740             pdu.community = cs.getBytes();
       
  1741         else
       
  1742             pdu.community = null ;
       
  1743         //Diff end
       
  1744 
       
  1745         // Diff start
       
  1746         if(enterpOid != null)
       
  1747             pdu.enterprise = enterpOid;
       
  1748         else
       
  1749             pdu.enterprise = enterpriseOid ;
       
  1750         //Diff end
       
  1751         pdu.genericTrap = generic ;
       
  1752         pdu.specificTrap = specific ;
       
  1753         //Diff start
       
  1754         if(time != null)
       
  1755             pdu.timeStamp = time.longValue();
       
  1756         else
       
  1757             pdu.timeStamp = getSysUpTime();
       
  1758         //Diff end
       
  1759 
       
  1760         if (varBindList != null) {
       
  1761             pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
       
  1762             varBindList.copyInto(pdu.varBindList);
       
  1763         }
       
  1764         else
       
  1765             pdu.varBindList = null ;
       
  1766 
       
  1767         if (agentAddr == null) {
       
  1768             // If the local host cannot be determined,
       
  1769             // we put 0.0.0.0 in agentAddr
       
  1770             try {
       
  1771                 final InetAddress inetAddr =
       
  1772                     (address!=null)?address:InetAddress.getLocalHost();
       
  1773                 agentAddr = handleMultipleIpVersion(inetAddr.getAddress());
       
  1774             }  catch (UnknownHostException e) {
       
  1775                 byte[] zeroedAddr = new byte[4];
       
  1776                 agentAddr = handleMultipleIpVersion(zeroedAddr);
       
  1777             }
       
  1778         }
       
  1779 
       
  1780         pdu.agentAddr = agentAddr;
       
  1781 
       
  1782         // Next, send the pdu to the specified destination
       
  1783         //
       
  1784         // Diff start
       
  1785         if(addr != null)
       
  1786             sendTrapPdu(addr, pdu) ;
       
  1787         else
       
  1788             sendTrapPdu(pdu);
       
  1789 
       
  1790         //End diff
       
  1791     }
       
  1792 
       
  1793     /**
       
  1794      * Sends a trap using SNMP V2 trap format.
       
  1795      * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
       
  1796      * <BR>The community string used is the one located in the
       
  1797      * <CODE>SnmpPeer</CODE> parameters
       
  1798      * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
       
  1799      * <BR>The variable list included in the outgoing trap is composed of
       
  1800      * the following items:
       
  1801      * <UL>
       
  1802      * <LI><CODE>sysUpTime.0</CODE> with the value specified by
       
  1803      *     <CODE>time</CODE></LI>
       
  1804      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  1805      *     <CODE>trapOid</CODE></LI>
       
  1806      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  1807      *     <CODE>varBindList</CODE></LI>
       
  1808      * </UL>
       
  1809      *
       
  1810      * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
       
  1811      * @param trapOid The OID identifying the trap.
       
  1812      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1813      * @param time The time stamp (overwrite the current time).
       
  1814      *
       
  1815      * @exception IOException An I/O error occurred while sending the trap.
       
  1816      * @exception SnmpStatusException If the trap exceeds the limit
       
  1817      * defined by <CODE>bufferSize</CODE>.
       
  1818      *
       
  1819      * @since 1.5
       
  1820      */
       
  1821     @Override
       
  1822     public void snmpV2Trap(SnmpPeer peer,
       
  1823                            SnmpOid trapOid,
       
  1824                            SnmpVarBindList varBindList,
       
  1825                            SnmpTimeticks time)
       
  1826         throws IOException, SnmpStatusException {
       
  1827 
       
  1828         SnmpParameters p = (SnmpParameters) peer.getParams();
       
  1829         snmpV2Trap(peer.getDestAddr(),
       
  1830                    peer.getDestPort(),
       
  1831                    p.getRdCommunity(),
       
  1832                    trapOid,
       
  1833                    varBindList,
       
  1834                    time);
       
  1835     }
       
  1836 
       
  1837     /**
       
  1838      * Sends a trap using SNMP V2 trap format.
       
  1839      * <BR>The trap is sent to each destination defined in the ACL file
       
  1840      * (if available). If no ACL file or no destinations are available,
       
  1841      * the trap is sent to the local host.
       
  1842      * <BR>The variable list included in the outgoing trap is composed of
       
  1843      * the following items:
       
  1844      * <UL>
       
  1845      * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
       
  1846      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  1847      *     <CODE>trapOid</CODE></LI>
       
  1848      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  1849      *     <CODE>varBindList</CODE></LI>
       
  1850      * </UL>
       
  1851      *
       
  1852      * @param trapOid The OID identifying the trap.
       
  1853      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1854      *
       
  1855      * @exception IOException An I/O error occurred while sending the trap.
       
  1856      * @exception SnmpStatusException If the trap exceeds the limit defined
       
  1857      *            by <CODE>bufferSize</CODE>.
       
  1858      */
       
  1859     @Override
       
  1860     public void snmpV2Trap(SnmpOid trapOid, SnmpVarBindList varBindList)
       
  1861         throws IOException, SnmpStatusException {
       
  1862 
       
  1863         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1864             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1865                 "snmpV2Trap", "trapOid=" + trapOid);
       
  1866         }
       
  1867 
       
  1868         // First, make an SNMP V2 trap pdu
       
  1869         // We clone varBindList and insert sysUpTime and snmpTrapOid
       
  1870         //
       
  1871         SnmpPduRequest pdu = new SnmpPduRequest() ;
       
  1872         pdu.address = null ;
       
  1873         pdu.port = trapPort ;
       
  1874         pdu.type = pduV2TrapPdu ;
       
  1875         pdu.version = snmpVersionTwo ;
       
  1876         pdu.community = null ;
       
  1877 
       
  1878         SnmpVarBindList fullVbl ;
       
  1879         if (varBindList != null)
       
  1880             fullVbl = varBindList.clone() ;
       
  1881         else
       
  1882             fullVbl = new SnmpVarBindList(2) ;
       
  1883         SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
       
  1884         fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
       
  1885         fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
       
  1886                                 0);
       
  1887         pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
       
  1888         fullVbl.copyInto(pdu.varBindList) ;
       
  1889 
       
  1890         // Next, send the pdu to all destinations defined in ACL
       
  1891         //
       
  1892         sendTrapPdu(pdu) ;
       
  1893     }
       
  1894 
       
  1895     /**
       
  1896      * Sends a trap using SNMP V2 trap format.
       
  1897      * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
       
  1898      * destination using the specified community string (and the ACL file
       
  1899      * is not used).
       
  1900      * <BR>The variable list included in the outgoing trap is composed of
       
  1901      * the following items:
       
  1902      * <UL>
       
  1903      * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
       
  1904      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  1905      *     <CODE>trapOid</CODE></LI>
       
  1906      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  1907      *     <CODE>varBindList</CODE></LI>
       
  1908      * </UL>
       
  1909      *
       
  1910      * @param addr The <CODE>InetAddress</CODE> destination of the trap.
       
  1911      * @param cs The community string to be used for the trap.
       
  1912      * @param trapOid The OID identifying the trap.
       
  1913      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1914      *
       
  1915      * @exception IOException An I/O error occurred while sending the trap.
       
  1916      * @exception SnmpStatusException If the trap exceeds the limit
       
  1917      *            defined by <CODE>bufferSize</CODE>.
       
  1918      */
       
  1919     @Override
       
  1920     public void snmpV2Trap(InetAddress addr, String cs, SnmpOid trapOid,
       
  1921                            SnmpVarBindList varBindList)
       
  1922         throws IOException, SnmpStatusException {
       
  1923 
       
  1924         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  1925             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  1926                 "snmpV2Trap", "trapOid=" + trapOid);
       
  1927         }
       
  1928 
       
  1929         // First, make an SNMP V2 trap pdu
       
  1930         // We clone varBindList and insert sysUpTime and snmpTrapOid
       
  1931         //
       
  1932         SnmpPduRequest pdu = new SnmpPduRequest() ;
       
  1933         pdu.address = null ;
       
  1934         pdu.port = trapPort ;
       
  1935         pdu.type = pduV2TrapPdu ;
       
  1936         pdu.version = snmpVersionTwo ;
       
  1937 
       
  1938         if(cs != null)
       
  1939             pdu.community = cs.getBytes();
       
  1940         else
       
  1941             pdu.community = null;
       
  1942 
       
  1943         SnmpVarBindList fullVbl ;
       
  1944         if (varBindList != null)
       
  1945             fullVbl = varBindList.clone() ;
       
  1946         else
       
  1947             fullVbl = new SnmpVarBindList(2) ;
       
  1948         SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
       
  1949         fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
       
  1950         fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
       
  1951                                 0);
       
  1952         pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
       
  1953         fullVbl.copyInto(pdu.varBindList) ;
       
  1954 
       
  1955         // Next, send the pdu to the specified destination
       
  1956         //
       
  1957         if(addr != null)
       
  1958             sendTrapPdu(addr, pdu);
       
  1959         else
       
  1960             sendTrapPdu(pdu);
       
  1961     }
       
  1962 
       
  1963     /**
       
  1964      * Sends a trap using SNMP V2 trap format.
       
  1965      * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
       
  1966      * destination using the specified parameters (and the ACL file is not
       
  1967      * used).
       
  1968      * Note that if the specified <CODE>InetAddress</CODE> destination is null,
       
  1969      * then the ACL file mechanism is used.
       
  1970      * <BR>The variable list included in the outgoing trap is composed of the
       
  1971      * following items:
       
  1972      * <UL>
       
  1973      * <LI><CODE>sysUpTime.0</CODE> with the value specified by
       
  1974      *     <CODE>time</CODE></LI>
       
  1975      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  1976      *     <CODE>trapOid</CODE></LI>
       
  1977      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  1978      *     <CODE>varBindList</CODE></LI>
       
  1979      * </UL>
       
  1980      *
       
  1981      * @param addr The <CODE>InetAddress</CODE> destination of the trap.
       
  1982      * @param cs The community string to be used for the trap.
       
  1983      * @param trapOid The OID identifying the trap.
       
  1984      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  1985      * @param time The time stamp (overwrite the current time).
       
  1986      *
       
  1987      * @exception IOException An I/O error occurred while sending the trap.
       
  1988      * @exception SnmpStatusException If the trap exceeds the limit
       
  1989      * defined by <CODE>bufferSize</CODE>.
       
  1990      *
       
  1991      * @since 1.5
       
  1992      */
       
  1993     public void snmpV2Trap(InetAddress addr,
       
  1994                            String cs,
       
  1995                            SnmpOid trapOid,
       
  1996                            SnmpVarBindList varBindList,
       
  1997                            SnmpTimeticks time)
       
  1998         throws IOException, SnmpStatusException {
       
  1999 
       
  2000         snmpV2Trap(addr,
       
  2001                    trapPort,
       
  2002                    cs,
       
  2003                    trapOid,
       
  2004                    varBindList,
       
  2005                    time);
       
  2006     }
       
  2007 
       
  2008     private void snmpV2Trap(InetAddress addr,
       
  2009                             int port,
       
  2010                             String cs,
       
  2011                             SnmpOid trapOid,
       
  2012                             SnmpVarBindList varBindList,
       
  2013                             SnmpTimeticks time)
       
  2014         throws IOException, SnmpStatusException {
       
  2015 
       
  2016         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2017             final StringBuilder strb = new StringBuilder()
       
  2018                 .append("trapOid=").append(trapOid)
       
  2019                 .append("\ncommunity=").append(cs)
       
  2020                 .append("\naddr=").append(addr)
       
  2021                 .append("\nvarBindList=").append(varBindList)
       
  2022                 .append("\ntime=").append(time)
       
  2023                 .append("\ntrapPort=").append(port);
       
  2024             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2025                 "snmpV2Trap", strb.toString());
       
  2026         }
       
  2027 
       
  2028         // First, make an SNMP V2 trap pdu
       
  2029         // We clone varBindList and insert sysUpTime and snmpTrapOid
       
  2030         //
       
  2031         SnmpPduRequest pdu = new SnmpPduRequest() ;
       
  2032         pdu.address = null ;
       
  2033         pdu.port = port ;
       
  2034         pdu.type = pduV2TrapPdu ;
       
  2035         pdu.version = snmpVersionTwo ;
       
  2036 
       
  2037         if(cs != null)
       
  2038             pdu.community = cs.getBytes();
       
  2039         else
       
  2040             pdu.community = null;
       
  2041 
       
  2042         SnmpVarBindList fullVbl ;
       
  2043         if (varBindList != null)
       
  2044             fullVbl = varBindList.clone() ;
       
  2045         else
       
  2046             fullVbl = new SnmpVarBindList(2) ;
       
  2047 
       
  2048         // Only difference with other
       
  2049         SnmpTimeticks sysUpTimeValue;
       
  2050         if(time != null)
       
  2051             sysUpTimeValue = time;
       
  2052         else
       
  2053             sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
       
  2054         //End of diff
       
  2055 
       
  2056         fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
       
  2057         fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
       
  2058                                 0);
       
  2059         pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
       
  2060         fullVbl.copyInto(pdu.varBindList) ;
       
  2061 
       
  2062         // Next, send the pdu to the specified destination
       
  2063         //
       
  2064         // Diff start
       
  2065         if(addr != null)
       
  2066             sendTrapPdu(addr, pdu) ;
       
  2067         else
       
  2068             sendTrapPdu(pdu);
       
  2069         //End diff
       
  2070     }
       
  2071 
       
  2072     /**
       
  2073      * Send the specified trap PDU to the passed <CODE>InetAddress</CODE>.
       
  2074      * @param address The destination address.
       
  2075      * @param pdu The pdu to send.
       
  2076      * @exception IOException An I/O error occurred while sending the trap.
       
  2077      * @exception SnmpStatusException If the trap exceeds the limit
       
  2078      * defined by <CODE>bufferSize</CODE>.
       
  2079      *
       
  2080      * @since 1.5
       
  2081      */
       
  2082     @Override
       
  2083     public void snmpPduTrap(InetAddress address, SnmpPduPacket pdu)
       
  2084             throws IOException, SnmpStatusException {
       
  2085 
       
  2086         if(address != null)
       
  2087             sendTrapPdu(address, pdu);
       
  2088         else
       
  2089             sendTrapPdu(pdu);
       
  2090     }
       
  2091 
       
  2092     /**
       
  2093      * Send the specified trap PDU to the passed <CODE>SnmpPeer</CODE>.
       
  2094      * @param peer The destination peer. The Read community string is used of
       
  2095      * <CODE>SnmpParameters</CODE> is used as the trap community string.
       
  2096      * @param pdu The pdu to send.
       
  2097      * @exception IOException An I/O error occurred while sending the trap.
       
  2098      * @exception SnmpStatusException If the trap exceeds the limit defined
       
  2099      * by <CODE>bufferSize</CODE>.
       
  2100      * @since 1.5
       
  2101      */
       
  2102     @Override
       
  2103     public void snmpPduTrap(SnmpPeer peer,
       
  2104                             SnmpPduPacket pdu)
       
  2105         throws IOException, SnmpStatusException {
       
  2106         if(peer != null) {
       
  2107             pdu.port = peer.getDestPort();
       
  2108             sendTrapPdu(peer.getDestAddr(), pdu);
       
  2109         }
       
  2110         else {
       
  2111             pdu.port = getTrapPort().intValue();
       
  2112             sendTrapPdu(pdu);
       
  2113         }
       
  2114     }
       
  2115 
       
  2116     /**
       
  2117      * Send the specified trap PDU to every destinations from the ACL file.
       
  2118      */
       
  2119     private void sendTrapPdu(SnmpPduPacket pdu)
       
  2120      throws SnmpStatusException, IOException {
       
  2121 
       
  2122         // Make an SNMP message from the pdu
       
  2123         //
       
  2124         SnmpMessage msg = null ;
       
  2125         try {
       
  2126             msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
       
  2127             if (msg == null) {
       
  2128                 throw new SnmpStatusException(
       
  2129                           SnmpDefinitions.snmpRspAuthorizationError) ;
       
  2130             }
       
  2131         }
       
  2132         catch (SnmpTooBigException x) {
       
  2133             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2134                 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2135                     "sendTrapPdu", "Trap pdu is too big. " +
       
  2136                      "Trap hasn't been sent to anyone" );
       
  2137             }
       
  2138             throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
       
  2139             // FIXME: is the right exception to throw ?
       
  2140             // We could simply forward SnmpTooBigException ?
       
  2141         }
       
  2142 
       
  2143         // Now send the SNMP message to each destination
       
  2144         //
       
  2145         int sendingCount = 0 ;
       
  2146         openTrapSocketIfNeeded() ;
       
  2147         if (ipacl != null) {
       
  2148             Enumeration<InetAddress> ed = ipacl.getTrapDestinations() ;
       
  2149             while (ed.hasMoreElements()) {
       
  2150                 msg.address = ed.nextElement() ;
       
  2151                 Enumeration<String> ec = ipacl.getTrapCommunities(msg.address) ;
       
  2152                 while (ec.hasMoreElements()) {
       
  2153                     msg.community = ec.nextElement().getBytes() ;
       
  2154                     try {
       
  2155                         sendTrapMessage(msg) ;
       
  2156                         sendingCount++ ;
       
  2157                     }
       
  2158                     catch (SnmpTooBigException x) {
       
  2159                         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2160                             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2161                                 "sendTrapPdu", "Trap pdu is too big. " +
       
  2162                                  "Trap hasn't been sent to "+msg.address);
       
  2163                         }
       
  2164                     }
       
  2165                 }
       
  2166             }
       
  2167         }
       
  2168 
       
  2169         // If there is no destination defined or if everything has failed
       
  2170         // we tried to send the trap to the local host (as suggested by
       
  2171         // mister Olivier Reisacher).
       
  2172         //
       
  2173         if (sendingCount == 0) {
       
  2174             try {
       
  2175                 msg.address = InetAddress.getLocalHost() ;
       
  2176                 sendTrapMessage(msg) ;
       
  2177             } catch (SnmpTooBigException x) {
       
  2178                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2179                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2180                         "sendTrapPdu", "Trap pdu is too big. " +
       
  2181                          "Trap hasn't been sent.");
       
  2182                 }
       
  2183             } catch (UnknownHostException e) {
       
  2184                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2185                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2186                         "sendTrapPdu", "Trap pdu is too big. " +
       
  2187                          "Trap hasn't been sent.");
       
  2188                 }
       
  2189             }
       
  2190         }
       
  2191 
       
  2192         closeTrapSocketIfNeeded() ;
       
  2193     }
       
  2194 
       
  2195     /**
       
  2196      * Send the specified trap PDU to the specified destination.
       
  2197      */
       
  2198     private void sendTrapPdu(InetAddress addr, SnmpPduPacket pdu)
       
  2199         throws SnmpStatusException, IOException {
       
  2200 
       
  2201         // Make an SNMP message from the pdu
       
  2202         //
       
  2203         SnmpMessage msg = null ;
       
  2204         try {
       
  2205             msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
       
  2206             if (msg == null) {
       
  2207                 throw new SnmpStatusException(
       
  2208                           SnmpDefinitions.snmpRspAuthorizationError) ;
       
  2209             }
       
  2210         } catch (SnmpTooBigException x) {
       
  2211             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2212                 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2213                     "sendTrapPdu", "Trap pdu is too big. " +
       
  2214                      "Trap hasn't been sent to the specified host.");
       
  2215             }
       
  2216             throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
       
  2217             // FIXME: is the right exception to throw ?
       
  2218             // We could simply forward SnmpTooBigException ?
       
  2219         }
       
  2220 
       
  2221         // Now send the SNMP message to specified destination
       
  2222         //
       
  2223         openTrapSocketIfNeeded() ;
       
  2224         if (addr != null) {
       
  2225             msg.address = addr;
       
  2226             try {
       
  2227                 sendTrapMessage(msg) ;
       
  2228             } catch (SnmpTooBigException x) {
       
  2229                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
  2230                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
       
  2231                         "sendTrapPdu", "Trap pdu is too big. " +
       
  2232                          "Trap hasn't been sent to " +  msg.address);
       
  2233                 }
       
  2234             }
       
  2235         }
       
  2236 
       
  2237         closeTrapSocketIfNeeded() ;
       
  2238     }
       
  2239 
       
  2240     /**
       
  2241      * Send the specified message on trapSocket.
       
  2242      */
       
  2243     private void sendTrapMessage(SnmpMessage msg)
       
  2244         throws IOException, SnmpTooBigException {
       
  2245 
       
  2246         byte[] buffer = new byte[bufferSize] ;
       
  2247         DatagramPacket packet = new DatagramPacket(buffer, buffer.length) ;
       
  2248         int encodingLength = msg.encodeMessage(buffer) ;
       
  2249         packet.setLength(encodingLength) ;
       
  2250         packet.setAddress(msg.address) ;
       
  2251         packet.setPort(msg.port) ;
       
  2252         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2253             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2254                 "sendTrapMessage", "sending trap to " + msg.address + ":" +
       
  2255                   msg.port);
       
  2256         }
       
  2257         trapSocket.send(packet) ;
       
  2258         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2259             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2260                 "sendTrapMessage", "sent to " + msg.address + ":" +
       
  2261                   msg.port);
       
  2262         }
       
  2263         snmpOutTraps++;
       
  2264         snmpOutPkts++;
       
  2265     }
       
  2266 
       
  2267     /**
       
  2268      * Open trapSocket if it's not already done.
       
  2269      */
       
  2270     synchronized void openTrapSocketIfNeeded() throws SocketException {
       
  2271         if (trapSocket == null) {
       
  2272             trapSocket = new DatagramSocket(0, address) ;
       
  2273             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2274                 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2275                     "openTrapSocketIfNeeded", "using port " +
       
  2276                       trapSocket.getLocalPort() + " to send traps");
       
  2277             }
       
  2278         }
       
  2279     }
       
  2280 
       
  2281     /**
       
  2282      * Close trapSocket if the SNMP protocol adaptor is not ONLINE.
       
  2283      */
       
  2284     synchronized void closeTrapSocketIfNeeded() {
       
  2285         if ((trapSocket != null) && (state != ONLINE)) {
       
  2286             trapSocket.close() ;
       
  2287             trapSocket = null ;
       
  2288         }
       
  2289     }
       
  2290 
       
  2291     // SENDING SNMP INFORMS STUFF
       
  2292     //---------------------------
       
  2293 
       
  2294     /**
       
  2295      * Sends an inform using SNMP V2 inform request format.
       
  2296      * <BR>The inform request is sent to each destination defined in the ACL
       
  2297      * file (if available).
       
  2298      * If no ACL file or no destinations are available, the inform request is
       
  2299      * sent to the local host.
       
  2300      * <BR>The variable list included in the outgoing inform is composed of
       
  2301      * the following items:
       
  2302      * <UL>
       
  2303      * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
       
  2304      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  2305      *     <CODE>trapOid</CODE></LI>
       
  2306      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  2307      *     <CODE>varBindList</CODE></LI>
       
  2308      * </UL>
       
  2309      * To send an inform request, the SNMP adaptor server must be active.
       
  2310      *
       
  2311      * @param cb The callback that is invoked when a request is complete.
       
  2312      * @param trapOid The OID identifying the trap.
       
  2313      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  2314      *
       
  2315      * @return A vector of {@link com.sun.jmx.snmp.daemon.SnmpInformRequest}
       
  2316      *         objects.
       
  2317      *         <P>If there is no destination host for this inform request,
       
  2318      *         the returned vector will be empty.
       
  2319      *
       
  2320      * @exception IllegalStateException  This method has been invoked while
       
  2321      *            the SNMP adaptor server was not active.
       
  2322      * @exception IOException An I/O error occurred while sending the
       
  2323      *            inform request.
       
  2324      * @exception SnmpStatusException If the inform request exceeds the
       
  2325      *            limit defined by <CODE>bufferSize</CODE>.
       
  2326      */
       
  2327     @Override
       
  2328     public Vector<SnmpInformRequest> snmpInformRequest(SnmpInformHandler cb,
       
  2329                                                        SnmpOid trapOid,
       
  2330                                                        SnmpVarBindList varBindList)
       
  2331         throws IllegalStateException, IOException, SnmpStatusException {
       
  2332 
       
  2333         if (!isActive()) {
       
  2334             throw new IllegalStateException(
       
  2335                "Start SNMP adaptor server before carrying out this operation");
       
  2336         }
       
  2337         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2338             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2339                 "snmpInformRequest", "trapOid=" + trapOid);
       
  2340         }
       
  2341 
       
  2342         // First, make an SNMP inform pdu:
       
  2343         // We clone varBindList and insert sysUpTime and snmpTrapOid variables.
       
  2344         //
       
  2345         SnmpVarBindList fullVbl ;
       
  2346         if (varBindList != null)
       
  2347             fullVbl = varBindList.clone() ;
       
  2348         else
       
  2349             fullVbl = new SnmpVarBindList(2) ;
       
  2350         SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
       
  2351         fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
       
  2352         fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
       
  2353                                 0);
       
  2354 
       
  2355         // Next, send the pdu to the specified destination
       
  2356         //
       
  2357         openInformSocketIfNeeded() ;
       
  2358 
       
  2359         // Now send the SNMP message to each destination
       
  2360         //
       
  2361         Vector<SnmpInformRequest> informReqList = new Vector<>();
       
  2362         InetAddress addr;
       
  2363         String cs;
       
  2364         if (ipacl != null) {
       
  2365             Enumeration<InetAddress> ed = ipacl.getInformDestinations() ;
       
  2366             while (ed.hasMoreElements()) {
       
  2367                 addr = ed.nextElement() ;
       
  2368                 Enumeration<String> ec = ipacl.getInformCommunities(addr) ;
       
  2369                 while (ec.hasMoreElements()) {
       
  2370                     cs = ec.nextElement() ;
       
  2371                     informReqList.addElement(
       
  2372                        informSession.makeAsyncRequest(addr, cs, cb,
       
  2373                                               fullVbl,getInformPort())) ;
       
  2374                 }
       
  2375             }
       
  2376         }
       
  2377 
       
  2378         return informReqList ;
       
  2379     }
       
  2380 
       
  2381     /**
       
  2382      * Sends an inform using SNMP V2 inform request format.
       
  2383      * <BR>The inform is sent to the specified <CODE>InetAddress</CODE>
       
  2384      * destination
       
  2385      * using the specified community string.
       
  2386      * <BR>The variable list included in the outgoing inform is composed
       
  2387      *     of the following items:
       
  2388      * <UL>
       
  2389      * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
       
  2390      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  2391      *      <CODE>trapOid</CODE></LI>
       
  2392      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  2393      *     <CODE>varBindList</CODE></LI>
       
  2394      * </UL>
       
  2395      * To send an inform request, the SNMP adaptor server must be active.
       
  2396      *
       
  2397      * @param addr The <CODE>InetAddress</CODE> destination for this inform
       
  2398      *             request.
       
  2399      * @param cs The community string to be used for the inform request.
       
  2400      * @param cb The callback that is invoked when a request is complete.
       
  2401      * @param trapOid The OID identifying the trap.
       
  2402      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  2403      *
       
  2404      * @return The inform request object.
       
  2405      *
       
  2406      * @exception IllegalStateException  This method has been invoked
       
  2407      *            while the SNMP adaptor server was not active.
       
  2408      * @exception IOException An I/O error occurred while sending the
       
  2409      *            inform request.
       
  2410      * @exception SnmpStatusException If the inform request exceeds the
       
  2411      *            limit defined by <CODE>bufferSize</CODE>.
       
  2412      */
       
  2413     @Override
       
  2414     public SnmpInformRequest snmpInformRequest(InetAddress addr,
       
  2415                                                String cs,
       
  2416                                                SnmpInformHandler cb,
       
  2417                                                SnmpOid trapOid,
       
  2418                                                SnmpVarBindList varBindList)
       
  2419         throws IllegalStateException, IOException, SnmpStatusException {
       
  2420 
       
  2421         return snmpInformRequest(addr,
       
  2422                                  getInformPort(),
       
  2423                                  cs,
       
  2424                                  cb,
       
  2425                                  trapOid,
       
  2426                                  varBindList);
       
  2427     }
       
  2428 
       
  2429     /**
       
  2430      * Sends an inform using SNMP V2 inform request format.
       
  2431      * <BR>The inform is sent to the specified <CODE>SnmpPeer</CODE>
       
  2432      *     destination.
       
  2433      * <BR>The community string used is the one located in the
       
  2434      *     <CODE>SnmpPeer</CODE> parameters
       
  2435      *     (<CODE>SnmpParameters.getInformCommunity() </CODE>).
       
  2436      * <BR>The variable list included in the outgoing inform is composed
       
  2437      *     of the following items:
       
  2438      * <UL>
       
  2439      * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
       
  2440      * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
       
  2441      *     <CODE>trapOid</CODE></LI>
       
  2442      * <LI><CODE>all the (oid,values)</CODE> from the specified
       
  2443      *     <CODE>varBindList</CODE></LI>
       
  2444      * </UL>
       
  2445      * To send an inform request, the SNMP adaptor server must be active.
       
  2446      *
       
  2447      * @param peer The <CODE>SnmpPeer</CODE> destination for this inform
       
  2448      *             request.
       
  2449      * @param cb The callback that is invoked when a request is complete.
       
  2450      * @param trapOid The OID identifying the trap.
       
  2451      * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
       
  2452      *
       
  2453      * @return The inform request object.
       
  2454      *
       
  2455      * @exception IllegalStateException  This method has been invoked while
       
  2456      *            the SNMP adaptor server was not active.
       
  2457      * @exception IOException An I/O error occurred while sending the
       
  2458      *            inform request.
       
  2459      * @exception SnmpStatusException If the inform request exceeds the
       
  2460      *            limit defined by <CODE>bufferSize</CODE>.
       
  2461      *
       
  2462      * @since 1.5
       
  2463      */
       
  2464     @Override
       
  2465     public SnmpInformRequest snmpInformRequest(SnmpPeer peer,
       
  2466                                                SnmpInformHandler cb,
       
  2467                                                SnmpOid trapOid,
       
  2468                                                SnmpVarBindList varBindList)
       
  2469         throws IllegalStateException, IOException, SnmpStatusException {
       
  2470 
       
  2471         SnmpParameters p = (SnmpParameters) peer.getParams();
       
  2472         return snmpInformRequest(peer.getDestAddr(),
       
  2473                                  peer.getDestPort(),
       
  2474                                  p.getInformCommunity(),
       
  2475                                  cb,
       
  2476                                  trapOid,
       
  2477                                  varBindList);
       
  2478     }
       
  2479 
       
  2480     /**
       
  2481      * Method that maps an SNMP error status in the passed protocolVersion
       
  2482      * according to the provided pdu type.
       
  2483      * @param errorStatus The error status to convert.
       
  2484      * @param protocolVersion The protocol version.
       
  2485      * @param reqPduType The pdu type.
       
  2486      */
       
  2487     public static int mapErrorStatus(int errorStatus,
       
  2488                                      int protocolVersion,
       
  2489                                      int reqPduType) {
       
  2490         return SnmpSubRequestHandler.mapErrorStatus(errorStatus,
       
  2491                                                     protocolVersion,
       
  2492                                                     reqPduType);
       
  2493     }
       
  2494 
       
  2495     private SnmpInformRequest snmpInformRequest(InetAddress addr,
       
  2496                                                 int port,
       
  2497                                                 String cs,
       
  2498                                                 SnmpInformHandler cb,
       
  2499                                                 SnmpOid trapOid,
       
  2500                                                 SnmpVarBindList varBindList)
       
  2501         throws IllegalStateException, IOException, SnmpStatusException {
       
  2502 
       
  2503         if (!isActive()) {
       
  2504             throw new IllegalStateException(
       
  2505               "Start SNMP adaptor server before carrying out this operation");
       
  2506         }
       
  2507         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2508             SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2509                 "snmpInformRequest", "trapOid=" + trapOid);
       
  2510         }
       
  2511 
       
  2512         // First, make an SNMP inform pdu:
       
  2513         // We clone varBindList and insert sysUpTime and snmpTrapOid variables.
       
  2514         //
       
  2515         SnmpVarBindList fullVbl ;
       
  2516         if (varBindList != null)
       
  2517             fullVbl = varBindList.clone() ;
       
  2518         else
       
  2519             fullVbl = new SnmpVarBindList(2) ;
       
  2520         SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
       
  2521         fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
       
  2522         fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
       
  2523                                 0);
       
  2524 
       
  2525         // Next, send the pdu to the specified destination
       
  2526         //
       
  2527         openInformSocketIfNeeded() ;
       
  2528         return informSession.makeAsyncRequest(addr, cs, cb, fullVbl, port) ;
       
  2529     }
       
  2530 
       
  2531 
       
  2532     /**
       
  2533      * Open informSocket if it's not already done.
       
  2534      */
       
  2535     synchronized void openInformSocketIfNeeded() throws SocketException {
       
  2536         if (informSession == null) {
       
  2537             informSession = new SnmpSession(this) ;
       
  2538             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2539                 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2540                    "openInformSocketIfNeeded",
       
  2541                       "to send inform requests and receive inform responses");
       
  2542             }
       
  2543         }
       
  2544     }
       
  2545 
       
  2546     /**
       
  2547      * Close informSocket if the SNMP protocol adaptor is not ONLINE.
       
  2548      */
       
  2549     synchronized void closeInformSocketIfNeeded() {
       
  2550         if ((informSession != null) && (state != ONLINE)) {
       
  2551             informSession.destroySession() ;
       
  2552             informSession = null ;
       
  2553         }
       
  2554     }
       
  2555 
       
  2556     /**
       
  2557      * Gets the IP address to bind.
       
  2558      * This getter is used to initialize the DatagramSocket in the
       
  2559      * SnmpSocket object created for the inform request stuff.
       
  2560      */
       
  2561     InetAddress getAddress() {
       
  2562         return address;
       
  2563     }
       
  2564 
       
  2565 
       
  2566     // PROTECTED METHODS
       
  2567     //------------------
       
  2568 
       
  2569     /**
       
  2570      * Finalizer of the SNMP protocol adaptor objects.
       
  2571      * This method is called by the garbage collector on an object
       
  2572      * when garbage collection determines that there are no more
       
  2573      * references to the object.
       
  2574      * <P>Closes the datagram socket associated to this SNMP protocol adaptor.
       
  2575      */
       
  2576     @Override
       
  2577     protected void finalize() {
       
  2578         try {
       
  2579             if (socket != null) {
       
  2580                 socket.close() ;
       
  2581                 socket = null ;
       
  2582             }
       
  2583 
       
  2584             threadService.terminate();
       
  2585         } catch (Exception e) {
       
  2586             if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
       
  2587                 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
       
  2588                    "finalize", "Exception in finalizer", e);
       
  2589             }
       
  2590         }
       
  2591     }
       
  2592 
       
  2593     // PACKAGE METHODS
       
  2594     //----------------
       
  2595 
       
  2596     /**
       
  2597      * Returns the string used in debug traces.
       
  2598      */
       
  2599     @Override
       
  2600     String makeDebugTag() {
       
  2601         return "SnmpAdaptorServer["+ getProtocol() + ":" + getPort() + "]";
       
  2602     }
       
  2603 
       
  2604     void updateRequestCounters(int pduType) {
       
  2605         switch(pduType)  {
       
  2606 
       
  2607         case pduGetRequestPdu:
       
  2608             snmpInGetRequests++;
       
  2609             break;
       
  2610         case pduGetNextRequestPdu:
       
  2611             snmpInGetNexts++;
       
  2612             break;
       
  2613         case pduSetRequestPdu:
       
  2614             snmpInSetRequests++;
       
  2615             break;
       
  2616         default:
       
  2617             break;
       
  2618         }
       
  2619         snmpInPkts++ ;
       
  2620     }
       
  2621 
       
  2622     void updateErrorCounters(int errorStatus) {
       
  2623         switch(errorStatus) {
       
  2624 
       
  2625         case snmpRspNoError:
       
  2626             snmpOutGetResponses++;
       
  2627             break;
       
  2628         case snmpRspGenErr:
       
  2629             snmpOutGenErrs++;
       
  2630             break;
       
  2631         case snmpRspBadValue:
       
  2632             snmpOutBadValues++;
       
  2633             break;
       
  2634         case snmpRspNoSuchName:
       
  2635             snmpOutNoSuchNames++;
       
  2636             break;
       
  2637         case snmpRspTooBig:
       
  2638             snmpOutTooBigs++;
       
  2639             break;
       
  2640         default:
       
  2641             break;
       
  2642         }
       
  2643         snmpOutPkts++ ;
       
  2644     }
       
  2645 
       
  2646     void updateVarCounters(int pduType, int n) {
       
  2647         switch(pduType) {
       
  2648 
       
  2649         case pduGetRequestPdu:
       
  2650         case pduGetNextRequestPdu:
       
  2651         case pduGetBulkRequestPdu:
       
  2652             snmpInTotalReqVars += n ;
       
  2653             break ;
       
  2654         case pduSetRequestPdu:
       
  2655             snmpInTotalSetVars += n ;
       
  2656             break ;
       
  2657         }
       
  2658     }
       
  2659 
       
  2660     void incSnmpInASNParseErrs(int n) {
       
  2661         snmpInASNParseErrs += n ;
       
  2662     }
       
  2663 
       
  2664     void incSnmpInBadVersions(int n) {
       
  2665         snmpInBadVersions += n ;
       
  2666     }
       
  2667 
       
  2668     void incSnmpInBadCommunityUses(int n) {
       
  2669         snmpInBadCommunityUses += n ;
       
  2670     }
       
  2671 
       
  2672     void incSnmpInBadCommunityNames(int n) {
       
  2673         snmpInBadCommunityNames += n ;
       
  2674     }
       
  2675 
       
  2676     void incSnmpSilentDrops(int n) {
       
  2677         snmpSilentDrops += n ;
       
  2678     }
       
  2679     // PRIVATE METHODS
       
  2680     //----------------
       
  2681 
       
  2682     /**
       
  2683      * Returns the time (in hundreths of second) elapsed since the SNMP
       
  2684      * protocol adaptor startup.
       
  2685      */
       
  2686     long getSysUpTime() {
       
  2687         return (System.currentTimeMillis() - startUpTime) / 10 ;
       
  2688     }
       
  2689 
       
  2690     /**
       
  2691      * Control the way the SnmpAdaptorServer service is deserialized.
       
  2692      */
       
  2693     private void readObject(ObjectInputStream stream)
       
  2694         throws IOException, ClassNotFoundException {
       
  2695 
       
  2696         // Call the default deserialization of the object.
       
  2697         //
       
  2698         stream.defaultReadObject();
       
  2699 
       
  2700         // Call the specific initialization for the SnmpAdaptorServer service.
       
  2701         // This is for transient structures to be initialized to specific
       
  2702         // default values.
       
  2703         //
       
  2704         mibs      = new Vector<>() ;
       
  2705     }
       
  2706 
       
  2707     /**
       
  2708      * Common initializations.
       
  2709      */
       
  2710     private void init(InetAddressAcl acl, int p, InetAddress a) {
       
  2711 
       
  2712         root= new SnmpMibTree();
       
  2713 
       
  2714         // The default Agent is initialized with a SnmpErrorHandlerAgent agent.
       
  2715         root.setDefaultAgent(new SnmpErrorHandlerAgent());
       
  2716 
       
  2717         // For the trap time, use the time the agent started ...
       
  2718         //
       
  2719         startUpTime= java.lang.System.currentTimeMillis();
       
  2720         maxActiveClientCount = 10;
       
  2721 
       
  2722         // Create the default message factory
       
  2723         pduFactory = new SnmpPduFactoryBER() ;
       
  2724 
       
  2725         port = p ;
       
  2726         ipacl = acl ;
       
  2727         address = a ;
       
  2728 
       
  2729         if ((ipacl == null) && (useAcl == true))
       
  2730             throw new IllegalArgumentException("ACL object cannot be null") ;
       
  2731 
       
  2732         threadService = new ThreadService(threadNumber);
       
  2733     }
       
  2734 
       
  2735     SnmpMibAgent getAgentMib(SnmpOid oid) {
       
  2736         return root.getAgentMib(oid);
       
  2737     }
       
  2738 
       
  2739     @Override
       
  2740     protected Thread createMainThread() {
       
  2741         final Thread t = super.createMainThread();
       
  2742         t.setDaemon(true);
       
  2743         return t;
       
  2744     }
       
  2745 
       
  2746 }