Introduction to snmp4j

Update 2010-09-22: Asynchronous fetch which is tested with Awaitility.

SNMP is a widely accepted technology and is used in to monitor a wide variety of devices, but as it turns out very few people (at least among java programmers) seems to know anything about how to build snmp based solutions.

This post will not discuss anything at all about SNMP theory, instead I will focus on how to dig right into building a simple solution using snmp4j. So, if your boss just told you to implement any type of snmp technology in a java product and you have no idea where to start, this post is for you. Unfortunately, it is impossible to cover all aspects of snmp4j (and honestly I have a lot to learn) but hopefully this will get you up and running quickly.

We will create a simple client and a simple agent (with support for snmp version 2c) that we will use in an automated test.

SNMP crash course
SNMP was created to be very simple but it is actually quite hard to grasp at first glance, but there are other great sources that covers this. However, while writing I realized that there are really a few things that you must know before you can really understand this post.

– MIB (Management Information Base), if you have no idea what this is it might be a good idea to briefly read about it at wikipedia. To make it easy, think of a MIB as a tree.

– OID (Object identifier), represents the key of a tree node and is used to GET/SET values in that node. An example is .1.3.6.1.2.1.1.1.

– Scalar object, a node with a single object value.

– MIB table, allows for grouping of values in a node and it can contain multiple rows.

Other resources
Wikipedia | snmplink.org | Beginners guide (short!)

Getting started
This example project is built using maven 2.2.1 and java6. It might also be good to download the snmp4j sources from http://www.snmp4j.org.
Snmp4j is the leading open source technology for snmp based java solutions and has an API for both snmp clients (or managers) and agents and is licensed under Apache 2.

Download example sources
All example code published is on github https://github.com/jrask/snmp-blog.

Building your first snmp client
A client (or snmp manager) is an application that queries an agent for information. It may also receive traps from agents but this will not be discussed here. Building a client is very easy and this is well described in the javadoc for the org.snmp4j.Snmp class.

Below is some code fragments from my class SimpleSnmpClient which is included in the project.

1. Start the Snmp session. If you forget the listen() method you will not get any answers because under the hood the communication is asynchronous and the listen() method listens for answers.

private void start() throws IOException {
        TransportMapping transport = new DefaultUdpTransportMapping();
	snmp = new Snmp(transport);
	// Do not forget this line!
	transport.listen();
}

2. To make is as simple as possible in my client I have a simple method which takes a single OID and returns the response from the agent as a String.

public String getAsString(OID oid) throws IOException {
	ResponseEvent event = get(new OID[]{oid});
	return event.getResponse().get(0).getVariable().toString();
}

3. This method is more generic and is capable of handling multiple OIDs. In a real application with lots of agents you would probably implement this asynchronously with a ResponseListener instead to prevent your threadpool from being exhausted.

public ResponseEvent get(OID oids[]) throws IOException {
	PDU pdu = new PDU();
 	for (OID oid : oids) {
 	     pdu.add(new VariableBinding(oid));
 	}
 	pdu.setType(PDU.GET);
 	ResponseEvent event = snmp.send(pdu, getTarget(), null);
	if(event != null) {
             return event;
	}
	throw new RuntimeException("GET timed out");
}

4. This method returns a Target, which contains information about where the data should be fetched and how.

private Target getTarget() {
	Address targetAddress = GenericAddress.parse(address);
	CommunityTarget target = new CommunityTarget();
	target.setCommunity(new OctetString("public"));
	target.setAddress(targetAddress);
	target.setRetries(2);
	target.setTimeout(1500);
	target.setVersion(SnmpConstants.version2c);
	return target;
}

Invoking the client
Using the code below and aim for i.e. one of your routers (if snmp is enabled) you will get som basic information about what kind of router it is.

SimpleSnmpClient client = new SimpleSnmpClient("udp:10.0.0.50/161");
String sysDescr = client.getAsString(new OID(".1.3.6.1.2.1.1.1.0"));
System.out.println(sysDescr);

That was really easy, and it is basically the same code you can find in the org.snmp4j.Snmp class so we haven´t provided anything new yet. Ok, so what if we would like to test this client without accessing the physical router? Thats next.

Creating a super simple snmp agent
If creating an snmp client is easy, creating an snmp agent (and knowing what you are doing) is a much harder. To help you get started, snmp4j provides two classes; BaseAgent which can be subclassed to build your custom agent, and TestAgent which is an executable class that extends BaseAgent. The problem once you start looking at these classes is that it is very difficult to understand what they do unless you are an snmp expert, so instead I have created an agent implementation that only contains the minimum functionality to support snmp v2c. Basically what I have done is to rip out the parts from TestAgent that I really did not need for this demo.

   // package and imports removed
/**
 * This Agent contains mimimal functionality for running a version 2c snmp agent.
 */
public class Agent extends BaseAgent {

	// not needed but very useful of course
	static {
		LogFactory.setLogFactory(new Log4jLogFactory());
	}

	private String address;

	public Agent(String address) throws IOException {

		// These files does not exist and are not used but has to be specified
		// Read snmp4j docs for more info
		super(new File("conf.agent"), new File("bootCounter.agent"),
				new CommandProcessor(
						new OctetString(MPv3.createLocalEngineID())));
		this.address = address;
	}

