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. The SNMP proxy implementation is only 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 nor the check method.
Before it is used, the proxy must be initialized with the hostname and port of the sub-agent. It uses this information to create the corresponding SNMP parameter object and SNMP peer object. 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 implements this algorithm for reducing errors 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(SnmpMibRequest inRequest) throws SnmpStatusException { java.lang.System.out.println( "Proxy: Sending get request to SNMP sub-agent on " + host + " using port " + port); // Get the protocol version final int version = inRequest.getVersion(); // Request using SNMP v1 protocol if (version == SnmpDefinitions.snmpVersionOne) { get(inRequest, version, sessionV1); } // Request using SNMP v2 protocol. if (version == SnmpDefinitions.snmpVersionTwo) { get(inRequest, version, sessionV2); } } // the internal implementation private void get(SnmpMibRequest inRequest, int version, SnmpSession session) throws SnmpStatusException { // Construction of the SnmpVarBindList for the request. final SnmpVarbindList varbindlist = new SnmpVarbindList("SnmpMibAgentImpl varbind list", inRequest.getSubList() ); SnmpRequest request = null; 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(inRequest, SnmpDefinitions.snmpVersionOne, sessionV2WithV1); return; } } // Check the request result 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(inRequest, SnmpDefinitions.snmpVersionOne, sessionV2WithV1); return; } } // Get and display the returned values final SnmpVarbindList result = request.getResponseVarBindList(); java.lang.System.out.println("\nResult: \n" + result.varBindListToString()); // Update the list parameter with the result // The varbinds in the result list are expected to be in the same // order as in the request, so we can safely loop sequentially // over both lists. 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(SnmpMibRequest req) - Processes a get operation.
void getNext(SnmpMibRequest req) - Processes a getNext operation.
void getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat) - Processes a getBulk operation.
void check(SnmpMibRequest req) - Prepares a set operation.
void set(SnmpMibRequest req) - Processes a set operation.