/*
* 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.
/**
* 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.
/**
* 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 List
. /**
* Same behaviour than size() in {@link java.util.List}.
**/
public final int size() { return size;}
Same behaviour than add(long o) in List
. Any access to this method should be protected in a synchronized block on the LongList object. /**
* 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 List
. Any access to this method should be protected in a synchronized block on the LongList object. /**
* 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 count elements to the list.
Params: - at – index at which the elements must be inserted. The
first element will be inserted at this index.
- src – An array containing the elements we want to insert.
- from – Index of the first element from src that
must be inserted.
- count – number of elements to insert.
Any access to this method should be protected in a synchronized
block on the LongList object.
/**
* 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.
/**
* 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 List
. Any access to this method should be protected in a synchronized block on the LongList object. /**
* 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 List
. Any access to this method should be protected in a synchronized block on the LongList object. /**
* 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 List
. Any access to this method should be protected in a synchronized block on the LongList object. /**
* 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.
/**
* 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 length.
Params: - length – new minimal length requested.
Any call to this method must be protected by a synchronized
block on this LongList.
/**
* 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.
/**
* 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.
/**
* 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.
When compiling a SNMP MIB, among all the classes generated by
mibgen
, there is one which extends SnmpMib
for representing a whole MIB.
The class is used by the SNMP protocol adaptor as the entry point in
the MIB.
This generated class can be subclassed in your code in order to
plug in your own specific behaviour.
This API is a Sun Microsystems internal API and is subject
to change without notice.
/**
* 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.
/**
* Default constructor.
* Initializes the OID tree.
*/
public SnmpMib() {
root= new SnmpMibOid();
}
// --------------------------------------------------------------------
// POLYMORHIC METHODS
// --------------------------------------------------------------------
This callback should return the OID associated to the group
identified by the given groupName
.
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.
The default implementation of this method is to return the given
defaultOid
Params: - groupName – The java-ized name of the SNMP group.
- defaultOid – The OID defined in the MIB for that group
(in dot notation).
Returns: The OID of the group identified by groupName
,
in dot-notation.
/**
* <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;
}
This callback should return the ObjectName associated to the
group identified by the given groupName
.
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 mibgen
.
This method is only meaningful if the MIB is registered
in the MBeanServer, otherwise, it will not be called.
The default implementation of this method is to return an ObjectName
built from the given defaultName
.
Params: - name – The java-ized name of the SNMP group.
- oid – The OID returned by getGroupOid() - in dot notation.
- defaultName – The name by default generated by
mibgen
Returns: The ObjectName of the group identified by name
/**
* <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);
}
Register an SNMP group and its metadata node in the MIB.
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..
If the MIB is not registered in the MBeanServer, the
server
and groupObjName
parameters will be
null
.
If the given group MBean is not null
, and if the
server
and groupObjName
parameters are
not null, then this method will also automatically register the
group MBean with the given MBeanServer server
.
Params: - groupName – The java-ized name of the SNMP group.
- groupOid – The OID as returned by getGroupOid() - in dot
notation.
- groupObjName – The ObjectName as returned by getGroupObjectName().
This parameter may be
null
if the
MIB is not registered in the MBeanServer. - node – The metadata node, as returned by the metadata
factory method for this group.
- group – The MBean for this group, as returned by the
MBean factory method for this group.
- server – The MBeanServer in which the groups are to be
registered. This parameter will be
null
if the MIB is not registered, otherwise it is a
reference to the MBeanServer in which the MIB is
registered.
/**
* <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);
}
Register an SNMP Table metadata node in the MIB.
This method is used internally and you should never need to
call it directly.
It is used to establish the link
between an SNMP table metadata node and its bean-like counterpart.
The group metadata nodes will create and register their
underlying table metadata nodes in the MIB using this
method.
The metadata nodes will be later retrieved from the MIB by the
bean-like table objects using the getRegisterTableMeta() method.
Params: - name – The java-ized name of the SNMP table.
- table – The SNMP table metadata node - usually this
corresponds to a
mibgen
generated
object.
/**
* <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.
This method is used internally and you should never need to
call it directly.
/**
* 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 get
operation.
/**
* 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 set
operation.
/**
* 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 set
operation can be performed.
If the operation cannot be performed, the method will raise a
SnmpStatusException
.
/**
* 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 getNext
operation.
/**
* 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 getBulk
operation.
The method implements the getBulk
operation by calling
appropriately the getNext
method.
/**
* 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.
In order to be accurate, the method should be called once the
MIB is fully initialized (that is, after a call to init
or preRegister
).
Returns: The root object identifier.
/**
* 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'.
Params: - req – The SnmpMibRequest object holding the varbind list
concerning this MIB.
- createflag – Indicates whether the operation allow for creation
of new instances (ie: it is a SET).
- atomic – Indicates whether the operation is atomic or not.
- type – Request type (from SnmpDefinitions).
Returns: The request-tree where the original varbind list has been
dispatched to the appropriate nodes.
/**
* 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'.
Params: - req – The SnmpMibRequest object holding the varbind list
concerning this MIB.
Returns: 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.
/**
* 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
/**
* The top element in the Mib tree.
* @serial
*/
protected SnmpMibOid root;
// --------------------------------------------------------------------
// PRIVATE VARIABLES
// --------------------------------------------------------------------
The root object identifier of the MIB.
/**
* The root object identifier of the MIB.
*/
private transient long[] rootOid= null;
}