The SNMP proxy is an extension of the abstract SnmpMibAgent which implements all of its abstract methods and can be instantiated. The proxy implements a synchronous SNMP manager that forwards the requests to the sub-agent. It does some error fixing for SNMPv2 requests but doesn't claim to be extensive. In any case, the SNMP proxy implementation is provided as an example and Sun Microsystems makes no claim as to its suitability for any particular usage.
The implementation of the example proxy does not support the getBulk request or the check method that allows the SNMP Walk request.
Before it is used, the proxy must be initialized with the hostname and port of the sub-agent. It uses this information to create SNMP parameter and SNMP peer objects. It then creates three SNMP sessions:
One for SNMPv1 requests
One for SNMPv2 requests
One for failed SNMPv2 requests that are retried as v1 requests
public void initializeProxy(String h, int p, String strOid, String name) throws UnknownHostException, SnmpStatusException { host = h; port = p; oid = strOid; mibName = name; // Initialization for SNMP v1 protocol. // SnmpParameters paramsV1 = new SnmpParameters("public", "private"); paramsV1.setProtocolVersion(SnmpDefinitions.snmpVersionOne); SnmpPeer peerV1 = new SnmpPeer(host, port); peerV1.setSnmpParam(paramsV1); sessionV1 = new SnmpSession("SnmpMibAgentImpl session V1"); sessionV1.setDefaultPeer(peerV1); // Using SNMP v1 protocol, errors are not fixed and // forwarded to the manager sessionV1.snmpOptions.setPduFixedOnError(false); // Initialization for SNMP v2 protocol. // SnmpParameters paramsV2 = new SnmpParameters("public", "private"); paramsV2.setProtocolVersion(SnmpDefinitions.snmpVersionTwo); SnmpPeer peerV2 = new SnmpPeer(host, port); peerV2.setSnmpParam(paramsV2); // If we get an error, we don't retry the request using SNMP v2, // but we try the request using SNMP v1 peerV2.setMaxRetries(0); sessionV2 = new SnmpSession("SnmpMibAgentImpl session V2"); sessionV2.setDefaultPeer(peerV2); // Using SNMP v2 protocol, the error is fixed // sessionV2.snmpOptions.setPduFixedOnError(true); // Initialization for SNMP v2 protocol simulated // using SNMP v1 protocol // sessionV2WithV1 = new SnmpSession("SnmpMibAgentImpl session V2 with V1"); sessionV2WithV1.setDefaultPeer(peerV1); // Simulating SNMP v2 with SNMP v1 protocol, the error is fixed. // sessionV2WithV1.snmpOptions.setPduFixedOnError(true); } |
The proxy exposes the public methods for handling requests, and then this algorithm for reducing errors is implemented by internal methods. Roughly, the proxy must determine the version of the incoming request and handle it as promised. Version 1 requests that timeout or fail are dropped, and v2 requests that timeout or fail are retried as v1 requests. Here we only show the code for implementing the get method.
// the exposed method public void get(Vector list, int version) throws SnmpStatusException { java.lang.System.out.println( "Proxy: Sending get request to SNMP sub-agent on " + host + " using port " + port); // Request using SNMP v1 protocol if (version == SnmpDefinitions.snmpVersionOne) { get(list, version, sessionV1); } // Request using SNMP v2 protocol. if (version == SnmpDefinitions.snmpVersionTwo) { get(list, version, sessionV2); } } // the internal implementation private void get(Vector list, int version, SnmpSession session) throws SnmpStatusException { SnmpVarbindList varbindlist = setVarBindList(list); try { request = session.snmpGet(null, varbindlist); } catch (SnmpStatusException e) { throw new SnmpStatusException(SnmpDefinitions.snmpRspGenErr, 0); } java.lang.System.out.println("\nRequest:\n" + request.toString()); boolean completed = request.waitForCompletion(10000); if (completed == false) { // If the completion failed using SNMP v1, we give up if (version == SnmpDefinitions.snmpVersionOne) { java.lang.System.out.println( "\nRequest timed out: check reachability of sub-agent."); return; } // If the completion failed using SNMP v2, we try again using v1 if (version == SnmpDefinitions.snmpVersionTwo) { get(list, SnmpDefinitions.snmpVersionOne, sessionV2WithV1); return; } } int errorStatus = request.getErrorStatus(); int errorIndex = request.getErrorIndex() + 1; if (errorStatus != SnmpDefinitions.snmpRspNoError) { // If there is an error status using v1, we throw an exception if (version == SnmpDefinitions.snmpVersionOne) { throw new SnmpStatusException(errorStatus, errorIndex); } // If there is an error status using v2, we try again using v1 if (version == SnmpDefinitions.snmpVersionTwo) { get(list, SnmpDefinitions.snmpVersionOne, sessionV2WithV1); return; } } result = request.getResponseVbList(); // Update the list parameter with the result Enumeration l = list.elements(); for (Enumeration e = result.elements(); e.hasMoreElements();) { SnmpVarBind varres = (SnmpVarBind) e.nextElement(); SnmpVarBind varbind = (SnmpVarBind) l.nextElement(); varbind.value = varres.value; } } |
The complete list of methods that a proxy must implement are the same as for MIB MBeans represented by instances of the SnmpMib class:
long[] getRootOid() - Gets the root object identifier of the MIB
void get(java.util.Vector list, int version) - Processes a get operation.
void getNext(java.util.Vector list, int version) - Processes a getNext operation.
void getBulk(java.util.Vector list, int nonRepeat, int maxRepeat, int version) - Processes a getBulk operation.
void check(java.util.Vector list) - Prepares a walk operation.
void set(java.util.Vector list, int version) - Processes a set operation.