Creating SNMP Agent (Server) in JAVA using SNMP4j

Author posted by Jitendra on Posted on under category Categories SNMP and tagged as Tags , with 29 Comments on Creating SNMP Agent (Server) in JAVA using SNMP4j

Creating SNMP Agent (Server) in JAVA using SNMP4j

In Previous article, we have seen that how to create SNMP client in JAVA using SNMP4j.

To create the Agent for SNMP which listens for the request should extend the abstract class BaseAgent.
The BaseAgent abstract class defines a framework for writing SNMP agents using the SNMP4J-Agent API. To implement your own SNMP agent, extend this class and implement the abstract methods defined by BaseAgent. The hook methods do not need any specific implementation. They only provide a defined mechanism to customize your agent.

Below Class is used to create the SNMP Agent:

package com.G2.SNMP.Server;

import java.io.File;
import java.io.IOException;

import org.snmp4j.TransportMapping;
import org.snmp4j.agent.BaseAgent;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.MOGroup;
import org.snmp4j.agent.ManagedObject;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.snmp.RowStatus;
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
import org.snmp4j.agent.mo.snmp.StorageType;
import org.snmp4j.agent.mo.snmp.VacmMIB;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;
import org.snmp4j.transport.TransportMappings;

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
	protected 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(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
	protected 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));
	}

}

This class is used to create ManagedObject which is used by the SNMP agent Class created above:

package com.G2.SNMP.Server;

import org.snmp4j.agent.mo.MOAccessImpl;
import org.snmp4j.agent.mo.MOScalar;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;

/**
 * This class creates and returns ManagedObjects
 * @author Shiva
 *
 */
public class MOCreator {
	public static MOScalar createReadOnly(OID oid,Object value ){
		return new MOScalar(oid,
				MOAccessImpl.ACCESS_READ_ONLY,
				getVariable(value));
	}

	private static Variable getVariable(Object value) {
		if(value instanceof String) {
			return new OctetString((String)value);
		}
		throw new IllegalArgumentException("Unmanaged Type: " + value.getClass());
	}

}

Below class tests that agent is working properly or not :

package com.G2.SNMP.Server;

import java.io.IOException;

import org.snmp4j.smi.OID;

import com.G2.SNMP.client.SNMPManager;

public class TestSNMPAgent {

	static final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");

	public static void main(String[] args) throws IOException {
		TestSNMPAgent client = new TestSNMPAgent("udp:127.0.0.1/161");
		client.init();
	}

	SNMPAgent agent = null;
	/**
	 * This is the client which we have created earlier
	 */
	SNMPManager client = null;

	String address = null;

	/**
	 * Constructor
	 *
	 * @param add
	 */
	public TestSNMPAgent(String add) {
		address = add;
	}

	private void init() throws IOException {
		agent = new SNMPAgent("0.0.0.0/2001");
		agent.start();

		// Since BaseAgent registers some MIBs by default we need to unregister
		// one before we register our own sysDescr. Normally you would
		// override that method and register the MIBs that you need
		agent.unregisterManagedObject(agent.getSnmpv2MIB());

		// Register a system description, use one from you product environment
		// to test with
		agent.registerManagedObject(MOCreator.createReadOnly(sysDescr,
				"This Description is set By ShivaSoft"));

		// Setup the client to use our newly started agent
		client = new SNMPManager("udp:127.0.0.1/2001");
		client.start();
		// Get back Value which is set
		System.out.println(client.getAsString(sysDescr));
	}

}

Output :

This Description is set By ShivaSoft

Possible run time errors :
Few of you may receive error like

“Exception in thread “main” java.lang.RuntimeException: java.net.BindException: Address already in use: Cannot bind”.

Solution: You are trying to listen on a local IP and port which is already in use by some other process (for example the operating system – if you use port 161 this is rather likely).

Try to use a different port (or IP address – but most services listen on all local IP addresses) or stop the process that is using it.

Related posts

