0N/A/*
2362N/A * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage com.sun.jmx.snmp.agent;
0N/A
0N/Aimport java.io.Serializable;
0N/Aimport java.util.Enumeration;
0N/Aimport java.util.logging.Level;
0N/Aimport java.util.Vector;
0N/A
0N/Aimport javax.management.ObjectName;
0N/Aimport javax.management.MBeanServer;
0N/Aimport javax.management.MalformedObjectNameException;
0N/Aimport javax.management.InstanceAlreadyExistsException;
0N/Aimport javax.management.MBeanRegistrationException;
0N/Aimport javax.management.NotCompliantMBeanException;
0N/A
0N/Aimport static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
0N/Aimport com.sun.jmx.snmp.SnmpOid;
0N/Aimport com.sun.jmx.snmp.SnmpVarBind;
0N/Aimport com.sun.jmx.snmp.SnmpDefinitions;
0N/Aimport com.sun.jmx.snmp.SnmpStatusException;
0N/Aimport com.sun.jmx.snmp.SnmpEngine;
0N/Aimport com.sun.jmx.snmp.SnmpUnknownModelException;
0N/Aimport com.sun.jmx.snmp.internal.SnmpAccessControlModel;
0N/Aimport com.sun.jmx.snmp.internal.SnmpEngineImpl;
0N/A
0N/A/**
0N/A * This list is used in order to construct the OID during the getnext.
0N/A * The constructed oid is checked by the checker AcmChecker.
0N/A */
0N/Afinal class LongList {
0N/A
0N/A public static int DEFAULT_CAPACITY = 10;
0N/A
0N/A public static int DEFAULT_INCREMENT = 10;
0N/A
0N/A
0N/A private final int DELTA;
0N/A private int size;
0N/A
0N/A /**
0N/A * The list content. Any access to this variable must be protected
0N/A * by a synchronized block on the LongList object.
0N/A * Only read-only action should be performed on this object.
0N/A **/
0N/A public long[] list;
0N/A
0N/A LongList() {
0N/A this(DEFAULT_CAPACITY,DEFAULT_INCREMENT);
0N/A }
0N/A
0N/A LongList(int initialCapacity) {
0N/A this(initialCapacity,DEFAULT_INCREMENT);
0N/A }
0N/A
0N/A LongList(int initialCapacity, int delta) {
0N/A size = 0;
0N/A DELTA = delta;
0N/A list = allocate(initialCapacity);
0N/A }
0N/A
0N/A /**
0N/A * Same behaviour than size() in {@link java.util.List}.
0N/A **/
0N/A public final int size() { return size;}
0N/A
0N/A /**
0N/A * Same behaviour than add(long o) in {@link java.util.List}.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final boolean add(final long o) {
0N/A if (size >= list.length)
0N/A resize();
0N/A list[size++]=o;
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * Same behaviour than add(int index, long o) in
0N/A * {@link java.util.List}.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final void add(final int index, final long o) {
0N/A if (index > size) throw new IndexOutOfBoundsException();
0N/A if (index >= list.length) resize();
0N/A if (index == size) {
0N/A list[size++]=o;
0N/A return;
0N/A }
0N/A
0N/A java.lang.System.arraycopy(list,index,list,index+1,size-index);
0N/A list[index]=o;
0N/A size++;
0N/A }
0N/A
0N/A /**
0N/A * Adds <var>count</var> elements to the list.
0N/A * @param at index at which the elements must be inserted. The
0N/A * first element will be inserted at this index.
0N/A * @param src An array containing the elements we want to insert.
0N/A * @param from Index of the first element from <var>src</var> that
0N/A * must be inserted.
0N/A * @param count number of elements to insert.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final void add(final int at,final long[] src, final int from,
0N/A final int count) {
0N/A if (count <= 0) return;
0N/A if (at > size) throw new IndexOutOfBoundsException();
0N/A ensure(size+count);
0N/A if (at < size) {
0N/A java.lang.System.arraycopy(list,at,list,at+count,size-at);
0N/A }
0N/A java.lang.System.arraycopy(src,from,list,at,count);
0N/A size+=count;
0N/A }
0N/A
0N/A /**
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final long remove(final int from, final int count) {
0N/A if (count < 1 || from < 0) return -1;
0N/A if (from+count > size) return -1;
0N/A
0N/A final long o = list[from];
0N/A final int oldsize = size;
0N/A size = size - count;
0N/A
0N/A if (from == size) return o;
0N/A
0N/A java.lang.System.arraycopy(list,from+count,list,from,
0N/A size-from);
0N/A return o;
0N/A }
0N/A
0N/A /**
0N/A * Same behaviour than remove(int index) in {@link java.util.List}.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final long remove(final int index) {
0N/A if (index >= size) return -1;
0N/A final long o = list[index];
0N/A list[index]=0;
0N/A if (index == --size) return o;
0N/A
0N/A java.lang.System.arraycopy(list,index+1,list,index,
0N/A size-index);
0N/A return o;
0N/A }
0N/A
0N/A /**
0N/A * Same behaviour than the toArray(long[] a) method in
0N/A * {@link java.util.List}.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final long[] toArray(long[] a) {
0N/A java.lang.System.arraycopy(list,0,a,0,size);
0N/A return a;
0N/A }
0N/A
0N/A /**
0N/A * Same behaviour than the toArray() method in
0N/A * {@link java.util.List}.
0N/A * Any access to this method should be protected in a synchronized
0N/A * block on the LongList object.
0N/A **/
0N/A public final long[] toArray() {
0N/A return toArray(new long[size]);
0N/A }
0N/A
0N/A /**
0N/A * Resize the list. Increase its capacity by DELTA elements.
0N/A * Any call to this method must be protected by a synchronized
0N/A * block on this LongList.
0N/A **/
0N/A private final void resize() {
0N/A final long[] newlist = allocate(list.length + DELTA);
0N/A java.lang.System.arraycopy(list,0,newlist,0,size);
0N/A list = newlist;
0N/A }
0N/A
0N/A /**
0N/A * Resize the list. Insure that the new length will be at
0N/A * least equal to <var>length</var>.
0N/A * @param length new minimal length requested.
0N/A * Any call to this method must be protected by a synchronized
0N/A * block on this LongList.
0N/A **/
0N/A private final void ensure(int length) {
0N/A if (list.length < length) {
0N/A final int min = list.length+DELTA;
0N/A length=(length<min)?min:length;
0N/A final long[] newlist = allocate(length);
0N/A java.lang.System.arraycopy(list,0,newlist,0,size);
0N/A list = newlist;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Allocate a new array of object of specified length.
0N/A **/
0N/A private final long[] allocate(final int length) {
0N/A return new long[length];
0N/A }
0N/A
0N/A}
0N/A
0N/A/**
0N/A * Oid Checker makes use of ACM to check each OID during the getnext process.
0N/A */
0N/Aclass AcmChecker {
0N/A
0N/A
0N/A SnmpAccessControlModel model = null;
0N/A String principal = null;
0N/A int securityLevel = -1;
0N/A int version = -1;
0N/A int pduType = -1;
0N/A int securityModel = -1;
0N/A byte[] contextName = null;
0N/A SnmpEngineImpl engine = null;
0N/A LongList l = null;
0N/A AcmChecker(SnmpMibRequest req) {
0N/A engine = (SnmpEngineImpl) req.getEngine();
0N/A //We are in V3 architecture, ACM is in the picture.
0N/A if(engine != null) {
0N/A if(engine.isCheckOidActivated()) {
0N/A try {
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "AcmChecker(SnmpMibRequest)",
0N/A "SNMP V3 Access Control to be done");
0N/A }
0N/A model = (SnmpAccessControlModel)
0N/A engine.getAccessControlSubSystem().
0N/A getModel(SnmpDefinitions.snmpVersionThree);
0N/A principal = req.getPrincipal();
0N/A securityLevel = req.getSecurityLevel();
0N/A pduType = req.getPdu().type;
0N/A version = req.getRequestPduVersion();
0N/A securityModel = req.getSecurityModel();
0N/A contextName = req.getAccessContextName();
0N/A l = new LongList();
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A final StringBuilder strb = new StringBuilder()
0N/A .append("Will check oid for : principal : ")
0N/A .append(principal)
0N/A .append("; securityLevel : ").append(securityLevel)
0N/A .append("; pduType : ").append(pduType)
0N/A .append("; version : ").append(version)
0N/A .append("; securityModel : ").append(securityModel)
0N/A .append("; contextName : ").append(contextName);
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "AcmChecker(SnmpMibRequest)", strb.toString());
0N/A }
0N/A
0N/A }catch(SnmpUnknownModelException e) {
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "AcmChecker(SnmpMibRequest)",
0N/A "Unknown Model, no ACM check.");
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A void add(int index, long arc) {
0N/A if(model != null)
0N/A l.add(index, arc);
0N/A }
0N/A
0N/A void remove(int index) {
0N/A if(model != null)
0N/A l.remove(index);
0N/A }
0N/A
0N/A void add(final int at,final long[] src, final int from,
0N/A final int count) {
0N/A if(model != null)
0N/A l.add(at,src,from,count);
0N/A }
0N/A
0N/A void remove(final int from, final int count) {
0N/A if(model != null)
0N/A l.remove(from,count);
0N/A }
0N/A
0N/A void checkCurrentOid() throws SnmpStatusException {
0N/A if(model != null) {
0N/A SnmpOid oid = new SnmpOid(l.toArray());
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "checkCurrentOid", "Checking access for : " + oid);
0N/A }
0N/A model.checkAccess(version,
0N/A principal,
0N/A securityLevel,
0N/A pduType,
0N/A securityModel,
0N/A contextName,
0N/A oid);
0N/A }
0N/A }
0N/A
0N/A}
0N/A
0N/A/**
0N/A * Abstract class for representing an SNMP MIB.
0N/A * <P>
0N/A * When compiling a SNMP MIB, among all the classes generated by
0N/A * <CODE>mibgen</CODE>, there is one which extends <CODE>SnmpMib</CODE>
0N/A * for representing a whole MIB.
0N/A * <BR>The class is used by the SNMP protocol adaptor as the entry point in
0N/A * the MIB.
0N/A *
0N/A * <p>This generated class can be subclassed in your code in order to
0N/A * plug in your own specific behaviour.
0N/A * </p>
0N/A *
0N/A * <p><b>This API is a Sun Microsystems internal API and is subject
0N/A * to change without notice.</b></p>
0N/A */
0N/Apublic abstract class SnmpMib extends SnmpMibAgent implements Serializable {
0N/A
0N/A /**
0N/A * Default constructor.
0N/A * Initializes the OID tree.
0N/A */
0N/A public SnmpMib() {
0N/A root= new SnmpMibOid();
0N/A }
0N/A
0N/A
0N/A // --------------------------------------------------------------------
0N/A // POLYMORHIC METHODS
0N/A // --------------------------------------------------------------------
0N/A
0N/A /**
0N/A * <p>
0N/A * This callback should return the OID associated to the group
0N/A * identified by the given <code>groupName</code>.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * This method is provided as a hook to plug-in some custom
0N/A * specific behavior. Although doing so is discouraged you might
0N/A * want to subclass this method in order to store & provide more metadata
0N/A * information (mapping OID <-> symbolic name) within the agent,
0N/A * or to "change" the root of the MIB OID by prefixing the
0N/A * defaultOid by an application dependant OID string, for instance.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * The default implementation of this method is to return the given
0N/A * <code>defaultOid</code>
0N/A * </p>
0N/A *
0N/A * @param groupName The java-ized name of the SNMP group.
0N/A * @param defaultOid The OID defined in the MIB for that group
0N/A * (in dot notation).
0N/A *
0N/A * @return The OID of the group identified by <code>groupName</code>,
0N/A * in dot-notation.
0N/A */
0N/A protected String getGroupOid(String groupName, String defaultOid) {
0N/A return defaultOid;
0N/A }
0N/A
0N/A /**
0N/A * <p>
0N/A * This callback should return the ObjectName associated to the
0N/A * group identified by the given <code>groupName</code>.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * This method is provided as a hook to plug-in some custom
0N/A * specific behavior. You might want to override this method
0N/A * in order to provide a different object naming scheme than
0N/A * that proposed by default by <code>mibgen</code>.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * This method is only meaningful if the MIB is registered
0N/A * in the MBeanServer, otherwise, it will not be called.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * The default implementation of this method is to return an ObjectName
0N/A * built from the given <code>defaultName</code>.
0N/A * </p>
0N/A *
0N/A * @param name The java-ized name of the SNMP group.
0N/A * @param oid The OID returned by getGroupOid() - in dot notation.
0N/A * @param defaultName The name by default generated by <code>
0N/A * mibgen</code>
0N/A *
0N/A * @return The ObjectName of the group identified by <code>name</code>
0N/A */
0N/A protected ObjectName getGroupObjectName(String name, String oid,
0N/A String defaultName)
0N/A throws MalformedObjectNameException {
0N/A return new ObjectName(defaultName);
0N/A }
0N/A
0N/A /**
0N/A * <p>
0N/A * Register an SNMP group and its metadata node in the MIB.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * This method is provided as a hook to plug-in some custom
0N/A * specific behavior. You might want to override this method
0N/A * if you want to set special links between the MBean, its metadata
0N/A * node, its OID or ObjectName etc..
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * If the MIB is not registered in the MBeanServer, the <code>
0N/A * server</code> and <code>groupObjName</code> parameters will be
0N/A * <code>null</code>.<br>
0N/A * If the given group MBean is not <code>null</code>, and if the
0N/A * <code>server</code> and <code>groupObjName</code> parameters are
0N/A * not null, then this method will also automatically register the
0N/A * group MBean with the given MBeanServer <code>server</code>.
0N/A * </p>
0N/A *
0N/A * @param groupName The java-ized name of the SNMP group.
0N/A * @param groupOid The OID as returned by getGroupOid() - in dot
0N/A * notation.
0N/A * @param groupObjName The ObjectName as returned by getGroupObjectName().
0N/A * This parameter may be <code>null</code> if the
0N/A * MIB is not registered in the MBeanServer.
0N/A * @param node The metadata node, as returned by the metadata
0N/A * factory method for this group.
0N/A * @param group The MBean for this group, as returned by the
0N/A * MBean factory method for this group.
0N/A * @param server The MBeanServer in which the groups are to be
0N/A * registered. This parameter will be <code>null</code>
0N/A * if the MIB is not registered, otherwise it is a
0N/A * reference to the MBeanServer in which the MIB is
0N/A * registered.
0N/A *
0N/A */
0N/A protected void registerGroupNode(String groupName, String groupOid,
0N/A ObjectName groupObjName, SnmpMibNode node,
0N/A Object group, MBeanServer server)
0N/A throws NotCompliantMBeanException, MBeanRegistrationException,
0N/A InstanceAlreadyExistsException, IllegalAccessException {
0N/A root.registerNode(groupOid,node);
0N/A if (server != null && groupObjName != null && group != null)
0N/A server.registerMBean(group,groupObjName);
0N/A }
0N/A
0N/A /**
0N/A * <p>
0N/A * Register an SNMP Table metadata node in the MIB.
0N/A * </p>
0N/A *
0N/A * <p>
0N/A * <b><i>
0N/A * This method is used internally and you should never need to
0N/A * call it directly.</i></b><br> It is used to establish the link
0N/A * between an SNMP table metadata node and its bean-like counterpart.
0N/A * <br>
0N/A * The group metadata nodes will create and register their
0N/A * underlying table metadata nodes in the MIB using this
0N/A * method. <br>
0N/A * The metadata nodes will be later retrieved from the MIB by the
0N/A * bean-like table objects using the getRegisterTableMeta() method.
0N/A * </p>
0N/A *
0N/A * @param name The java-ized name of the SNMP table.
0N/A * @param table The SNMP table metadata node - usually this
0N/A * corresponds to a <code>mibgen</code> generated
0N/A * object.
0N/A */
0N/A public abstract void registerTableMeta(String name, SnmpMibTable table);
0N/A
0N/A /**
0N/A * Returns a registered SNMP Table metadata node.
0N/A *
0N/A * <p><b><i>
0N/A * This method is used internally and you should never need to
0N/A * call it directly.
0N/A * </i></b></p>
0N/A *
0N/A */
0N/A public abstract SnmpMibTable getRegisteredTableMeta(String name);
0N/A
0N/A // --------------------------------------------------------------------
0N/A // PUBLIC METHODS
0N/A // --------------------------------------------------------------------
0N/A
0N/A /**
0N/A * Processes a <CODE>get</CODE> operation.
0N/A *
0N/A **/
0N/A // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
0N/A // for java-doc
0N/A //
0N/A public void get(SnmpMibRequest req) throws SnmpStatusException {
0N/A
0N/A // Builds the request tree: creation is not allowed, operation
0N/A // is not atomic.
0N/A
0N/A final int reqType = SnmpDefinitions.pduGetRequestPdu;
0N/A SnmpRequestTree handlers = getHandlers(req,false,false,reqType);
0N/A
0N/A SnmpRequestTree.Handler h = null;
0N/A SnmpMibNode meta = null;
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "get", "Processing handlers for GET... ");
0N/A }
0N/A
0N/A // For each sub-request stored in the request-tree, invoke the
0N/A // get() method.
0N/A for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
0N/A h = (SnmpRequestTree.Handler) eh.nextElement();
0N/A
0N/A // Gets the Meta node. It can be either a Group Meta or a
0N/A // Table Meta.
0N/A //
0N/A meta = handlers.getMetaNode(h);
0N/A
0N/A // Gets the depth of the Meta node in the OID tree
0N/A final int depth = handlers.getOidDepth(h);
0N/A
0N/A for (Enumeration rqs=handlers.getSubRequests(h);
0N/A rqs.hasMoreElements();) {
0N/A
0N/A // Invoke the get() operation.
0N/A meta.get((SnmpMibSubRequest)rqs.nextElement(),depth);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Processes a <CODE>set</CODE> operation.
0N/A *
0N/A */
0N/A // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
0N/A // for java-doc
0N/A //
0N/A public void set(SnmpMibRequest req) throws SnmpStatusException {
0N/A
0N/A SnmpRequestTree handlers = null;
0N/A
0N/A // Optimization: we're going to get the whole SnmpRequestTree
0N/A // built in the "check" method, so that we don't have to rebuild
0N/A // it here.
0N/A //
0N/A if (req instanceof SnmpMibRequestImpl)
0N/A handlers = ((SnmpMibRequestImpl)req).getRequestTree();
0N/A
0N/A // Optimization didn't work: we have to rebuild the tree.
0N/A //
0N/A // Builds the request tree: creation is not allowed, operation
0N/A // is atomic.
0N/A //
0N/A final int reqType = SnmpDefinitions.pduSetRequestPdu;
0N/A if (handlers == null) handlers = getHandlers(req,false,true,reqType);
0N/A handlers.switchCreationFlag(false);
0N/A handlers.setPduType(reqType);
0N/A
0N/A SnmpRequestTree.Handler h = null;
0N/A SnmpMibNode meta = null;
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "set", "Processing handlers for SET... ");
0N/A }
0N/A
0N/A // For each sub-request stored in the request-tree, invoke the
0N/A // get() method.
0N/A for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
0N/A h = (SnmpRequestTree.Handler) eh.nextElement();
0N/A
0N/A // Gets the Meta node. It can be either a Group Meta or a
0N/A // Table Meta.
0N/A //
0N/A meta = handlers.getMetaNode(h);
0N/A
0N/A // Gets the depth of the Meta node in the OID tree
0N/A final int depth = handlers.getOidDepth(h);
0N/A
0N/A for (Enumeration rqs=handlers.getSubRequests(h);
0N/A rqs.hasMoreElements();) {
0N/A
0N/A // Invoke the set() operation
0N/A meta.set((SnmpMibSubRequest)rqs.nextElement(),depth);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Checks if a <CODE>set</CODE> operation can be performed.
0N/A * If the operation cannot be performed, the method will raise a
0N/A * <CODE>SnmpStatusException</CODE>.
0N/A *
0N/A */
0N/A // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
0N/A // for java-doc
0N/A //
0N/A public void check(SnmpMibRequest req) throws SnmpStatusException {
0N/A
0N/A final int reqType = SnmpDefinitions.pduWalkRequest;
0N/A // Builds the request tree: creation is allowed, operation
0N/A // is atomic.
0N/A SnmpRequestTree handlers = getHandlers(req,true,true,reqType);
0N/A
0N/A SnmpRequestTree.Handler h = null;
0N/A SnmpMibNode meta = null;
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "check", "Processing handlers for CHECK... ");
0N/A }
0N/A
0N/A // For each sub-request stored in the request-tree, invoke the
0N/A // check() method.
0N/A for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
0N/A h = (SnmpRequestTree.Handler) eh.nextElement();
0N/A
0N/A // Gets the Meta node. It can be either a Group Meta or a
0N/A // Table Meta.
0N/A //
0N/A meta = handlers.getMetaNode(h);
0N/A
0N/A // Gets the depth of the Meta node in the OID tree
0N/A final int depth = handlers.getOidDepth(h);
0N/A
0N/A for (Enumeration rqs=handlers.getSubRequests(h);
0N/A rqs.hasMoreElements();) {
0N/A
0N/A // Invoke the check() operation
0N/A meta.check((SnmpMibSubRequest)rqs.nextElement(),depth);
0N/A }
0N/A }
0N/A
0N/A // Optimization: we're going to pass the whole SnmpRequestTree
0N/A // to the "set" method, so that we don't have to rebuild it there.
0N/A //
0N/A if (req instanceof SnmpMibRequestImpl) {
0N/A ((SnmpMibRequestImpl)req).setRequestTree(handlers);
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * Processes a <CODE>getNext</CODE> operation.
0N/A *
0N/A */
0N/A // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
0N/A // for java-doc
0N/A //
0N/A public void getNext(SnmpMibRequest req) throws SnmpStatusException {
0N/A // Build the request tree for the operation
0N/A // The subrequest stored in the request tree are valid GET requests
0N/A SnmpRequestTree handlers = getGetNextHandlers(req);
0N/A
0N/A SnmpRequestTree.Handler h = null;
0N/A SnmpMibNode meta = null;
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "getNext", "Processing handlers for GET-NEXT... ");
0N/A }
0N/A
0N/A // Now invoke get() for each subrequest of the request tree.
0N/A for (Enumeration eh=handlers.getHandlers();eh.hasMoreElements();) {
0N/A h = (SnmpRequestTree.Handler) eh.nextElement();
0N/A
0N/A // Gets the Meta node. It can be either a Group Meta or a
0N/A // Table Meta.
0N/A //
0N/A meta = handlers.getMetaNode(h);
0N/A
0N/A // Gets the depth of the Meta node in the OID tree
0N/A int depth = handlers.getOidDepth(h);
0N/A
0N/A for (Enumeration rqs=handlers.getSubRequests(h);
0N/A rqs.hasMoreElements();) {
0N/A
0N/A // Invoke the get() operation
0N/A meta.get((SnmpMibSubRequest)rqs.nextElement(),depth);
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Processes a <CODE>getBulk</CODE> operation.
0N/A * The method implements the <CODE>getBulk</CODE> operation by calling
0N/A * appropriately the <CODE>getNext</CODE> method.
0N/A *
0N/A */
0N/A // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
0N/A // for java-doc
0N/A //
0N/A public void getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat)
0N/A throws SnmpStatusException {
0N/A
0N/A getBulkWithGetNext(req, nonRepeat, maxRepeat);
0N/A }
0N/A
0N/A /**
0N/A * Gets the root object identifier of the MIB.
0N/A * <P>In order to be accurate, the method should be called once the
0N/A * MIB is fully initialized (that is, after a call to <CODE>init</CODE>
0N/A * or <CODE>preRegister</CODE>).
0N/A *
0N/A * @return The root object identifier.
0N/A */
0N/A public long[] getRootOid() {
0N/A
0N/A if( rootOid == null) {
0N/A Vector<Integer> list= new Vector<Integer>(10);
0N/A
0N/A // Ask the tree to do the job !
0N/A //
0N/A root.getRootOid(list);
0N/A
0N/A // Now format the result
0N/A //
0N/A rootOid= new long[list.size()];
0N/A int i=0;
0N/A for(Enumeration<Integer> e= list.elements(); e.hasMoreElements(); ) {
0N/A Integer val= e.nextElement();
0N/A rootOid[i++]= val.longValue();
0N/A }
0N/A }
0N/A return rootOid;
0N/A
0N/A }
0N/A
0N/A // --------------------------------------------------------------------
0N/A // PRIVATE METHODS
0N/A //---------------------------------------------------------------------
0N/A
0N/A /**
0N/A * This method builds the temporary request-tree that will be used to
0N/A * perform the SNMP request associated with the given vector of varbinds
0N/A * `list'.
0N/A *
0N/A * @param req The SnmpMibRequest object holding the varbind list
0N/A * concerning this MIB.
0N/A * @param createflag Indicates whether the operation allow for creation
0N/A * of new instances (ie: it is a SET).
0N/A * @param atomic Indicates whether the operation is atomic or not.
0N/A * @param type Request type (from SnmpDefinitions).
0N/A *
0N/A * @return The request-tree where the original varbind list has been
0N/A * dispatched to the appropriate nodes.
0N/A */
0N/A private SnmpRequestTree getHandlers(SnmpMibRequest req,
0N/A boolean createflag, boolean atomic,
0N/A int type)
0N/A throws SnmpStatusException {
0N/A
0N/A // Build an empty request tree
0N/A SnmpRequestTree handlers =
0N/A new SnmpRequestTree(req,createflag,type);
0N/A
0N/A int index=0;
0N/A SnmpVarBind var = null;
0N/A final int ver= req.getVersion();
0N/A
0N/A // For each varbind in the list finds its handling node.
0N/A for (Enumeration e= req.getElements(); e.hasMoreElements(); index++) {
0N/A
0N/A var= (SnmpVarBind) e.nextElement();
0N/A
0N/A try {
0N/A // Find the handling node for this varbind.
0N/A root.findHandlingNode(var,var.oid.longValue(false),
0N/A 0,handlers);
0N/A } catch(SnmpStatusException x) {
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers",
0N/A "Couldn't find a handling node for " +
0N/A var.oid.toString());
0N/A }
0N/A
0N/A // If the operation is atomic (Check/Set) or the version
0N/A // is V1 we must generate an exception.
0N/A //
0N/A if (ver == SnmpDefinitions.snmpVersionOne) {
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers", "\tV1: Throwing exception");
0N/A }
0N/A
0N/A // The index in the exception must correspond to the
0N/A // SNMP index ...
0N/A //
0N/A final SnmpStatusException sse =
0N/A new SnmpStatusException(x, index + 1);
0N/A sse.initCause(x);
0N/A throw sse;
0N/A } else if ((type == SnmpDefinitions.pduWalkRequest) ||
0N/A (type == SnmpDefinitions.pduSetRequestPdu)) {
0N/A final int status =
0N/A SnmpRequestTree.mapSetException(x.getStatus(),ver);
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers", "\tSET: Throwing exception");
0N/A }
0N/A
0N/A final SnmpStatusException sse =
0N/A new SnmpStatusException(status, index + 1);
0N/A sse.initCause(x);
0N/A throw sse;
0N/A } else if (atomic) {
0N/A
0N/A // Should never come here...
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers", "\tATOMIC: Throwing exception");
0N/A }
0N/A
0N/A final SnmpStatusException sse =
0N/A new SnmpStatusException(x, index + 1);
0N/A sse.initCause(x);
0N/A throw sse;
0N/A }
0N/A
0N/A final int status =
0N/A SnmpRequestTree.mapGetException(x.getStatus(),ver);
0N/A
0N/A if (status == SnmpStatusException.noSuchInstance) {
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers",
0N/A "\tGET: Registering noSuchInstance");
0N/A }
0N/A
0N/A var.value= SnmpVarBind.noSuchInstance;
0N/A
0N/A } else if (status == SnmpStatusException.noSuchObject) {
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers",
0N/A "\tGET: Registering noSuchObject");
0N/A }
0N/A
0N/A var.value= SnmpVarBind.noSuchObject;
0N/A
0N/A } else {
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getHandlers",
0N/A "\tGET: Registering global error: " + status);
0N/A }
0N/A
0N/A final SnmpStatusException sse =
0N/A new SnmpStatusException(status, index + 1);
0N/A sse.initCause(x);
0N/A throw sse;
0N/A }
0N/A }
0N/A }
0N/A return handlers;
0N/A }
0N/A
0N/A /**
0N/A * This method builds the temporary request-tree that will be used to
0N/A * perform the SNMP GET-NEXT request associated with the given vector
0N/A * of varbinds `list'.
0N/A *
0N/A * @param req The SnmpMibRequest object holding the varbind list
0N/A * concerning this MIB.
0N/A *
0N/A * @return The request-tree where the original varbind list has been
0N/A * dispatched to the appropriate nodes, and where the original
0N/A * OIDs have been replaced with the correct "next" OID.
0N/A */
0N/A private SnmpRequestTree getGetNextHandlers(SnmpMibRequest req)
0N/A throws SnmpStatusException {
0N/A
0N/A // Creates an empty request tree, no entry creation is allowed (false)
0N/A SnmpRequestTree handlers = new
0N/A SnmpRequestTree(req,false,SnmpDefinitions.pduGetNextRequestPdu);
0N/A
0N/A // Sets the getNext flag: if version=V2, status exception are
0N/A // transformed in endOfMibView
0N/A handlers.setGetNextFlag();
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
0N/A "getGetNextHandlers", "Received MIB request : " + req);
0N/A }
0N/A AcmChecker checker = new AcmChecker(req);
0N/A int index=0;
0N/A SnmpVarBind var = null;
0N/A final int ver= req.getVersion();
0N/A SnmpOid original = null;
0N/A // For each varbind, finds the handling node.
0N/A // This function has the side effect of transforming a GET-NEXT
0N/A // request into a valid GET request, replacing the OIDs in the
0N/A // original GET-NEXT request with the OID of the first leaf that
0N/A // follows.
0N/A for (Enumeration e= req.getElements(); e.hasMoreElements(); index++) {
0N/A
0N/A var = (SnmpVarBind) e.nextElement();
0N/A SnmpOid result = null;
0N/A try {
0N/A // Find the node handling the OID that follows the varbind
0N/A // OID. `result' contains this next leaf OID.
0N/A //ACM loop.
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getGetNextHandlers", " Next OID of : " + var.oid);
0N/A }
0N/A result = new SnmpOid(root.findNextHandlingNode
0N/A (var,var.oid.longValue(false),0,
0N/A 0,handlers, checker));
0N/A
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getGetNextHandlers", " is : " + result);
0N/A }
0N/A // We replace the varbind original OID with the OID of the
0N/A // leaf object we have to return.
0N/A var.oid = result;
0N/A } catch(SnmpStatusException x) {
0N/A
0N/A // if (isDebugOn())
0N/A // debug("getGetNextHandlers",
0N/A // "Couldn't find a handling node for "
0N/A // + var.oid.toString());
0N/A
0N/A if (ver == SnmpDefinitions.snmpVersionOne) {
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getGetNextHandlers",
0N/A "\tThrowing exception " + x.toString());
0N/A }
0N/A // The index in the exception must correspond to the
0N/A // SNMP index ...
0N/A //
0N/A throw new SnmpStatusException(x, index + 1);
0N/A }
0N/A if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
0N/A SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
0N/A SnmpMib.class.getName(),
0N/A "getGetNextHandlers",
0N/A "Exception : " + x.getStatus());
0N/A }
0N/A
0N/A var.setSnmpValue(SnmpVarBind.endOfMibView);
0N/A }
0N/A }
0N/A return handlers;
0N/A }
0N/A
0N/A // --------------------------------------------------------------------
0N/A // PROTECTED VARIABLES
0N/A // --------------------------------------------------------------------
0N/A
0N/A /**
0N/A * The top element in the Mib tree.
0N/A * @serial
0N/A */
0N/A protected SnmpMibOid root;
0N/A
0N/A
0N/A // --------------------------------------------------------------------
0N/A // PRIVATE VARIABLES
0N/A // --------------------------------------------------------------------
0N/A
0N/A /**
0N/A * The root object identifier of the MIB.
0N/A */
0N/A private transient long[] rootOid= null;
0N/A}