Package com.sun.jmx.snmp.agent

Source Code of com.sun.jmx.snmp.agent.SnmpMib

/*
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.  Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package com.sun.jmx.snmp.agent;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.Vector;

import javax.management.ObjectName;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.NotCompliantMBeanException;

import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
import com.sun.jmx.snmp.SnmpOid;
import com.sun.jmx.snmp.SnmpVarBind;
import com.sun.jmx.snmp.SnmpDefinitions;
import com.sun.jmx.snmp.SnmpStatusException;
import com.sun.jmx.snmp.SnmpEngine;
import com.sun.jmx.snmp.SnmpUnknownModelException;
import com.sun.jmx.snmp.internal.SnmpAccessControlModel;
import com.sun.jmx.snmp.internal.SnmpEngineImpl;

/**
* This list is used in order to construct the OID during the getnext.
* The constructed oid is checked by the checker AcmChecker.
*/
final class LongList {

    public static int DEFAULT_CAPACITY = 10;

    public static int DEFAULT_INCREMENT = 10;


    private final int DELTA;
    private int size;

    /**
     * The list content. Any access to this variable must be protected
     * by a synchronized block on the LongList object.
     * Only read-only action should be performed on this object.
     **/
    public  long[] list;

    LongList() {
        this(DEFAULT_CAPACITY,DEFAULT_INCREMENT);
    }

    LongList(int initialCapacity) {
        this(initialCapacity,DEFAULT_INCREMENT);
    }

    LongList(int initialCapacity, int delta) {
        size = 0;
        DELTA = delta;
        list = allocate(initialCapacity);
    }

    /**
     * Same behaviour than size() in {@link java.util.List}.
     **/
    public final int size() { return size;}

    /**
     * Same behaviour than add(long o) in {@link java.util.List}.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final boolean add(final long o) {
        if (size >= list.length)
            resize();
        list[size++]=o;
        return true;
    }

    /**
     * Same behaviour than add(int index, long o) in
     * {@link java.util.List}.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final void add(final int index, final long o) {
        if (index >  size) throw new IndexOutOfBoundsException();
        if (index >= list.length) resize();
        if (index == size) {
            list[size++]=o;
            return;
        }

        java.lang.System.arraycopy(list,index,list,index+1,size-index);
        list[index]=o;
        size++;
    }

    /**
     * Adds <var>count</var> elements to the list.
     * @param at index at which the elements must be inserted. The
     *        first element will be inserted at this index.
     * @param src  An array containing the elements we want to insert.
     * @param from Index of the first element from <var>src</var> that
     *        must be inserted.
     * @param count number of elements to insert.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final void add(final int at,final long[] src, final int from,
                          final int count) {
        if (count <= 0) return;
        if (at > size) throw new IndexOutOfBoundsException();
        ensure(size+count);
        if (at < size) {
            java.lang.System.arraycopy(list,at,list,at+count,size-at);
        }
        java.lang.System.arraycopy(src,from,list,at,count);
        size+=count;
    }

    /**
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final long remove(final int from, final int count) {
        if (count < 1 || from < 0) return -1;
        if (from+count > size) return -1;

        final long o = list[from];
        final int oldsize = size;
        size = size - count;

        if (from == size) return o;

        java.lang.System.arraycopy(list,from+count,list,from,
                                   size-from);
        return o;
    }

    /**
     * Same behaviour than remove(int index) in {@link java.util.List}.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final long remove(final int index) {
        if (index >= size) return -1;
        final long o = list[index];
        list[index]=0;
        if (index == --size) return o;

        java.lang.System.arraycopy(list,index+1,list,index,
                                   size-index);
        return o;
    }

    /**
     * Same behaviour than the toArray(long[] a) method in
     * {@link java.util.List}.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final long[] toArray(long[] a) {
        java.lang.System.arraycopy(list,0,a,0,size);
        return a;
    }

    /**
     * Same behaviour than the toArray() method in
     * {@link java.util.List}.
     * Any access to this method should be protected in a synchronized
     * block on the LongList object.
     **/
    public final long[] toArray() {
        return toArray(new long[size]);
    }