29 thoughts on “Creating SNMP Agent (Server) in JAVA using SNMP4j”

  1. Thanks for the code.

    TestSNMPAgent gives following error:
    “start() has private access in com.G2.SNMP.client.SNMPManager”

    To resolve this can I make start as public in snmp client?

  2. Thanks, It Worked Successfully, Can you help me to create an SNMPV3 agent with security parameters using SNMP4j.

    Thanks
    Hanks

  3. Tried your code.

    It returns
    Exception in thread “main” java.lang.NullPointerException
    at SnmpHelp.SNMPManager.get(SNMPManager.java:87)
    at SnmpHelp.SNMPManager.getAsString(SNMPManager.java:70)
    at SnmpHelp.TestSNMPAgent.init(TestSNMPAgent.java:51)
    at SnmpHelp.TestSNMPAgent.main(TestSNMPAgent.java:13)
    Is the Agent not working properly?

    1. Check whether the OID supplied in our program is available on your SNMP agent. you can use MIB explorer to know about the OID of SNMP agent. Please refer previous articles of SNMP on this blog to know how to use MIB Explorer.

      Thanks,
      Jitendra Zaa

  4. Hello,

    I’m trying to use this code to create an snmp v1 agent.

    But in the following section of code :
    public SNMPAgent(String address) throws IOException {
    super(new File(“conf.agent”), new File(“bootCounter.agent”), new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
    this.address = address;
    }

    I can ‘t find out what to pass as argument instead of MPv3.createLocalEngineID(). I tried to use the class MPv1 but is does not have a createLocalEngineID().

    Can you help me ?

    Thanks,
    Olivier

    1. Hi Oliver,
      From your code snippets its seems that class MPv3 have a method named “createLocalEngineID()”, from wherever you are using the code, please check it again.. or it would be nice if you can post complete code.

      Thanks,
      Jitendra Zaa

  5. Hi Jitendra,

    Thanks for the quick answer.

    The code is what you posted on this page 🙂

    Your example creates a server using SNMP v3. I’d like to create the same server but for SNMP v1.

    My problem is to find out how can specify the version 1 instead of 3.

    Your code uses MPv3.createLocalEngineID(). So I thought I could use something similar with the class MPv1. But the MPv1 class does not have the createLocalEngineID() method :-(. So I don’t know to specify to use SNMP version 1.

    Thanks,
    Olivier

  6. Creating SNMP in a system and it should manage at least four systems.The coding should be written in java and executed with the help of uduntu 10.04. tell me some suggestions.

  7. hi,
    when i am trying to compile the above code i am getting the following error.

    Exception in thread “main” java.lang.NoSuchFieldError: LOCAL_ENGINE_ID
    at org.snmp4j.agent.CommandProcessor.(CommandProcessor.java:80)
    at server.SNMPAgent.(SNMPAgent.java:54)
    at server.TestSNMPAgent.init(TestSNMPAgent.java:37)
    at server.TestSNMPAgent.main(TestSNMPAgent.java:16)

    can you help

  8. Hi,

    Iam working with SNMP implementation in my java application.

    i found ur code and trying to implement in to my app.

    My task is i want to moniter my DBserver and check the connections and if any event happens it should make a alarm to my system.

    iam very new to this task and am trying to modify your code according to my task. I created sample MIB file and iam using the same OID for testing.

    while start running.. i got this error

    Exception in thread “main” java.lang.NullPointerException
    at org.snmp4j.agent.mo.DefaultMOTableModel.addRow(DefaultMOTableModel.java:39)
    at org.snmp4j.agent.mo.DefaultMOMutableTableModel.addRow(DefaultMOMutableTableModel.java:280)
    at org.snmp4j.agent.mo.DefaultMOTable.addRow(DefaultMOTable.java:174)
    at com.santhosh.SNMPAgent.addCommunities(SNMPAgent.java:88)
    at org.snmp4j.agent.BaseAgent.init(BaseAgent.java:169)
    at com.santhosh.SNMPAgent.start(SNMPAgent.java:171)
    at com.santhosh.TestAgent.init(TestAgent.java:43)
    at com.santhosh.TestAgent.main(TestAgent.java:16)

    please give some istructions to do my task. iam waiting for ur reply.

    thanks in advance..

    santhosh

    1. Hello, Has anybody answered you to your question? I also have to implement SNMP with own MIB, but every one shows just the simplest example without custom MIB file. Furthermore this code will not compile, because of “addRow”

    2. I’m not getting a NullPointerException myself but this seems to work for me:

      global variables:

      static final OID glbItem = new OID(“.1.3.6.1.2.1.99.1.0”);

      static final OID glbItem2 = new OID(“.1.3.6.1.2.1.99.2.0”);

      static final OID glbItem3 = new OID(“.1.3.6.1.2.1.99.3.0”);

      and then inside the main where I make the agent object:

      agent = new SNMPAgent(“127.0.0.1/161”);

      //agent.registerManagedObject();

      agent.registerManagedObject(MOCreator.createWritable(glbItem,

      “This Description is set By Ghaleb”));

      agent.registerManagedObject(MOCreator.createReadOnly(glbItem2,

      “#FG”));

      agent.registerManagedObject(MOCreator.createWritable(glbItem3,

      “-1”));

      agent.start();

      while(true);

      MOCreator.createWritable is a function I made:

      public static MOScalar createWritable(OID oid,Object value ){

      return new MOScalar(oid,

      MOAccessImpl.ACCESS_READ_WRITE,

      getVariable(value));

      }

  9. I want some information about SNMP4J. Is there any good book to learn SNMP4J? Or any links? I searched a lot in Google but i could not find it?

  10. Hello

    The code works fine, but I have some tasks I´m not able to find how:

    a) Another Manager should SET a new value to a OID. I get “no access” and where in the code I get a notification, if a OID is read or write?
    b) Some OID have not a static value. How can I update the Value of an OID (ManagedObject)?

    Maybe someone can help me?

    Thank you

  11. Hi

    I want to implement an SNMP agent as an Android activity. a simple agent that allows me to do set/get queries.
    Any help please
    thank you

  12. Can you please provide the content of conf.agent and bootCounter.agent file?.
    Please correct my understanding:
    – This program is used to create an SNMPAgent (SNMPv3) then in some where in the comments you are talking about installing snmp daemon. Is snmp daemon is needed to run this program ?

    What I’m looking for ?
    I need to implement my own SNMPv3 Agent (Secured Agent) which should capable of receiving v3 GET request. And then I need to parse the PDU and form the response PDU. How to accomplish this in your program?
    What is the difference between CommandProcessor and CommandResponder. In some example I’ve seen they use CommandResponder.processPDU to process the PDU then what is the use of CommandRseponder.

    Thanks in Advance,
    Arun V

  13. I’m trying to link an OID to a variable in my code, but the variable is changing while the agent run, I,m trying to find a way to update the MO when the variable is changing but I’m unable to do it, Hope you can help

    1. You need a Community (private one) with write permissions to write. Also you may wanna add this function to the MOCreator class:

      public static MOScalar createWritable(OID oid,Object value ){

      return new MOScalar(oid,

      MOAccessImpl.ACCESS_READ_WRITE,

      getVariable(value));

      }

      (That is if the object you want to change is a scalar)

  14. Dear Sir,

    I am using SNMP4J Agent and MIB for creating an
    application that will monitor disk usage starus, network bandwidth and
    intercat with camera on a PC/laptop and perform actions like Check
    Camera Status/Take picture/Videos, etc. I have gone through MIB tree and
    have found the relevant OID for disk space and networking.However, I am
    unable to find the OID of Camera in the MIB. Please let me know how do I
    get this.

    Regards,
    Sudhansu

  15. did 2 programs to be compiled in once r separtedly…please anyone confirm
    and how to set classpath for 2 jar
    ..pls help me anybody…

  16. Hi Jitendra,
    Thanks for this page. It helped me a lot in getting an idea about how to implement SnmpAgent. With some exploration I am able to create an agent which accepts my SNMP get request for non scalar OIDs also. Can you help me to understand how the SNMP GET NEXT or walk can be integrated for the SNMP agent.

Leave a Reply

Your email address will not be published. Required fields are marked *