0
votes

I am new to snmp and using snmp4j to create an snmp agent.My java application needs to listen to snmp request and query the db based on the incoming oid and send a response back. I have a src code for snmp agent. But how does the agent query the db based on the incoming oid? Do I need to register all oids in my db as managed objects in the agent so the agent can do the look up when the request arrives? or in other words, how do i point to my datastore/db from the agent?

this is the code i am using.

http://shivasoft.in/blog/java/snmp/creating-snmp-agent-server-in-java-using-snmp4j/

`List oidList = impl.getOidList(); //get data from db

for (Oid oid : oidList) {

   agent.registerManagedObject(MOScalarFactory.createReadOnly(new OID(
                oid.getOid()), oid.getValue()));

    }'

I am trying to register the managed objects with data in db. Is this correct? I am getting duplicate registration exception on second row though the oid is unique.

`.1.3.6.1.4.1.1166.1.6.1.2.2.1.3.1.1

.1.3.6.1.4.1.1166.1.6.1.2.2.1.3.1.2`

I dont think this is the right way because what if the db is huge? Any help/tips are greatly appreciated.

2
I found a work around. I am using the command processor to intercept the incoming get request and hopefully i can have a custom method to populate data from db and send it back in the response. i am still working on that part.yonikawa
need help !!..i succcesfully created SNMP agent using snmp4j libraray Here is the refrence code(jitendrazaa.com/blog/java/snmp/…). My query is how can i make this agent to run always to listen all incoming OIDs from manager.??Balwinder SIngh

2 Answers

3
votes

Problem

You get org.snmp4j.agent.DuplicateRegistrationException because there can be only one ManagedObject in the ContextScope. Each registration assigns ManagedObject value to the MOContextScope. Second registration tries to set second object to the contextScope. The scope is already filled and thus exception is thrown. Althow each scalar value SHOULD end up with .0. You may check any MIB browser like iReasoning and pick any value. If this value is scalar - trailing zero is appended automaticaly despite the fact it is not mentioned in MIB-file. So the most "correct" way is to use 4.1 solution.

Solution 1 - own MOScalar

Write your own MOScalar. With tinier bounds. You should overwrite getLowerBound, getUpperBound, isLowerIncluded, isUpperIncluded to get separate contextScopes for your objects.

I would suggest to return Scalar OID every time and include both boundaries. Upper and lower boundaries better return same OID you've settled.

Solution 2 - own MOServer

Write your own MOServer. With blackJack and others... Mostly you can simply copypaste code despite this one

private SortedMap<MOScope, ManagedObject> registry;

It should look like this

private SortedMap<MOScope, Set<ManagedObject>> registry;

And it would affect registration, unregistration and other logic. DefaultMOServer - 678 lines incl. comments. In fact you should fix several classes:

query.matchesQuery(object)

private boolean matchesQuery(MOQuery query, ManagedObject object) {
    if ((query.matchesQuery(object)) && object.getScope().isOverlapping(query.getScope()))
        if (object instanceof MOScalar) {
            MOScalar moScalar = (MOScalar) object;
            return query.getLowerBound().compareTo(moScalar.getID()) <= 0 &&
                    query.getUpperBound().compareTo(moScalar.getID()) >= 0;
        } else {
            return true;
        }

    return false;
}

protected void fire...Event(ManagedObject objects, MOQuery query) {

protected void fire...Event(Set<ManagedObject> objects, MOQuery query) {
        if (lookupListener != null) {
            for (ManagedObject mo : objects) {

ManagedObject other = lookup(new DefaultMOQuery(contextScope));

Set<ManagedObject> other = lookup(new DefaultMOQuery(contextScope), false);

And so on...

Solution 3 - Tables

Use table rows. You can add a table and append rows.

You would be able to access cells as the

<tableEntryOID>.<columnSubID>.<rowIndexOID>

You may use this question as tutorial.

Solution 4 - OIDs fixup

Make you oid's use different contextScopes.

Solution 4.1 Adding trailing zero

    agent.registerManagedObject(
            MOScalarFactory.createReadOnly(
                    new OID(oid.getOid()).successor(),
                    oid.getValue()
            )
    );

This will append .0 to the same-level properties.

snmpget -v2c -c public localhost:2001 oid.getOid().0

Also any MIBbrowser will append .0 to each scalar oid defined in the MIB-file. You may check it with iReasoning as the most popular browser. Even hrSystemUptime (.1.3.6.1.2.1.25.1.1 - see left bottom) is requested as hrSystemUptime.0 (.1.3.6.1.2.1.25.1.1.0) on the top.

Solution 4.2 Separate OID at the base.

static final OID sysDescr1 = new OID("1.3.6.1.4.1.5.6.1.8.9"),
        sysDescr2 = new OID("1.3.6.1.4.1.5.6.2.2.5");

Fix the database OIDs to get separate contextScopes.

In addition

You can try reading SNMP4J-Agent-Instrumentation-Guide.pdf. This didn't helped me btw.
You can attach the sources to your IDE to read about zero trailer and other nuances. This helped me a lot to get more info about DefaultMOServer.

Correct pom.xml import to get latest version

    <repositories>
        <repository>
            <id>SNMP4J</id>
            <url>https://oosnmp.net/dist/release/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.snmp4j</groupId>
            <artifactId>snmp4j-agent</artifactId>
            <version>2.3.2</version>
        </dependency>
    </dependencies>
1
votes

First of all, OIDs do start with a number - not a dot. The syntax you are using is from NET-SNMP and is non-standard.

Second, please read the SNMP4J-Agent-Instrumentation-Guide.pdf document that describes in detail how you can instrument an agent for a MIB. You got the duplicate registration exception, because you registered a scalar as a sub-tree. Scalar OIDs have to end with the ".0" instance suffix.

Using the CommandResponder interface is sort of reinventing the wheel. You will most likely never manage to implement a secure and standard conform SNMP agent when you start from scratch. Using SNMP4J-Agent and its instrumentation hooks will save you a lot of work and trouble.