    /**
     * Resize the list. Increase its capacity by DELTA elements.
     * Any call to this method must be protected by a synchronized
     * block on this LongList.
     **/
    private final void resize() {
        final long[] newlist = allocate(list.length + DELTA);
        java.lang.System.arraycopy(list,0,newlist,0,size);
        list = newlist;
    }

    /**
     * Resize the list. Insure that the new length will be at
     * least equal to <var>length</var>.
     * @param length new minimal length requested.
     * Any call to this method must be protected by a synchronized
     * block on this LongList.
     **/
    private final void ensure(int length) {
        if (list.length < length) {
            final int min = list.length+DELTA;
            length=(length<min)?min:length;
            final long[] newlist = allocate(length);
            java.lang.System.arraycopy(list,0,newlist,0,size);
            list = newlist;
        }
    }

    /**
     * Allocate a new array of object of specified length.
     **/
    private final long[] allocate(final int length) {
        return new long[length];
    }

}

/**
* Oid Checker makes use of ACM to check each OID during the getnext process.
*/
class AcmChecker {


    SnmpAccessControlModel model = null;
    String principal = null;
    int securityLevel = -1;
    int version = -1;
    int pduType = -1;
    int securityModel = -1;
    byte[] contextName = null;
    SnmpEngineImpl engine = null;
    LongList l = null;
    AcmChecker(SnmpMibRequest req) {
        engine = (SnmpEngineImpl) req.getEngine();
        //We are in V3 architecture, ACM is in the picture.
        if(engine != null) {
            if(engine.isCheckOidActivated()) {
                try {
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "AcmChecker(SnmpMibRequest)",
                                "SNMP V3 Access Control to be done");
                    }
                    model = (SnmpAccessControlModel)
                        engine.getAccessControlSubSystem().
                        getModel(SnmpDefinitions.snmpVersionThree);
                    principal = req.getPrincipal();
                    securityLevel = req.getSecurityLevel();
                    pduType = req.getPdu().type;
                    version = req.getRequestPduVersion();
                    securityModel = req.getSecurityModel();
                    contextName = req.getAccessContextName();
                    l = new LongList();
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        final StringBuilder strb = new StringBuilder()
                        .append("Will check oid for : principal : ")
                        .append(principal)
                        .append("; securityLevel : ").append(securityLevel)
                        .append("; pduType : ").append(pduType)
                        .append("; version : ").append(version)
                        .append("; securityModel : ").append(securityModel)
                        .append("; contextName : ").append(contextName);
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "AcmChecker(SnmpMibRequest)", strb.toString());
                    }

                }catch(SnmpUnknownModelException e) {
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "AcmChecker(SnmpMibRequest)",
                                "Unknown Model, no ACM check.");
                    }
                }
            }
        }
    }

    void add(int index, long arc) {
        if(model != null)
            l.add(index, arc);
    }

    void remove(int index) {
        if(model != null)
            l.remove(index);
    }

    void add(final int at,final long[] src, final int from,
             final int count) {
        if(model != null)
            l.add(at,src,from,count);
    }

    void remove(final int from, final int count) {
        if(model != null)
            l.remove(from,count);
    }

    void checkCurrentOid() throws SnmpStatusException {
        if(model != null) {
            SnmpOid oid = new SnmpOid(l.toArray());
            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                        "checkCurrentOid", "Checking access for : " + oid);
            }
            model.checkAccess(version,
                              principal,
                              securityLevel,
                              pduType,
                              securityModel,
                              contextName,
                              oid);
        }
    }

}

