Performing SNMP walk and get operations using SNMP4j and Java

I was recently tasked with writing some java code to retrieve values, using SNMP and Java. Obviously, I turned to  the SNMP4j library, but to my dismay, the documentation was a little vague on how to simply achieve a GET and WALK operation, and I did not want to spend that much time writing code that was going to be used only once.

Thankfully Google provided some good examples, but as it happens often, none of them were quite complete, as to say, not exactly what I needed. So I am sharing my scripts that I used to achieve my objectives.

SNMP Get

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class SnmpGet {

    public SnmpGet() {
		// TODO Auto-generated constructor stub
	}


	/*
	 *  SnmpGet method

	 * return Response for given OID from the Device.

	 */

	public static String snmpGet(String strAddress, String community, String strOID, int snmpVersion)

	{

		String str="";

		try

		{

			OctetString community1 = new OctetString(community);

			strAddress= strAddress+"/" + 161;

			Address targetaddress = new UdpAddress(strAddress);

			TransportMapping transport = new DefaultUdpTransportMapping();

			transport.listen();

			CommunityTarget comtarget = new CommunityTarget();

			comtarget.setCommunity(community1);

			if(snmpVersion == 1){
				comtarget.setVersion(SnmpConstants.version1);
			}
			
			if(snmpVersion == 2){
				comtarget.setVersion(SnmpConstants.version2c);
			}
			
			if(snmpVersion == 3){
				comtarget.setVersion(SnmpConstants.version3);
			}
	

			comtarget.setAddress(targetaddress);

			comtarget.setRetries(2);

			comtarget.setTimeout(5000);

			PDU pdu = new PDU();

			ResponseEvent response;

			Snmp snmp;

			pdu.add(new VariableBinding(new OID(strOID)));

			pdu.setType(PDU.GET);

			snmp = new Snmp(transport);

			response = snmp.get(pdu,comtarget);

			if(response != null)

			{

				if(response.getResponse().getErrorStatusText().equalsIgnoreCase("Success"))

				{

					PDU pduresponse=response.getResponse();

					str=pduresponse.getVariableBindings().firstElement().toString();

					if(str.contains("="))

					{

						int len = str.indexOf("=");

						str=str.substring(len+1, str.length());

					}

				}

			}

			else

			{

				System.out.println("Feeling like a TimeOut occured ");

			}

			snmp.close();

		} catch(Exception e) { e.printStackTrace(); }

		System.out.println("Response="+str);

		return str;

	}
	
	
}

SNMP Walk

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
 
import org.snmp4j.CommunityTarget;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TreeUtils;
import org.snmp4j.util.TreeEvent;
 
public class Snmpwalk {  
  private String targetAddr;
  private String oidStr;
  private String commStr;
  private int snmpVersion;
  private String portNum;  
  private String usage;
  private ArrayList<String> results = new ArrayList<String>();
    
  Snmpwalk() throws IOException{
    // Set default value.
    targetAddr = null;
    oidStr = null;
    commStr = "public";
    snmpVersion = SnmpConstants.version2c;
    portNum =  "161";
    usage = "Usage: snmpwalk [-c communityName -p portNumber -v snmpVersion(1 or 2)] targetAddr oid";
  }
  
  public Snmpwalk(HashMap<String, String> values){
      targetAddr = values.get("ipaddr");
	  oidStr = values.get("oid");
	  commStr = values.get("communityString");
	  int tempVersion = Integer.parseInt(values.get("version"));
	  if(tempVersion == 1){
		  snmpVersion = SnmpConstants.version1;
	  }
	  if(tempVersion == 2){
		  snmpVersion = SnmpConstants.version2c;
	  }
	  if(tempVersion == 3){
		  snmpVersion = SnmpConstants.version3;
	  }
	  portNum =  "161";
  }
  
  public void doSnmpwalk() throws IOException  {
    Address targetAddress = GenericAddress.parse("udp:"+ targetAddr + "/" + portNum);
    TransportMapping transport = new DefaultUdpTransportMapping();
    Snmp snmp = new Snmp(transport);
    transport.listen();
  
    // setting up target
    CommunityTarget target = new CommunityTarget();
    target.setCommunity(new OctetString(commStr));
    target.setAddress(targetAddress);
    target.setRetries(3);
    target.setTimeout(1000 * 3);
    target.setVersion(snmpVersion);
  
    OID oid = null;
    try{
      oid = new OID(oidStr);
    }
    catch(RuntimeException ex){
      System.out.println("OID is not specified correctly.");
      System.exit(1);
    }
  
    TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory());      
    List<TreeEvent> events = treeUtils.getSubtree(target, oid);
    if(events == null || events.size() == 0){
      System.out.println("No result returned.");
      System.exit(1);
    }
    
    // Get snmpwalk result.
    for (TreeEvent event : events) {
      if(event != null){
        if (event.isError()) {
            System.err.println("oid [" + oid + "] " + event.getErrorMessage());
          }
            
        VariableBinding[] varBindings = event.getVariableBindings();
        if(varBindings == null || varBindings.length == 0){
          System.out.println("No result returned.");
        }
        for (VariableBinding varBinding : varBindings) {
          results.add(varBinding.getVariable().toString());
        }
      }
    }
    
    //print results
    for(String value: results){
    	System.out.println(value);
    }
    snmp.close();
  }
  
  public boolean isInResults(String value){
	  return results.contains(value);
  }
    
  
  private void checkAndSetArgs(String[] args){
    if(args.length < 2){
      System.err.println(usage);
      System.exit(1);
    }
    
    for (int i=0; i<args.length; i++){
      if("-c".equals(args[i])){
        commStr = args[++i]; 
      }
      else if ("-v".equals(args[i])){
        if(Integer.parseInt(args[++i]) == 1){
          snmpVersion = SnmpConstants.version1;
        }
        else {
          snmpVersion = SnmpConstants.version2c;
        }
      }
      else if ("-p".equals(args[i])){
        portNum = args[++i];
      }
      else{
        targetAddr = args[i++];
        oidStr = args[i];
      }
    }
    if(targetAddr == null || oidStr == null){
      System.err.println(usage);
      System.exit(1);
    }
  }

The above code has been tested to work with SNMP version 1 and 2, but should work with 3 as well.

Hope this helps…!

One thought on “Performing SNMP walk and get operations using SNMP4j and Java

Leave a Reply

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