	/**
	 * We let clients of this agent register the MO they
	 * need so this method does nothing
	 */
	@Override
	protected void registerManagedObjects() {
	}

	/**
	 * 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));
	}

	/*
	 * Empty implementation
	 */
	@Override
	protected void addNotificationTargets(SnmpTargetMIB targetMIB,
			SnmpNotificationMIB notificationMIB) {
	}

	/**
	 * Minimal View based Access Control
	 *
	 * http://www.faqs.org/rfcs/rfc2575.html
	 */
	@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);
	}

	/**
	 * User based Security Model, only applicable to
	 * SNMP v.3
	 *
	 */
	protected void addUsmUser(USM usm) {
	}

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

	protected void unregisterManagedObjects() {
		// here we should unregister those objects previously registered...
	}

	/**
	 * The table of community strings configured in the SNMP
	 * engine's Local Configuration Datastore (LCD).
	 *
	 * We only configure one, "public".
	 */
	protected void addCommunities(SnmpCommunityMIB communityMIB) {
		Variable[] com2sec = new Variable[] {
				new OctetString("public"), // community name
				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);
	}
}

Testing the client agains the agent
Next we will hook the agent and client into a JUnit test to verify that it works as expected.

// standard in RFC-1213
static final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");

@BeforeClass
public static void setUp() throws Exception {
	agent = new Agent("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(MOScalarFactory.createReadOnly(sysDescr,"MySystemDescr"));

        // Setup the client to use our newly started agent
	client = new SimpleSnmpClient("udp:127.0.0.1/2001");
}

@AfterClass
public static void tearDown() throws Exception {
	agent.stop();
        client.stop();
}

@Test
public void verifySysDescr() throws IOException {
     assertEquals("MySystemDescr", client.getAsString(sysDescr));
}

/**
  * Uses asynchronous fetch and test it with Awaitility.
  */
@Test
public void verifySysDescrAsynch() throws Exception {
    final StringResponseListener listener = new StringResponseListener();
    client.getAsString(sysDescr, listener);
    await().until(callTo(listener).getValue(),equalTo("MySystemDescr"));
}

Adding MIB tables to your agent
You will probably not get away from creating a table so the final thing I will show is how we create and test this. To show how this is done I will first create a table in the agent and then write a test that will pull the data from the table and verify the contents.

To create the table I have created a utility class that can be found in the downloadable project.

// standard in RFC-1213
static final OID interfacesTable = new OID(".1.3.6.1.2.1.2.2.1");

@BeforeClass
public static void setUp() throws Exception {
	agent = new Agent("0.0.0.0/2001");
	agent.start();
	// Build a table. This example is taken from TestAgent and sets up
	// two physical interfaces
	MOTableBuilder builder = new MOTableBuilder(interfacesTable)
		.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_OCTET_STRING,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_GAUGE32,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_OCTET_STRING,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY)
		.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY)
		// Normally you would begin loop over you two domain objects here
		.addRowValue(new Integer32(1))
		.addRowValue(new OctetString("loopback"))
		.addRowValue(new Integer32(24))
		.addRowValue(new Integer32(1500))
		.addRowValue(new Gauge32(10000000))
		.addRowValue(new OctetString("00:00:00:00:01"))
		.addRowValue(new Integer32(1500))
		.addRowValue(new Integer32(1500))
		//next row
		.addRowValue(new Integer32(2))
		.addRowValue(new OctetString("eth0"))
		.addRowValue(new Integer32(24))
		.addRowValue(new Integer32(1500))
		.addRowValue(new Gauge32(10000000))
		.addRowValue(new OctetString("00:00:00:00:02"))
		.addRowValue(new Integer32(1500))
		.addRowValue(new Integer32(1500));

	agent.registerManagedObject(builder.build());

	// Setup the client to use our newly started agent
	client = new SimpleSnmpClient("udp:127.0.0.1/2001");
}

To test that we receive expected table data I have created a method getTableAsString() method in the SimpleSnmpClient class. This method uses org.snmp4j.util.TableUtils getTable() method.

/**
* Normally this would return domain objects or something else than this...
 */
public List> getTableAsStrings(OID[] oids) {
	TableUtils tUtils = new TableUtils(snmp, new DefaultPDUFactory());

	@SuppressWarnings("unchecked")
	List events = tUtils.getTable(getTarget(), oids, null, null);

	List> list = new ArrayList>();
	for (TableEvent event : events) {
		if(event.isError()) {
			throw new RuntimeException(event.getErrorMessage());
		}
		List strList = new ArrayList();
		list.add(strList);
		for(VariableBinding vb: event.getColumns()) {
			strList.add(vb.getVariable().toString());
		}
	}
	return list;
}

To get table contents we supply which table columns that we want to fetch. In my test I only supply three columns and this is done by adding a column number(starts with 1) after the table OID.

