2

I'm trying to develop a SNMPAgent that is able to simulate a SNMP device, using the existing snmp4j library.

public class SNMPAgent extends BaseAgent {

private String address;

/**
 *
 * @param address
 * @throws IOException
 */
public SNMPAgent(String address) throws IOException {

    /**
     * Creates a base agent with boot-counter, config file, and a
     * CommandProcessor for processing SNMP requests. Parameters:
     * "bootCounterFile" - a file with serialized boot-counter information
     * (read/write). If the file does not exist it is created on shutdown of
     * the agent. "configFile" - a file with serialized configuration
     * information (read/write). If the file does not exist it is created on
     * shutdown of the agent. "commandProcessor" - the CommandProcessor
     * instance that handles the SNMP requests.
     */
    super(new File("./conf.agent"), new File("./bootCounter.agent"),
            new CommandProcessor(
                    new OctetString(MPv3.createLocalEngineID())));
    this.address = address;
}

/**
 * Adds community to security name mappings needed for SNMPv1 and SNMPv2c.
 */
@Override
public void addCommunities(SnmpCommunityMIB communityMIB) {
    Variable[] com2sec = new Variable[] { new OctetString("public"),
            new OctetString("cpublic"), // security name
            getAgent().getContextEngineID(), // local engine ID
            new OctetString("public"), // default context name
            new OctetString(), // transport tag
            new Integer32(StorageType.nonVolatile), // storage type
            new Integer32(RowStatus.active) // row status
    };
    MOTableRow row = communityMIB.getSnmpCommunityEntry().createRow(
            new OctetString("public2public").toSubIndex(true), com2sec);
    communityMIB.getSnmpCommunityEntry().addRow((SnmpCommunityMIB.SnmpCommunityEntryRow) row);

}

/**
 * Adds initial notification targets and filters.
 */
@Override
protected void addNotificationTargets(SnmpTargetMIB arg0,
                                      SnmpNotificationMIB arg1) {
    // TODO Auto-generated method stub

}

/**
 * Adds all the necessary initial users to the USM.
 */
@Override
protected void addUsmUser(USM arg0) {
    // TODO Auto-generated method stub

}

/**
 * Adds initial VACM configuration.
 */
@Override
public void addViews(VacmMIB vacm) {
    vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c, new OctetString(
                    "cpublic"), new OctetString("v1v2group"),
            StorageType.nonVolatile);

    vacm.addAccess(new OctetString("v1v2group"), new OctetString("public"),
            SecurityModel.SECURITY_MODEL_ANY, SecurityLevel.NOAUTH_NOPRIV,
            MutableVACM.VACM_MATCH_EXACT, new OctetString("fullReadView"),
            new OctetString("fullWriteView"), new OctetString(
                    "fullNotifyView"), StorageType.nonVolatile);

    vacm.addViewTreeFamily(new OctetString("fullReadView"), new OID("1.3"),
            new OctetString(), VacmMIB.vacmViewIncluded,
            StorageType.nonVolatile);

}

/**
 * Unregister the basic MIB modules from the agent's MOServer.
 */
@Override
protected void unregisterManagedObjects() {
    // TODO Auto-generated method stub

}

/**
 * Register additional managed objects at the agent's server.
 */
@Override
protected void registerManagedObjects() {
    // TODO Auto-generated method stub

}

protected void initTransportMappings() throws IOException {
    transportMappings = new TransportMapping[1];
    Address addr = GenericAddress.parse(address);
    TransportMapping tm = TransportMappings.getInstance()
            .createTransportMapping(addr);
    transportMappings[0] = tm;
}

/**
 * Start method invokes some initialization methods needed to start the
 * agent
 *
 * @throws IOException
 */
public void start() throws IOException {

    init();
    // This method reads some old config from a file and causes
    // unexpected behavior.
    // loadConfig(ImportModes.REPLACE_CREATE);
    addShutdownHook();
    getServer().addContext(new OctetString("public"));
    finishInit();
    run();
    sendColdStartNotification();
}

/**
 * Clients can register the MO they need
 */
public void registerManagedObject(ManagedObject mo) {
    try {
        server.register(mo, null);
    } catch (DuplicateRegistrationException ex) {
        throw new RuntimeException(ex);
    }
}


public void unregisterManagedObject(MOGroup moGroup) {
    moGroup.unregisterMOs(server, getContext(moGroup));
}

}

It currently works when I try to register a new oid with a given value

        SNMPAgent testAgent = new SNMPAgent(ip+"/"+port);
    testAgent.start();
    testAgent.unregisterManagedObject(testAgent.getSnmpv2MIB());
    MOScalar editableScalar = MOCreator.createScalarEditable(new OID(oidval),  new Integer32(48));
    testAgent.registerManagedObject(editableScalar);

and also when I want to query the same ( and already registered ) oid

        Optional<PDU> get = sender.sendGet(community, ip, port, "1.3.6.1.4.1.2011.2.1.2.1", 2, 1000L);

My trouble is that the set fuction, which should override the existing value within the oid, doesn't work. I'm using it as follows:

    Integer32 intVal = new Integer32(28);
    Optional<PDU> set = sender.sendSet(community, ip, port, "1.3.6.1.4.1.2011.2.1.2.1", intVal, 2, 1000L);

The sender object is instantiated from the SNMPSender class. The crucial part of the method sendSet is the following:

        CommunityTarget comtarget = new CommunityTarget();
    comtarget.setCommunity(new OctetString(community));
    comtarget.setVersion(snmpVersion);
    comtarget.setAddress(new UdpAddress(ipAddress + "/" + port));
    comtarget.setRetries(retries);
    comtarget.setTimeout(timeoutMillis);

    PDU pdu = new PDU();
    pdu.add(new VariableBinding(new OID(oidValue),setValue));
    pdu.setType(PDU.SET);


    ResponseEvent response = snmp.set(pdu, comtarget);

Last of all, the snmp is an object from the calss Snmp. And what does the .set method do?

  public ResponseEvent set(PDU pdu, Target target) throws IOException {
pdu.setType(PDU.SET);
return send(pdu, target);

}

It calls the same send method that is called when performing a get, and even with deep debugging I can't figure out how to make it work.

We tried the SNMPSender on a real node and it worked, so I'm assuming something must be wrong with the SNMPAgent. Also when inspecting the ResponseEvent response object, the response parameter is null

Pierangelo Calanna
  • 572
  • 1
  • 3
  • 17

0 Answers0