/**
* Abstract class for representing an SNMP MIB.
* <P>
* When compiling a SNMP MIB, among all the classes generated by
* <CODE>mibgen</CODE>, there is one which extends <CODE>SnmpMib</CODE>
* for representing a whole MIB.
* <BR>The class is used by the SNMP protocol adaptor as the entry point in
* the MIB.
*
* <p>This generated class can be subclassed in your code in order to
* plug in your own specific behaviour.
* </p>
*
* <p><b>This API is a Sun Microsystems internal API  and is subject
* to change without notice.</b></p>
*/
public abstract class SnmpMib extends SnmpMibAgent implements Serializable {

    /**
     * Default constructor.
     * Initializes the OID tree.
     */
    public SnmpMib() {
        root= new SnmpMibOid();
    }


    // --------------------------------------------------------------------
    // POLYMORHIC METHODS
    // --------------------------------------------------------------------

    /**
     * <p>
     * This callback should return the OID associated to the group
     * identified by the given <code>groupName</code>.
     * </p>
     *
     * <p>
     * This method is provided as a hook to plug-in some custom
     * specific behavior. Although doing so is discouraged you might
     * want to subclass this method in order to store & provide more metadata
     * information (mapping OID <-> symbolic name) within the agent,
     * or to "change" the root of the MIB OID by prefixing the
     * defaultOid by an application dependant OID string, for instance.
     * </p>
     *
     * <p>
     * The default implementation of this method is to return the given
     * <code>defaultOid</code>
     * </p>
     *
     * @param groupName   The java-ized name of the SNMP group.
     * @param defaultOid  The OID defined in the MIB for that group
     *                    (in dot notation).
     *
     * @return The OID of the group identified by <code>groupName</code>,
     *         in dot-notation.
     */
    protected String getGroupOid(String groupName, String defaultOid) {
        return defaultOid;
    }

    /**
     * <p>
     * This callback should return the ObjectName associated to the
     * group identified by the given <code>groupName</code>.
     * </p>
     *
     * <p>
     * This method is provided as a hook to plug-in some custom
     * specific behavior. You might want to override this method
     * in order to provide a different object naming scheme than
     * that proposed by default by <code>mibgen</code>.
     * </p>
     *
     * <p>
     * This method is only meaningful if the MIB is registered
     * in the MBeanServer, otherwise, it will not be called.
     * </p>
     *
     * <p>
     * The default implementation of this method is to return an ObjectName
     * built from the given <code>defaultName</code>.
     * </p>
     *
     * @param name  The java-ized name of the SNMP group.
     * @param oid   The OID returned by getGroupOid() - in dot notation.
     * @param defaultName The name by default generated by <code>
     *                    mibgen</code>
     *
     * @return The ObjectName of the group identified by <code>name</code>
     */
    protected ObjectName getGroupObjectName(String name, String oid,
                                            String defaultName)
        throws MalformedObjectNameException {
        return new ObjectName(defaultName);
    }

    /**
     * <p>
     * Register an SNMP group and its metadata node in the MIB.
     * </p>
     *
     * <p>
     * This method is provided as a hook to plug-in some custom
     * specific behavior. You might want to override this method
     * if you want to set special links between the MBean, its metadata
     * node, its OID or ObjectName etc..
     * </p>
     *
     * <p>
     * If the MIB is not registered in the MBeanServer, the <code>
     * server</code> and <code>groupObjName</code> parameters will be
     * <code>null</code>.<br>
     * If the given group MBean is not <code>null</code>, and if the
     * <code>server</code> and <code>groupObjName</code> parameters are
     * not null, then this method will also automatically register the
     * group MBean with the given MBeanServer <code>server</code>.
     * </p>
     *
     * @param groupName  The java-ized name of the SNMP group.
     * @param groupOid   The OID as returned by getGroupOid() - in dot
     *                   notation.
     * @param groupObjName The ObjectName as returned by getGroupObjectName().
     *                   This parameter may be <code>null</code> if the
     *                   MIB is not registered in the MBeanServer.
     * @param node       The metadata node, as returned by the metadata
     *                   factory method for this group.
     * @param group      The MBean for this group, as returned by the
     *                   MBean factory method for this group.
     * @param server     The MBeanServer in which the groups are to be
     *                   registered. This parameter will be <code>null</code>
     *                   if the MIB is not registered, otherwise it is a
     *                   reference to the MBeanServer in which the MIB is
     *                   registered.
     *
     */
    protected void registerGroupNode(String groupName,   String groupOid,
                                     ObjectName groupObjName, SnmpMibNode node,
                                     Object group, MBeanServer server)
        throws NotCompliantMBeanException, MBeanRegistrationException,
        InstanceAlreadyExistsException, IllegalAccessException {
        root.registerNode(groupOid,node);
        if (server != null && groupObjName != null && group != null)
            server.registerMBean(group,groupObjName);
    }

