introduction
SNMP (Simple Network Management Protocol) is a standard protocol for network device management. This article will explain how to use Java and SNMP4J (an open source SNMP implementation library) for SNMP operations. We will demonstrate how to initialize SNMP, create PDUs, send SNMP requests, and process responses by writing the SnmpUtil class.
Environmental preparation
First, make sure you have added the SNMP4J dependency. Dependency management can be performed through Maven or Gradle.
<dependency> <groupId>org.snmp4j</groupId> <artifactId>snmp4j</artifactId> <version>2.8.6</version> </dependency>
implementation 'org.snmp4j:snmp4j:2.8.6'
SnmpUtil class overview
The following is the overall structure of writing the SnmpUtil class. This class provides static methods to initialize SNMP, create SNMP targets, create PDUs, send SNMP requests, and process responses.
Static initialization of the class
We use static blocks here to initialize SNMP objects, ensuring that the entire application life cycle is initialized only once.
public class SnmpUtil { private static final Logger log = (); private static Snmp snmp = null; static { try { initSnmp(); } catch (IOException e) { ("SNMP initialization failed", e); } } private static synchronized void initSnmp() throws IOException { if (snmp == null) { MessageDispatcher messageDispatcher = new MessageDispatcherImpl(); (new MPv1()); (new MPv2c()); OctetString localEngineID = new OctetString(()); USM usm = new USM(().addDefaultProtocols(), localEngineID, 0); UsmUser user = new UsmUser(new OctetString("SNMPV3"), , new OctetString("authPassword"), , new OctetString("privPassword")); ((), user); (new MPv3(usm)); TransportMapping<?> transportMapping = new DefaultUdpTransportMapping(); snmp = new Snmp(messageDispatcher, transportMapping); (); } } }
Create a target
Write the createTarget method to create SNMP targets, supporting SNMP v1, v2c, and v3 versions.
private static Target createTarget(int version, String community, String ipAddress, int port) { Target target = null; if (!(version == SnmpConstants.version3 || version == SnmpConstants.version2c || version == SnmpConstants.version1)) { ("Parameter version exception"); return target; } if (version == SnmpConstants.version3) { target = new UserTarget(); (SecurityLevel.AUTH_PRIV); (new OctetString("SNMPV3")); } else { target = new CommunityTarget(); ((CommunityTarget) target).setCommunity(new OctetString(community)); if (version == SnmpConstants.version2c) { (SecurityModel.SECURITY_MODEL_SNMPv2c); } } (version); (("udp:" + ipAddress + "/" + port)); (5); (3000); return target; }
Create a PDU
Write a createPDU method to create a Protocol Data Unit (PDU), which is the basic component of SNMP messages.
private static PDU createPDU(int version, int type, String oid) { PDU pdu = null; if (version == SnmpConstants.version3) { pdu = new ScopedPDU(); } else { pdu = new PDUv1(); } (type); (new VariableBinding(new OID(oid))); return pdu; } private static PDU createPDU(int version, int type, List<String> oids) { PDU pdu = null; if (version == SnmpConstants.version3) { pdu = new ScopedPDU(); } else { pdu = new PDU(); } (type); for (String oid : oids) { (new VariableBinding(new OID(oid))); } return pdu; }
Send an SNMP request
Write the snmpWalk method to send GETNEXT requests and process responses. Note here that it is not necessarily GETNEXT requests, but GET requests can also be used. The difference between the two is therefore the name implies. One is to get the next oid and the other is to get yourself
public static PDU snmpWalk(String ipAddr, int port, int version, String community, String oid) { try { Target target = createTarget(version, community, ipAddr, port); PDU pdu = createPDU(version, , oid); ResponseEvent responseEvent = (pdu, target); PDU response = (); return response; } catch (IOException e) { ("SNMP send request failed", e); return new PDU(); } } public static PDU snmpWalk(String ipAddr, int port, int version, String community, List<String> oids) { try { Target target = createTarget(version, community, ipAddr, port); PDU pdu = createPDU(version, , oids); ResponseEvent responseEvent = (pdu, target); PDU response = (); return response; } catch (IOException e) { ("SNMP send request failed", e); return new PDU(); } }
Processing SNMP responses
Write the snmpWalkAll and snmpWalkSegment methods to process continuous SNMP responses until the end of the MIB is reached.
public static List<VariableBinding> snmpWalkAll(String ipAddr, int port, int version, String community, String startOid) { List<VariableBinding> results = new ArrayList<>(); Target target = createTarget(version, community, ipAddr, port); PDU pdu = new PDU(); (new VariableBinding(new OID(startOid))); while (true) { try { (); ResponseEvent responseEvent = (pdu, target); PDU response = (); if (response != null && () > 0 && () == 0) { if ((0).getVariable().toString().equals("endOfMibView")) { break; } (()); (null); // Reset request ID for the next request (0); // Remove the old request ((0)); // Add the new request based on the last response } else { break; } } catch (IOException e) { ("SNMP send request failed", e); break; } } return results; } // ...See the full code for other codes
Complete code
import org.; import org.; import org.snmp4j.*; import org.; import org..MPv1; import org..MPv2c; import org..MPv3; import org.; import org..*; import org.; import org.; import org.; import org.; import org.; import ; import ; import ; public class SnmpUtil { private static final Logger log = (); private static Snmp snmp = null; // Control the access of shared resources to static initialization static { // Put the initialization of the SNMP object in a static block to ensure that it is only initialized once try { initSnmp(); } catch (IOException e) { ("SNMP initialization failed", e); // Record the exception information of the initialization failure } } private static synchronized void initSnmp() throws IOException { // Add synchronized keyword to ensure thread safety if (snmp == null) { MessageDispatcher messageDispatcher = new MessageDispatcherImpl(); (new MPv1()); (new MPv2c()); OctetString localEngineID = new OctetString(()); USM usm = new USM(().addDefaultProtocols(), localEngineID, 0); UsmUser user = new UsmUser(new OctetString("SNMPV3"), , new OctetString("authPassword"), , new OctetString("privPassword")); ((), user); (new MPv3(usm)); TransportMapping<?> transportMapping = new DefaultUdpTransportMapping(); snmp = new Snmp(messageDispatcher, transportMapping); (); } } private static Target createTarget(int version, String community, String ipAddress, int port) { Target target = null; if (!(version == SnmpConstants.version3 || version == SnmpConstants.version2c || version == SnmpConstants.version1)) { ("Parameter version exception"); // Keep error logging return target; } if (version == SnmpConstants.version3) { target = new UserTarget(); (SecurityLevel.AUTH_PRIV); (new OctetString("SNMPV3")); } else { target = new CommunityTarget(); ((CommunityTarget) target).setCommunity(new OctetString(community)); if (version == SnmpConstants.version2c) { (SecurityModel.SECURITY_MODEL_SNMPv2c); } } (version); (("udp:" + ipAddress + "/" + port)); (5); (3000); return target; } /** * Create a PDU object * @param version * @param type * @param oid * @return */ private static PDU createPDU(int version, int type, String oid) { PDU pdu = null; if (version == SnmpConstants.version3) { pdu = new ScopedPDU(); } else { pdu = new PDUv1(); } (type); (new VariableBinding(new OID(oid))); return pdu; } /** * Create a PDU object * @param version * @param type * @param oids * @return */ private static PDU createPDU(int version, int type, List<String> oids) { PDU pdu = null; if (version == SnmpConstants.version3) { pdu = new ScopedPDU(); } else { pdu = new PDU(); } (type); for (String oid : oids) { (new VariableBinding(new OID(oid))); } return pdu; } /** * Get SNMP response * @param ipAddr * @param port * @param version * @param community * @param oid * @return */ public static PDU snmpWalk(String ipAddr, int port, int version, String community, String oid) { try { // Since the snmp object has been initialized in a static block, initSnmp is no longer required to call initSnmp here Target target = createTarget(version, community, ipAddr, port); PDU pdu = createPDU(version, , oid); // Keep internal string unchanged ResponseEvent responseEvent = (pdu, target); PDU response = (); return response; } catch (IOException e) { ("SNMP send request failed", e); // Add exception logging return new PDU(); // In exception case, a new PDU object is still returned, but the error message has been logged } } /** * Get SNMP response * @param ipAddr * @param port * @param version * @param community * @param oids * @return */ public static PDU snmpWalk(String ipAddr, int port, int version, String community, List<String> oids) { try { // Since the snmp object has been initialized in a static block, initSnmp is no longer required to call initSnmp here Target target = createTarget(version, community, ipAddr, port); PDU pdu = createPDU(version, , oids); // Keep internal string unchanged ResponseEvent responseEvent = (pdu, target); PDU response = (); return response; } catch (IOException e) { ("SNMP send request failed", e); // Add exception logging return new PDU(); // In exception case, a new PDU object is still returned, but the error message has been logged } } /** * Get SNMP response * @param ipAddr * @param port * @param version * @param community * @param startOid * @return */ public static List<VariableBinding> snmpWalkAll(String ipAddr, int port, int version, String community, String startOid) { List<VariableBinding> results = new ArrayList<>(); Target target = createTarget(version, community, ipAddr, port); PDU pdu = new PDU(); (new VariableBinding(new OID(startOid))); while (true) { try { (); ResponseEvent responseEvent = (pdu, target); PDU response = (); if (response != null && () > 0 && () == 0) { if ((0).getVariable().toString().equals("endOfMibView")) { break; } (()); (null); // Reset request ID for the next request (0); // Remove the old request ((0)); // Add the new request based on the last response } else { break; } } catch (IOException e) { ("SNMP send request failed", e); break; } } return results; } /** * Get SNMP response * @param ipAddr * @param port * @param version * @param community * @param startOid * @return */ public static List<VariableBinding> snmpWalkSegment(String ipAddr, int port, int version, String community, String startOid) { List<VariableBinding> results = new ArrayList<>(); Target target = createTarget(version, community, ipAddr, port); PDU pdu = new PDU(); (new VariableBinding(new OID(startOid))); while (true) { try { (); ResponseEvent responseEvent = (pdu, target); PDU response = (); if (response != null && () > 0 && () == 0) { VariableBinding vb = (0); (vb); // Check if we have reached the end of the branch if (!().startsWith(new OID(startOid)) || ().toString().equals("endOfMibView")) { break; } (null); // Reset request ID for the next request (0); // Remove the old request (vb); // Add the new request based on the last response ("OID: " + () + ", Value: " + ()); } else { break; } } catch (IOException e) { ("SNMP send request failed", e); break; } } return results; } public static List<VariableBinding> snmpWalkSegment(String ipAddr, int port, int version, String community, List<String> startOids) { List<VariableBinding> results = new ArrayList<>(); Target target = createTarget(version, community, ipAddr, port); for(String startOid: startOids){ PDU pdu = new PDU(); (new VariableBinding(new OID(startOid))); while (true) { try { (); ResponseEvent responseEvent = (pdu, target); PDU response = (); if (response != null && () > 0 && () == 0) { VariableBinding vb = (0); (vb); // Check if we have reached the end of the branch if (!().startsWith(new OID(startOid)) || ().toString().equals("endOfMibView")) { break; } (null); // Reset request ID for the next request (0); // Remove the old request (vb); // Add the new request based on the last response ("OID: " + () + ", Value: " + ()); } else { break; } } catch (IOException e) { ("SNMP send request failed", e); break; } } } return results; } public static void main(String[] args) { PDU response = ("127.0.0.1", 161, SnmpConstants.version2c, "public", ".1"); if (response != null && () == 0) { for (VariableBinding vb : ()) { ("OID: " + () + ", Value: " + ()); } } else { ("Error in response: " + ()); } } }
Summarize
Through this article, you should have mastered how to use Java and SNMP4J libraries for SNMP operations. We introduced the design and implementation of the SnmpUtil class, including SNMP initialization, creating targets, creating PDUs, sending SNMP requests and processing responses. Hope this tutorial will help you better understand and use SNMP4J for network device management
This is the end of this article about using Java and SNMP4J to implement SNMP operations. For more related content on Java and SNMP4J to implement SNMP, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!