@Test
public void verifyTableContents() {

	// You retreive a table by suppling the columns of the table that
	// you need, here we use column 2,6 and 8 so we do not verify the complete
	// table
	List> tableContents = client.getTableAsStrings(new OID[]{
   		new OID(interfacesTable.toString() + ".2"),
    		new OID(interfacesTable.toString() + ".6"),
    		new OID(interfacesTable.toString() + ".8")});

	//and validate here
	assertEquals(2, tableContents.size());
	assertEquals(3, tableContents.get(0).size());
	assertEquals(3, tableContents.get(1).size());

	// Row 1
	assertEquals("loopback", tableContents.get(0).get(0));
	assertEquals("00:00:00:00:01", tableContents.get(0).get(1));
	assertEquals("1500", tableContents.get(0).get(2));
	// Row 2
	assertEquals("eth0", tableContents.get(1).get(0));
	assertEquals("00:00:00:00:02", tableContents.get(1).get(1));
	assertEquals("1500", tableContents.get(1).get(2));
}

That´s it, please have a look at the https://github.com/jrask/snmp-blog if anything is unclear. The javadoc at http://www.snmp4j.org/ is also very useful.
Good luck!

This Post Has 99 Comments

  1. Do you have an example using staticMOGroup?

  2. Sorry, I haven’t tried it. I had a quick look at the javadoc and it looks straightforward. I can see if I figure out how it works and add it to the blog soon.

  3. Do you have an example using a set method for different types of variables? like octet string, etc.

    Thanks!!

  4. This post is a perfect example of the SNMP4J usage. It discusses multiple details the developer must know to add SNMP support to the application. The alternative is http://friendlysnmp.org which gives a developer option to hook SNMP4J to the application in couple lines of code. This makes SNMP4J use really simple.

    The examples above is totaling >200 lines of code. It has standard required set of low level SNMP terminology and SNMP4J implementations. This is scary for the first time users/developers and keeps them away from SNMP. FriendlySNMP is a perfect wrapper which hides all SNMP low level details.

  5. Thanks a lot, Johan!

    I need snmp agent example which integrated with MySQL as backend data.
    Would you like to give me some examples for that ? That is urgent for me.

    Thank You,
    Maryana

  6. @Taila – Nope, perhaps after the vacation…

    @FriendlySNMP – A higher level of abstraction is interesting since most of us is unfamiliar with the SNMP domain. I will definitely take a look at this.

    @maryana – No I don´t, but you need to override MOScalar.set/get methods to manage the values.

  7. Thanks Johan, i already have an example; now i’m trying to send asynchronous snmp requests (in high volumes, to different devices) in a
    multithreaded environment, and i´m not sure how manage them. Any idea??

    Thanks in advance,
    Taila

  8. Great !!!!

    — Anish Sneh

  9. @Taila : Well, actually snmp4j is designed for this. Of course, I am not aware of your volumes but… Snmp.send() method has everything you need for this. This method can be called in a multithreaded environment. All you need to do is collect the responses.

    Snmp.send(PDU pdu,
    Target target,
    java.lang.Object userHandle,
    ResponseListener listener)

    /johan

  10. hi
    I write the client segment but it has an error
    the error is because the event.GetResponse() is null
    why I get this error?
    and what do I do to resolve this error?

  11. @rezvan – I suggest using the snmp4j mailing list for questions like this.

    This is likely because of a timeout (no answer from agent), and i think this is also well documented in the javadoc, check it out.

  12. hi
    I have a project with subject :Topology Discovery with using SNMP
    but the result of code not same as utility
    whY?
    I have one result of ipRouteNextHop but in the utility it show multiple Address
    Why?

  13. hi
    how can I find the agent’s IP Address on the interface?

  14. I need some example about use of the ipRouteNext object.
    OID for ipRouteNextHop is complicate and need Agent’s IP Addr on the inteface
    How can I get Agent’s IP Addr ?
    Would you like to give me some example ?

    That is urgent for me

  15. Thanks for this beginner tutorial!
    I used your MOTableBuilder class for an agent i created.

    But when I do a snmpwalk over the table OID, i get a the error message:

    “No more variables left in this MIB View (It is past the end of the MIB tree)”

    at the end of the walk.

    Do you have a hint for me?

    thanks in advance. :-)

  16. Its really really a great code for the better understanding of SNMP4j. I am so much thankful to you.

  17. Very Useful, Can you also publish some examples as to how an SNMP manager can receive traps and how they can be handled?

  18. Hey thanks for writing wonderful tutorial on SNMP.
    Here i have one question, how we create our own mib file , are we need to use any kindly tool or we need to create manually ?

    Thanks
    -hari

  19. I created it manually, but I suppose there must be some tools to help you.

  20. @hari, try googling for mib tools or mib designer, I know there are some tools out there but I have not used them

  21. @Simon; Unfortunately I will not have any time over in the nearest future to add this stuff but fortunately for you receiving and managing traps is really simple with snmp4j so you should not really have any problems. If you have any specific questions maybe I can answer them.

  22. import static org.hamcrest.Matchers.equalTo;
    import static org.hamcrest.Matchers.is;
    import static com.jayway.awaitility.Awaitility.*;

    i cann’t find these package.

    1. When you run “mvn clean install” these files should be downloaded. Is it a maven problem or an IDE problem?

  23. hello, I’m trying to compile the code and it’s really work in the Windows XP. But when I try to compile it in another Windows/Linux platform, it’s cannot get anything. Do this code can only be used in Windows platform? Thank you.

  24. It work on all platforms, I use Mac.

  25. Hello everybody, thanks Johan Rask the tutorial is really good. I need your help. I hv a final project about Network Management using Java. The problem is that I dont know how to start and the deadline is approaching. I copied the code above (exactly the same) and tried to compile but it’s giving me several errors. I’m using JBuilder IDE to facilitate and integrate all. The errors are:
    1. for (OID oid : oids) { (error: expected ‘;’ at this point)
    2. return pdu; (error: illegal start of expression)
    3. public List<List> getTableAsStrings(OID[] oids) { (error: identifier expected at the line)
    Please help me as soon as possible I’m really worried. Thank you very much in advance.

    1. Hi Sufei,
      Sounds like you need to attend a java course before doing your project ;-)
      Sorry, please ask a friend with some java and Intellij knowledge to help you, there should be no problem getting this to work. If there are Real problems, please explain them clearly.

  26. Hi Juhan,

    Great job, happy to see people like you’ll are still exist..
    i am new to SNMP, but can u please tell me if we want to discover router and switches what should we do? and can u post a basic code to access and get basic information our own router, so that can improve by looking @ that code.

    Thank you.

    1. Hi Nivan,
      Not sure about the discovery features of snmp4j, does not seem to be implemented ( http://www.snmp4j.org/html/prospect.html ) but it might be possible to build something, try google. You can probably find the mibs for your hardware on the internet, if you know the ip address, this code (from the example program) should get the system description. Note that snmp might not be enabled by default on your routers!
      SimpleSnmpClient client = new SimpleSnmpClient("udp:YourHardwareIp/161");
      String sysDescr = client.getAsString(new OID(".1.3.6.1.2.1.1.1.0"));
      System.out.println(sysDescr);

  27. Hi Juhan,

    Thanks for the advice.. I am working on it. If it goes fine i’ll share the code here with u’ll.

  28. Sounds good!

  29. anybody got this error..java.lang.NoSuchFieldError: LOCAL_ENGINE_ID

    public CommandProcessor(OctetString contextEngineID) {
    this.ownContextEngineIDs.add(contextEngineID);
    this.ownContextEngineIDs.add(MPv3.LOCAL_ENGINE_ID);

    MPv3 class
    public static final OctetString LOCAL_ENGINE_ID =
    OctetString.fromHexString(“80:00:00:00:06”);

  30. this error….java.lang.NoSuchFieldError: LOCAL_ENGINE_ID

    is caused by using the wrong lib version. pls refer to pow xml.

  31. Hello John,

    Do you have any tutorials or examples on how to set up a sub agent (AgentX)? If so, is there something special I need to do to setup the master agent. I need my sub agent to work and co-exist with the linux net-snmp on RHEL5.5. Any help is much appreciated.

    Regards,
    Mike

  32. hi:
    I have a question. I know snmp4j could handle multithread scense. I used MultiThreadedMessageDispatcher and snmp.send to do that, but if I want to hanle “walk” not “get” command how could I do??

  33. Hi all ,
    I have an urgent requirement to generate SNMP4j trap with MIB . I am new to SNMP. So can you please help me with this .

    Thanks and Regards,
    Rashma

  34. Hi,

    I have problem sending set pdu.
    here is my code:
    PDU pdu = new PDU();
    VariableBinding vb = new VariableBinding(oid);
    Variable v = new Integer32(value);
    vb.setVariable(v);
    pdu.addOID(vb);
    snmp.set(pdu, getTarget());
    from the snmp pkt I captured, the value is always NULL. Can anybody help? thx.

  35. Which MIB works with this? 1213?

  36. hi,
    I have a problem with the Agent class,
    Exception in thread “main” java.lang.NoSuchFieldError: level
    at org.apache.log4j.spi.RootLogger.setLevel(RootLogger.java:65)
    at org.apache.log4j.spi.RootLogger.(RootLogger.java:44)
    at org.apache.log4j.LogManager.(LogManager.java:69)
    at org.apache.log4j.Logger.getLogger(Logger.java:94)
    at org.snmp4j.log.Log4jLogFactory.createLogger(Log4jLogFactory.java:47)
    at org.snmp4j.log.LogFactory.getLogger(LogFactory.java:56)
    at org.snmp4j.smi.AbstractVariable.(AbstractVariable.java:77)
    at org.snmp4j.PDU.(PDU.java:207)
    at com.jayway.snmpblogg.Agent.main(Agent.java:379)
    Java Result: 1
    can you help me please

  37. It seems like snmp4j knows nothing about MOScalarFactory class.

    The error is on that line:

    agent.registerManagedObject(MOScalarFactory.createReadOnly(sysDescr,”MySystemDescr”);

    Is that an error or it’s just because SNMP4J library changed?

  38. You did not supply any error message?
    Since I am not using a snapshot version it should not be a problem with versions or have you updated to the latest snmp4j version?

    I can build an run this project successfully.
    https://github.com/jrask/snmp-blog

  39. Well, it’s just when I put in Eclipse that line:

    agent.registerManagedObject(MOScalarFactory.createReadOnly(sysDescr,”MySystemDescr”));

    Eclipse itself underscores it in red telling that “MOScalarFactory cannot be resolved”

    I have the following jars in my classpath:
    * snmp4j-1.11.jar
    * snmp4j-agent-1.4.jar

    As I can see in your git repository you use versions 1.10.1 and 1.3.1 respectively. So, my jars are newer.

    Anyway, can you tell me in which jar this class is located exactly?

    Thanks in advance.

  40. OK. My fault. MOScalarFactory it’s a class that you declare. Sorry x1000.

    Regards.

  41. unable to see cold start notification on trap receiver.

  42. Suppose I am implementing some functionality using snmp4j , after that my code went on to some linux environment . Does the machine need to install some snmp related rpm for some package or snmp4j is enough.

    1. Nope, you do not need anything else but the snmp4j jars.

  43. Buenísimo! ;-)

  44. hey, i have a mib text file but don’t know how to integrate it with snmpj4. Will I need to compile it to a java class? please help!

  45. Hello everyone.
    I had my last sem project and had to make a network monitor tool. I am using openBSD OS for my router and Windows 7 on client. Does i need to write agent code for openBSD? As openBSD has a default snmp agent “snmpd”.
    Plz reply

    Thanks:)http:)

  46. Hi,
    Thanks for the code. It works for me.
    Now, I want to do PDU set to fire snmp set command.
    But i am getting response as : No access

    RESPONSE[requestID=1322290496, errorStatus=No access(6), errorIndex=1, VBS[1.3.6.1.2.1.1.1.0 = 10; 1.3.6.1.2.1.1.1.0 = This is sparta]]

    i changed the permissions inside MOScalarFactory from MOAccessImpl.ACCESS_READ_ONLY to ACCESS_READ_WRITE.

    Still i am getting same error.

    1. Hi, I’ve followed the steps I’m having exactly the same problem. Now, I want to do PDU set to fire snmp set command.
      But i am getting response as : No access

      Still i am getting same error.

      1. I changed the addViews function, and it works.

        /**
        * Minimal View based Access Control
        *
        * http://www.faqs.org/rfcs/rfc2575.html
        */
        @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);

        vacm.addViewTreeFamily(new OctetString(“fullWriteView”), new OID(“1.3”),
        new OctetString(), VacmMIB.vacmViewIncluded,
        StorageType.nonVolatile);

        vacm.addViewTreeFamily(new OctetString(“fullNotifyView”), new OID(“1.3”),
        new OctetString(), VacmMIB.vacmViewIncluded,
        StorageType.nonVolatile);
        }

        Ernst

  47. Hi Johan

    Great example, thanks very much! Is your example code licenced under the Apache Licence aswell, like Snmp4j? Am I allowed to use your source in my project?

    Thanks,
    Beni

    1. Thanks! Be my guest!

  48. I extended DefaultMOTable and register the object of that class with the base agent. My base agent code looks exactly like yours. In the class which extends DefaultMOTable I have overriden public void update(MOScope updateScope, SubRequest request) method. In this method i add rows to the table model. For some reason the update method keeps getting called several times when i do an snmpwalk on the oid. Sometimes my snmpwalk times out. Is there a better way to write an agent which returns tabular pdus ? The contents of which will change with every request.

  49. @MozyLazy: you can fixed by add write privilege for agent follow command
    vacm.addViewTreeFamily(new OctetString(“fullReadView”), new OID(“1.3”),
    new OctetString(), VacmMIB.vacmViewIncluded, StorageType.nonVolatile);
    //add Write view for agent
    vacm.addViewTreeFamily(new OctetString(“fullWriteView”), new OID(“1.3”),
    new OctetString(), VacmMIB.vacmViewIncluded, StorageType.nonVolatile);

  50. Hi it’s a good tuturial. thank you.
    I wonder how can I handle attributs associated with OIDs to to set/get in response cleint requests
    please any help

  51. is there any difference between snmpv2 and snmpv3 in implementation of GETBULK method?

    i can not find .jar file of snmpv3 or its source file! where can i download it or buy it?

    Thanks so much

  52. Hello, I copied the same code and tried to run it. I’m having a null pointer exception in this line:
    return event.getResponse().get(0).getVariable().toString();
    into the “getAsString” function.
    I was debugging and event.response is null
    Please, could you help me?

    1. Hi,
      I need more info, what are you trying to do?
      Have you cloned the github repo?
      Are you running unit tests?

  53. Hey,

    I am trying to map a lan topology. I am trying to get my head around it. The simplest way seemed to be implementing SNMP. I’m unable to understand this, when I run an snmp client on my system, should i run an snmp agent on other systems,routers, bridges etc. on the network? If not, do you any solution as to how I can trace them all? Not using snmp? I am still a noob. So, your answer will be mighty helpful.

    Thanks.
    Cheers!

      1. Hi,

        I’m not very sure about the link, couldn’t find anything helpful. I’m trying to develop on my own to map a network topology and java seemed the way. I thought using snmp devices could be easily managed and detected. Any advice on that??

        Thanks

  54. Hi !
    First, thank you for your code and advices, I’m new in snmp protocol and this is a great tuto !

    When I pasted your code to test it, I’ve got an error in the test class, line: “await().until(callTo(listener).getValue(),equalTo(“MySystemDescr”));”

    The method callTo() is surrounded and I don’t get why?

    Someone could advise me please?

  55. Problem of callTo()
    “await().until(callTo(listener).getValue(),equalTo(“MySystemDescr”));”

    You should download the old version of Awaitility 1.2.1 in this URL
    http://code.google.com/p/awaitility/wiki/OldNews

    Then you recompiled again. I didn’t get any error and could run it without error.

    I can snmpwalk, snmpget,
    but cannot snmpset value to the OID even I change from READ_ONLY to READ_WRITE

    Any suggest?

  56. i was open that project in netbeans ide 7.0.1,
    how can i solve test file error,

    Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.7.2:test (default-cli) on project snmp-blogg: No tests were executed! (Set -DfailIfNoTests=false to ignore this error.) -> [Help 1]

    To see the full stack trace of the errors, re-run Maven with the -e switch.
    Re-run Maven using the -X switch to enable full debug logging.

    1. Not sure how you import it into netbeans. Can you run “mvn clean install” ?

      1. please tell me how can i open this project using netbeans 7.0+

  57. Please tell me how to add missing plugin open this project in netbeans
    “‘build.plugins.plugin.version’ for org.apache.maven.plugins:maven-compiler-plugin is missing.”

    1. Try your question at a netbeans forum under “How to open a maven project with netbeans”.

  58. Thank you very much for your post. If anyone can please give advice for develop switch port monitoring system using above post…….

  59. Thank you very much for your post… please anyone can help me to develop application for monitor cisco switch port using above post…

  60. How can you connect to the agent via the internet(wan)?

    Lets say you want to connect to a switch which has a private ip address. How do i connect to it?

    What do i have to change in this “client = new SimpleSnmpClient(“udp:127.0.0.1/2001″);” code?

    1. Of course you need access to the switch.

  61. I’m trying to link an OID to a simple variable in my code, but this variable may changed while the agent is started. So i’m looking for a way to update automatically the value link to that OID.

    Thanks

    1. Sorry, I do not understand the question?

  62. Hi, Sir Johan Rask

    Can you please tell me how I can use the SNMP4J? from where I have to start?
    I downloaded the following packages :
    snmp4j-2.3.1
    snmp4j-agent-2.3.0
    snmp4j-agentx-2.2.0
    SNMP4J-SMI
    but I don’t know where and how I start, I didn’t find any document that tell me what I use from that packages and if I must collect them in one directory, I am really confused and need help.
    What I really need is the steps of configure SNMP4J before start write the application ?
    Best Regards.

  63. Hello all,
    I need to list all the devices(system,router,switch) with its connection mode(wired or wireless) in my network, using Inetaddress, I can list all the ip addresses connected in my network, but I cant get other details(deice type,connection mode).
    I heard that it is possible with SNMP but I dont know how. Hope you give any idea regarding this,thanks in advance.

  64. Hello!

    First off, this has given me a great start in understanding how to implement SNMP into my client application. So thanks!

    I have the application working well when using OIDs that are packaged by default. I would like to be able to use a different MIB (e.g. Dell IDRAC-MIB-SMIv2.mib) but am having some difficulties. I have the smiManager created and the MIB loaded but when I try to create one of the Dell OIDs the returned values are always null.

    Thoughts? Do you have any examples of this?

    Thanks for any help you can provide!

    Sincerely,

    Beeker

  65. For future reference: NullPointerException stack

    Exception in thread “main” java.lang.NullPointerException
    at com.jayway.snmpblogg.SimpleSnmpClient.getAsString(SimpleSnmpClient.java:65)
    at com.eat24.Main.main(Main.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

    Is caused by the use of the incorrect SNMP version so check this line in SimpleSnmpClient
    target.setVersion(SnmpConstants.version2c);

    And change it to either version1 or version3, you’ll probably want version1 as it is the most common
    target.setVersion(SnmpConstants.version1);

  66. Hi Johan Rask! Thank you for this tutorial. This made some SNMP things clear in my head. However, do you know how we can create a row in the MOTable by sending a SET from the client ? I get how to write in a scalar but not how to CREATE a row ! And I need this for my project :/ All help will be really appreciated. Thanks

  67. Thank you!
    How can I add a new notification Target using addNotificationTargets() agent API when the agent is running? How can I get to that API from my code?
    Thanks

  68. Hello , thank you for this usefull project
    well my boss asked me almost the same and i could get informations using the snmp , but i’m wonderin how can i turn off a roter or a switch if i want ?
    i hope to get feedback from you :)
    my best regards

  69. bonjour , je suis entrain de développer une application de supervision de réseaux baser sur snmp et j’utilise snmp4j et j’ai pris comme base de mon travail votre exemple que vous avez publier mais j’ai un erreur que je comprends pas pouvait vous m’explique svp. voici l’erreur :
    a la ligne : await().until(callTo(listener).getValue(),equalTo(“MySystemDescr”));
    erreur:
    The method callTo(SnmpAgentAndClientTest.StringResponseListener) is undefined for the type SnmpAgentAndClientTest SnmpAgentAndClientTest.java /snmp ap/src/fonction line 111 Java Problem

  70. hey good stufff. Is there any example of how to write oid to an xml document

  71. It’s Really good post to understand SNMP and Implementation…Thanks to Johan

  72. Hello! What is the equivalent configuration in SNMP4J to simulate the following snmpwalk commands?

    snmpwalk -v2c -c public -m ALL [SNMP_HOST] .
    snmpwalk -v2c -c public -m ALL [SNMP_HOST] .iso.org.dod.internet.mgmt.mib-2.at.atTable.atEntry.atIfIndex.9.1

    I am sending two statements instead of one to verify that querying the whole tree (using dot) may be different from getting subtree based on other partial OID spec.

    greetings!

  73. I did a loop to scan one IP range. If the ip got a snmp device work fine but if the IP is empty or without snmp device the program fall. How I catch the excepcion and to continue the program?

    for (int i = 37; i < 40; i++) {

    System.out.println("ip x.x.x." + i);
    SNMPManager client = new SNMPManager("udp:192.168.1." + i + "/161");
    client.start();

    String sysDescr = client.getAsString(new OID(".1.3.6.1.2.1.1.5.0"));
    System.out.println(".1.3.6.1.2.1.1.5.0" + " – SysName: " + sysDescr);

    String sysDescr2 = client.getAsString(new OID(".1.3.6.1.2.1.1.1.0"));
    System.out.println(".1.3.6.1.2.1.1.1.0" + " – SysDec: " + sysDescr2);
    }

  74. I have a snmp agent on android, a snmp manager on desktop. I use the manager to retrieve info about the device. It works perfectly on lan. It doesnt on wan. Both the manager and android device have public ips. But snmp does not establish a connection on wan. Need help

  75. sir i am working snmp4j version 3 in java .a program is GETBULK operation.my server send the request for agent and agent accept the server request but agent cant respond my server.sir if you have any example please help me.

  76. How to send the response for agent to server.here above my code agent and server.please help

    Java Snmp GetBulk Agent version 3 program.

    public class JavaExample implements CommandResponder
    {
    public static final OID sysDescr = new OID(“1.3.6.1.2.1.1.1.0”);
    private Snmp snmp;
    String SHADESAuthPassword;
    OctetString contextEngineID;
    OctetString contextName;

    public JavaExample() throws IOException
    {
    MessageDispatcher dispatcher = new MessageDispatcherImpl();
    dispatcher.addMessageProcessingModel(new MPv3());
    snmp = new Snmp(dispatcher, new DefaultUdpTransportMapping(new UdpAddress(“127.0.0.1/162”), true));
    snmp.addCommandResponder(this);
    OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
    USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
    SecurityModels.getInstance().addSecurityModel(usm);

    OctetString securityName = new OctetString(“SHADES”);
    OID authProtocol = AuthMD5.ID;
    OID privProtocol = PrivDES.ID;
    OctetString authPassphrase = new OctetString(“SHADESAuthPassword”);
    OctetString privPassphrase = new OctetString(“SHADESPrivPassword”);

    snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));
    SecurityModels.getInstance().addSecurityModel(new TSM(localEngineId, false));
    snmp.listen();
    }

    @Override
    public void processPdu(CommandResponderEvent event)
    {
    System.out.println(“Received PDU “+event);
    ScopedPDU pdu = (ScopedPDU) event.getPDU();
    switch (pdu.getType())
    {
    case PDU.GETBULK:
    List responses = newArrayList(pdu.size());
    for (VariableBinding v : pdu.getVariableBindings())
    {
    OID oid = v.getOid();
    // Answer the usual SNMP requests
    if (sysDescr.equals(oid))
    {
    responses.add(new VariableBinding(oid, new OctetString(“My System description”)));
    }
    try
    {
    UserTarget comm = new UserTarget();
    comm.setSecurityLevel(event.getSecurityLevel());
    comm.setSecurityName(new OctetString(“SHADES”));
    comm.setVersion(SnmpConstants.version3);
    comm.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
    comm.setSecurityModel(event.getSecurityModel());
    comm.setAddress(event.getPeerAddress());

    ScopedPDU resp = new ScopedPDU();
    resp.setContextEngineID(pdu.getContextEngineID());
    resp.setContextName(pdu.getContextName());
    resp.setType(RESPONSE);
    resp.setVariableBindings(responses);
    resp.setRequestID(pdu.getRequestID());
    System.out.println(String.format(“Sending response PDU to %s/%s: %s”, event.getPeerAddress(), new String(event.getSecurityName()), resp));

    snmp.send(resp, comm);
    }
    catch (IOException e)
    {
    System.err.println(String.format(“Unable to send response PDU! (%s)”, e.getMessage()));
    }
    event.setProcessed(true);
    break;
    default:
    System.err.println(String.format(“Unhandled PDU type %s.”, PDU.getTypeString(pdu.getType())));
    break;
    }
    }

    public static void main(String[] args) throws IOException
    {
    JavaExample sc = new JavaExample();
    System.out.println(“Listening…”);
    int n = 300; // 5 min
    while (true)
    {
    try

    {
    Thread.sleep(1000);
    } catch (InterruptedException e)
    { }
    if (–n <= 0) break;
    }
    System.out.println("Stopping…");
    sc.snmp.close();
    }

    }

    Java Snmp GetBulk Server Version 3 Program.

    public class GetBulkServer
    {
    String SHADES;
    public static void main(String[] args) throws IOException, InterruptedException
    {

    Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
    OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
    USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
    SecurityModels.getInstance().addSecurityModel(usm);

    OctetString securityName = new OctetString("SHADES");
    OID authProtocol = AuthMD5.ID;
    OID privProtocol = PrivDES.ID;
    OctetString authPassphrase = new OctetString("SHADESAuthPassword");
    OctetString privPassphrase = new OctetString("SHADESPrivPassword");

    snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));
    SecurityModels.getInstance().addSecurityModel(new TSM(localEngineId, false));
    snmp.listen();

    UserTarget target = new UserTarget();
    target.setSecurityName(new OctetString("SHADES"));sir this is my code here issue is my serve
    target.setVersion(SnmpConstants.version3);
    target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);

    target.setAddress(new UdpAddress("127.0.0.1/162"));
    target.setTimeout(3000); //3s
    target.setRetries(1);

    ScopedPDU pdu = new ScopedPDU();
    pdu.setType(ScopedPDU.GETBULK);
    pdu.setContextEngineID(pdu.getContextEngineID());
    pdu.setContextName(pdu.getContextName());
    pdu.setMaxRepetitions(1);
    pdu.setNonRepeaters(0);

    pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1.0")));

    ResponseEvent responseEvent = snmp.send(pdu, target);
    PDU response = responseEvent.getResponse();

    if (response == null)
    {
    System.out.println("TimeOut…");
    }
    else
    {
    if (response.getErrorStatus() == PDU.noError)
    {
    Vector vbs = response.getVariableBindings();
    for (VariableBinding vb : vbs)
    {
    System.out.println(vb.getVariable().toString());
    }
    }
    else
    {
    System.out.println(“Error:” + response.getErrorStatusText());
    }
    }
    }
    }

  77. //somebody help to where i am mistake in this code.this is my GETBULK SNMP agent program my server send the request 162/127.0.0.1 this agent but this is not response.

    Java Snmp GetBulk Agent version 3 program.
    public class JavaExample implements CommandResponder
    {
    public static final OID sysDescr = new OID(“1.3.6.1.2.1.1.1.0”);
    private Snmp snmp;
    String SHADESAuthPassword;
    OctetString contextEngineID;
    OctetString contextName;
    public JavaExample() throws IOException
    {
    MessageDispatcher dispatcher = new MessageDispatcherImpl();
    dispatcher.addMessageProcessingModel(new MPv3());
    snmp = new Snmp(dispatcher, new DefaultUdpTransportMapping(new UdpAddress(“127.0.0.1/162”), true));
    snmp.addCommandResponder(this);
    OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
    USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
    SecurityModels.getInstance().addSecurityModel(usm);
    OctetString securityName = new OctetString(“SHADES”);
    OID authProtocol = AuthMD5.ID;
    OID privProtocol = PrivDES.ID;
    OctetString authPassphrase = new OctetString(“SHADESAuthPassword”);
    OctetString privPassphrase = new OctetString(“SHADESPrivPassword”);
    snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol,authPassphrase, privProtocol, privPassphrase));
    SecurityModels.getInstance().addSecurityModel(new TSM(localEngineId, false));
    snmp.listen();
    }
    @Override
    public void processPdu(CommandResponderEvent event)
    {
    System.out.println(“Received PDU “+event);
    ScopedPDU pdu = (ScopedPDU) event.getPDU();
    switch (pdu.getType())
    {
    case PDU.GETBULK:
    List responses = newArrayList(pdu.size());
    for (VariableBinding v : pdu.getVariableBindings())
    {
    OID oid = v.getOid();
    // Answer the usual SNMP requests
    if (sysDescr.equals(oid))
    {
    responses.add(new VariableBinding(oid, new OctetString(“My System description”)));
    }
    try
    {
    UserTarget comm = new UserTarget();
    comm.setSecurityLevel(event.getSecurityLevel());
    comm.setSecurityName(new OctetString(“SHADES”));
    comm.setVersion(SnmpConstants.version3);
    comm.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
    comm.setSecurityModel(event.getSecurityModel());
    comm.setAddress(event.getPeerAddress());
    ScopedPDU resp = new ScopedPDU();
    resp.setContextEngineID(pdu.getContextEngineID());
    resp.setContextName(pdu.getContextName());
    resp.setType(RESPONSE);
    resp.setVariableBindings(responses);
    resp.setRequestID(pdu.getRequestID());
    System.out.println(String.format(“Sending response PDU to %s/%s: %s”, event.getPeerAddress(), new String(event.getSecurityName()), resp));
    snmp.send(resp, comm);
    }
    catch (IOException e)
    {
    System.err.println(String.format(“Unable to send response PDU! (%s)”, e.getMessage()));
    }
    event.setProcessed(true);
    break;
    default:
    System.err.println(String.format(“Unhandled PDU type %s.”, PDU.getTypeString(pdu.getType())));
    break;
    }
    }
    public static void main(String[] args) throws IOException
    {
    JavaExample sc = new JavaExample();
    System.out.println(“Listening…”);
    int n = 300; // 5 min
    while (true)
    {
    try
    {
    Thread.sleep(1000);
    } catch (InterruptedException e)
    { }
    if (–n <= 0) break;
    }
    System.out.println("Stopping…");
    sc.snmp.close();
    }
    }

Leave a Reply

Close Menu