    /**
     * <p>
     * Register an SNMP Table metadata node in the MIB.
     * </p>
     *
     * <p>
     * <b><i>
     * This method is used internally and you should never need to
     * call it directly.</i></b><br> It is used to establish the link
     * between an SNMP table metadata node and its bean-like counterpart.
     * <br>
     * The group metadata nodes will create and register their
     * underlying table metadata nodes in the MIB using this
     * method. <br>
     * The metadata nodes will be later retrieved from the MIB by the
     * bean-like table objects using the getRegisterTableMeta() method.
     * </p>
     *
     * @param name      The java-ized name of the SNMP table.
     * @param table     The SNMP table metadata node - usually this
     *                  corresponds to a <code>mibgen</code> generated
     *                  object.
     */
    public abstract void registerTableMeta(String name, SnmpMibTable table);

    /**
     * Returns a registered SNMP Table metadata node.
     *
     * <p><b><i>
     * This method is used internally and you should never need to
     * call it directly.
     * </i></b></p>
     *
     */
    public abstract SnmpMibTable getRegisteredTableMeta(String name);

    // --------------------------------------------------------------------
    // PUBLIC METHODS
    // --------------------------------------------------------------------

    /**
     * Processes a <CODE>get</CODE> operation.
     *
     **/
    // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
    // for java-doc
    //
    public void get(SnmpMibRequest req) throws SnmpStatusException {

        // Builds the request tree: creation is not allowed, operation
        // is not atomic.

        final int reqType = SnmpDefinitions.pduGetRequestPdu;
        SnmpRequestTree handlers = getHandlers(req,false,false,reqType);

        SnmpRequestTree.Handler h = null;
        SnmpMibNode meta = null;

        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                    "get", "Processing handlers for GET... ");
        }

        // For each sub-request stored in the request-tree, invoke the
        // get() method.
        for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
            h = (SnmpRequestTree.Handler) eh.nextElement();

            // Gets the Meta node. It can be either a Group Meta or a
            // Table Meta.
            //
            meta = handlers.getMetaNode(h);

            // Gets the depth of the Meta node in the OID tree
            final int depth = handlers.getOidDepth(h);

            for (Enumeration rqs=handlers.getSubRequests(h);
                 rqs.hasMoreElements();) {

                // Invoke the get() operation.
                meta.get((SnmpMibSubRequest)rqs.nextElement(),depth);
            }
        }
    }

    /**
     * Processes a <CODE>set</CODE> operation.
     *
     */
    // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
    // for java-doc
    //
    public void set(SnmpMibRequest req) throws SnmpStatusException {

        SnmpRequestTree handlers = null;

        // Optimization: we're going to get the whole SnmpRequestTree
        // built in the "check" method, so that we don't have to rebuild
        // it here.
        //
        if (req instanceof SnmpMibRequestImpl)
            handlers = ((SnmpMibRequestImpl)req).getRequestTree();

        // Optimization didn't work: we have to rebuild the tree.
        //
        // Builds the request tree: creation is not allowed, operation
        // is atomic.
        //
        final int reqType = SnmpDefinitions.pduSetRequestPdu;
        if (handlers == null) handlers = getHandlers(req,false,true,reqType);
        handlers.switchCreationFlag(false);
        handlers.setPduType(reqType);

        SnmpRequestTree.Handler h = null;
        SnmpMibNode meta = null;

        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                    "set", "Processing handlers for SET... ");
        }

        // For each sub-request stored in the request-tree, invoke the
        // get() method.
        for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
            h = (SnmpRequestTree.Handler) eh.nextElement();

            // Gets the Meta node. It can be either a Group Meta or a
            // Table Meta.
            //
            meta = handlers.getMetaNode(h);

            // Gets the depth of the Meta node in the OID tree
            final int depth = handlers.getOidDepth(h);

            for (Enumeration rqs=handlers.getSubRequests(h);
                 rqs.hasMoreElements();) {

                // Invoke the set() operation
                meta.set((SnmpMibSubRequest)rqs.nextElement(),depth);
            }
        }
    }

    /**
     * Checks if a <CODE>set</CODE> operation can be performed.
     * If the operation cannot be performed, the method will raise a
     * <CODE>SnmpStatusException</CODE>.
     *
     */
    // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
    // for java-doc
    //
    public void check(SnmpMibRequest req) throws SnmpStatusException {

        final int reqType = SnmpDefinitions.pduWalkRequest;
        // Builds the request tree: creation is allowed, operation
        // is atomic.
        SnmpRequestTree handlers = getHandlers(req,true,true,reqType);

        SnmpRequestTree.Handler h = null;
        SnmpMibNode meta = null;

        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                    "check", "Processing handlers for CHECK... ");
        }

        // For each sub-request stored in the request-tree, invoke the
        // check() method.
        for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
            h = (SnmpRequestTree.Handler) eh.nextElement();

            // Gets the Meta node. It can be either a Group Meta or a
            // Table Meta.
            //
            meta = handlers.getMetaNode(h);

            // Gets the depth of the Meta node in the OID tree
            final int depth = handlers.getOidDepth(h);

            for (Enumeration rqs=handlers.getSubRequests(h);
                 rqs.hasMoreElements();) {

                // Invoke the check() operation
                meta.check((SnmpMibSubRequest)rqs.nextElement(),depth);
            }
        }

        // Optimization: we're going to pass the whole SnmpRequestTree
        // to the "set" method, so that we don't have to rebuild it there.
        //
        if (req instanceof SnmpMibRequestImpl) {
            ((SnmpMibRequestImpl)req).setRequestTree(handlers);
        }

    }

    /**
     * Processes a <CODE>getNext</CODE> operation.
     *
     */
    // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
    // for java-doc
    //
    public void getNext(SnmpMibRequest req) throws SnmpStatusException {
        // Build the request tree for the operation
        // The subrequest stored in the request tree are valid GET requests
        SnmpRequestTree handlers = getGetNextHandlers(req);

        SnmpRequestTree.Handler h = null;
        SnmpMibNode meta = null;

        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                    "getNext", "Processing handlers for GET-NEXT... ");
        }

        // Now invoke get() for each subrequest of the request tree.
        for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
            h = (SnmpRequestTree.Handler) eh.nextElement();

            // Gets the Meta node. It can be either a Group Meta or a
            // Table Meta.
            //
            meta = handlers.getMetaNode(h);

            // Gets the depth of the Meta node in the OID tree
            int depth = handlers.getOidDepth(h);

            for (Enumeration rqs=handlers.getSubRequests(h);
                 rqs.hasMoreElements();) {

                // Invoke the get() operation
                meta.get((SnmpMibSubRequest)rqs.nextElement(),depth);
            }
        }
    }


    /**
     * Processes a <CODE>getBulk</CODE> operation.
     * The method implements the <CODE>getBulk</CODE> operation by calling
     * appropriately the <CODE>getNext</CODE> method.
     *
     */
    // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
    // for java-doc
    //
    public void getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat)
        throws SnmpStatusException {

        getBulkWithGetNext(req, nonRepeat, maxRepeat);
    }

    /**
     * Gets the root object identifier of the MIB.
     * <P>In order to be accurate, the method should be called once the
     * MIB is fully initialized (that is, after a call to <CODE>init</CODE>
     * or <CODE>preRegister</CODE>).
     *
     * @return The root object identifier.
     */
    public long[] getRootOid() {

        if( rootOid == null) {
            Vector<Integer> list= new Vector<Integer>(10);

            // Ask the tree to do the job !
            //
            root.getRootOid(list);

            // Now format the result
            //
            rootOid= new long[list.size()];
            int i=0;
            for(Enumeration<Integer> e= list.elements(); e.hasMoreElements(); ) {
                Integer val= e.nextElement();
                rootOid[i++]= val.longValue();
            }
        }
        return rootOid;

    }

    // --------------------------------------------------------------------
    // PRIVATE METHODS
    //---------------------------------------------------------------------

    /**
     * This method builds the temporary request-tree that will be used to
     * perform the SNMP request associated with the given vector of varbinds
     * `list'.
     *
     * @param req The SnmpMibRequest object holding the varbind list
     *             concerning this MIB.
     * @param createflag Indicates whether the operation allow for creation
     *        of new instances (ie: it is a SET).
     * @param atomic Indicates whether the operation is atomic or not.
     * @param type Request type (from SnmpDefinitions).
     *
     * @return The request-tree where the original varbind list has been
     *         dispatched to the appropriate nodes.
     */
    private SnmpRequestTree getHandlers(SnmpMibRequest req,
                                        boolean createflag, boolean atomic,
                                        int type)
        throws SnmpStatusException {

        // Build an empty request tree
        SnmpRequestTree handlers =
            new SnmpRequestTree(req,createflag,type);

        int index=0;
        SnmpVarBind var = null;
        final int ver= req.getVersion();

        // For each varbind in the list finds its handling node.
        for (Enumeration e= req.getElements(); e.hasMoreElements(); index++) {

            var= (SnmpVarBind) e.nextElement();

            try {
                // Find the handling node for this varbind.
                root.findHandlingNode(var,var.oid.longValue(false),
                                      0,handlers);
            } catch(SnmpStatusException x) {

                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                            SnmpMib.class.getName(),
                            "getHandlers",
                            "Couldn't find a handling node for " +
                            var.oid.toString());
                }

                // If the operation is atomic (Check/Set) or the version
                // is V1 we must generate an exception.
                //
                if (ver == SnmpDefinitions.snmpVersionOne) {

                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers", "\tV1: Throwing exception");
                    }

                    // The index in the exception must correspond to the
                    // SNMP index ...
                    //
                    final SnmpStatusException sse =
                        new SnmpStatusException(x, index + 1);
                    sse.initCause(x);
                    throw sse;
                } else if ((type == SnmpDefinitions.pduWalkRequest)   ||
                           (type == SnmpDefinitions.pduSetRequestPdu)) {
                    final int status =
                        SnmpRequestTree.mapSetException(x.getStatus(),ver);

                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers", "\tSET: Throwing exception");
                    }

                    final SnmpStatusException sse =
                        new SnmpStatusException(status, index + 1);
                    sse.initCause(x);
                    throw sse;
                } else if (atomic) {

                    // Should never come here...
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers", "\tATOMIC: Throwing exception");
                    }

                    final SnmpStatusException sse =
                        new SnmpStatusException(x, index + 1);
                    sse.initCause(x);
                    throw sse;
                }

                final int status =
                    SnmpRequestTree.mapGetException(x.getStatus(),ver);

                if (status == SnmpStatusException.noSuchInstance) {

                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers",
                                "\tGET: Registering noSuchInstance");
                    }

                    var.value= SnmpVarBind.noSuchInstance;

                } else if (status == SnmpStatusException.noSuchObject) {
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers",
                                "\tGET: Registering noSuchObject");
                    }

                        var.value= SnmpVarBind.noSuchObject;

                } else {

                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getHandlers",
                                "\tGET: Registering global error: " + status);
                    }

                    final SnmpStatusException sse =
                        new SnmpStatusException(status, index + 1);
                    sse.initCause(x);
                    throw sse;
                }
            }
        }
        return handlers;
    }

    /**
     * This method builds the temporary request-tree that will be used to
     * perform the SNMP GET-NEXT request associated with the given vector
     * of varbinds `list'.
     *
     * @param req The SnmpMibRequest object holding the varbind list
     *             concerning this MIB.
     *
     * @return The request-tree where the original varbind list has been
     *         dispatched to the appropriate nodes, and where the original
     *         OIDs have been replaced with the correct "next" OID.
     */
    private SnmpRequestTree getGetNextHandlers(SnmpMibRequest req)
        throws SnmpStatusException {

        // Creates an empty request tree, no entry creation is allowed (false)
        SnmpRequestTree handlers = new
            SnmpRequestTree(req,false,SnmpDefinitions.pduGetNextRequestPdu);

        // Sets the getNext flag: if version=V2, status exception are
        // transformed in  endOfMibView
        handlers.setGetNextFlag();

        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
                    "getGetNextHandlers", "Received MIB request : " + req);
        }
        AcmChecker checker = new AcmChecker(req);
        int index=0;
        SnmpVarBind var = null;
        final int ver= req.getVersion();
        SnmpOid original = null;
        // For each varbind, finds the handling node.
        // This function has the side effect of transforming a GET-NEXT
        // request into a valid GET request, replacing the OIDs in the
        // original GET-NEXT request with the OID of the first leaf that
        // follows.
        for (Enumeration e= req.getElements(); e.hasMoreElements(); index++) {

            var = (SnmpVarBind) e.nextElement();
            SnmpOid result = null;
            try {
                // Find the node handling the OID that follows the varbind
                // OID. `result' contains this next leaf OID.
                //ACM loop.
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                            SnmpMib.class.getName(),
                            "getGetNextHandlers", " Next OID of : " + var.oid);
                }
                result = new SnmpOid(root.findNextHandlingNode
                                     (var,var.oid.longValue(false),0,
                                      0,handlers, checker));

                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                            SnmpMib.class.getName(),
                            "getGetNextHandlers", " is : " + result);
                }
                // We replace the varbind original OID with the OID of the
                // leaf object we have to return.
                var.oid = result;
            } catch(SnmpStatusException x) {

                // if (isDebugOn())
                //    debug("getGetNextHandlers",
                //        "Couldn't find a handling node for "
                //        + var.oid.toString());

                if (ver == SnmpDefinitions.snmpVersionOne) {
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                                SnmpMib.class.getName(),
                                "getGetNextHandlers",
                                "\tThrowing exception " + x.toString());
                    }
                    // The index in the exception must correspond to the
                    // SNMP index ...
                    //
                    throw new SnmpStatusException(x, index + 1);
                }
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
                            SnmpMib.class.getName(),
                            "getGetNextHandlers",
                            "Exception : " + x.getStatus());
                }

                var.setSnmpValue(SnmpVarBind.endOfMibView);
            }
        }
        return handlers;
    }

    // --------------------------------------------------------------------
    // PROTECTED VARIABLES
    // --------------------------------------------------------------------

    /**
     * The top element in the Mib tree.
     * @serial
     */
    protected SnmpMibOid root;


    // --------------------------------------------------------------------
    // PRIVATE VARIABLES
    // --------------------------------------------------------------------

    /**
     * The root object identifier of the MIB.
     */
    private transient long[] rootOid= null;
}
TOP

Related Classes of com.sun.jmx.snmp.agent.SnmpMib

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.