Java Dynamic Management Kit 4.0 Tutorial

The SNMP Proxy Implementation

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.


Note -

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:


Example 9-3 Internal Initialization of the SNMP Proxy

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.


Example 9-4 Implementing a get Request in the Proxy

// 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: