{"id":64,"date":"2015-12-07T19:56:07","date_gmt":"2015-12-08T00:56:07","guid":{"rendered":"http:\/\/jsevy.com\/wordpress\/?page_id=64"},"modified":"2015-12-07T20:43:43","modified_gmt":"2015-12-08T01:43:43","slug":"snmp-package-introduction","status":"publish","type":"page","link":"https:\/\/jsevy.com\/wordpress\/index.php\/java-and-android\/snmp\/snmp-package-introduction\/","title":{"rendered":"Java SNMP Package Introduction"},"content":{"rendered":"<p>This provides an introduction to the <a href=\"http:\/\/jsevy.com\/wordpress\/index.php\/snmp\/\">Java SNMP package<\/a> , an open-source implementation of the SNMP protocol in a Java package. It provides support for basic SNMP client operations as defined in SNMP versions 1 and 2 (excluding the security model proposed as part of SNMP version 2, which was never widely accept or deployed). The package provides a mechanism for &#8220;getting and setting&#8221; SNMP object identifier (OID) values through a simple communication interface, and represents SNMP structures and datatypes as corresponding Java objects. The package assumes familiarity with the SNMP protocol as detailed in RFC&#8217;s 1157, 1155, 1212, etc.; however, some simple examples are provided which illustrate its use for simple get\/set operations (though a knowledge of the concepts of OIDs and SNMP datatypes is still required).<\/p>\n<p>The complete API documentation for the package is provided through <a href=\"http:\/\/jsevy.com\/wordpress\/index.php\/snmp\/\">JavaDoc documentation <\/a>. This introduction is intended to provide an overview of the package, with particular focus on the classes an end user will need to directly interface with to incorporate the package into a project.<\/p>\n<h2>Main Interface: the SNMPv1CommunicationInterface Class<\/h2>\n<p>Much of the top-level user functionality is provided by the class SNMPv1CommunicationInterface. This constructor for this class opens a datagram socket to a specified host for SNMP communication on the standard port (192). Several methods of the class then provide a means to retrieve and set the value of SNMP variables on the remote device by supplying a string specifying an object identifier and an appropriate SNMP object for set operations. The example program listed below illustrates the use of the communication interface class to open a connection to a remote device, get the value of two variables corresponding to OIDs 1.3.6.1.2.1.1.1.0 and 1.3.6.1.2.1.1.3.0, and set the value of a third variable. The source code for the SNMP Inquisitor (included in the <a href=\"http:\/\/jsevy.com\/wordpress\/index.php\/snmp\/\">Java SNMP package<\/a> source distribution) shows the use of the package in a general-purpose utility which permits SNMP querying and modification of a remote device.<\/p>\n<p>The constructor for the SNMPv1CommunicationInterface takes three parameters: an integer giving the SNMP version in use (generally always 0), the remote device address supplied as an InetAddress object, and a string giving the SNMP community to be used for the operations.<\/p>\n<h3>Getting and Setting Variable Values<\/h3>\n<p>Once the communication interface has been created to communicate with a device, the values of SNMP variables can be retrieved with calls to the getMIBEntry( ) method. This takes as argument a string with the variable&#8217;s OID; the return value is somewhat complex, due to SNMP&#8217;s ability to query multiple variables in a single message (though this particular method retrieves only one value at a time) and to support the getNextMIBEntry( ) method (describesd below). The return value is of type SNMPVarBindList, a subclass of SNMPSequence which holds a sequence of (OID, value) pairs. Thus the retrieved SNMP value is accessed as follows:<\/p>\n<ul>\n<li>the first (and only) element is extracted from the SNMPVarBindList using the getSNMPObjectAt( ) method with argument 0<\/li>\n<li>the extracted element is typecast to type SNMPSequence &#8211; it&#8217;s an (OID, value) pair, i.e., an SNMP sequence<\/li>\n<li>the second element &#8211; the value &#8211; is extracted from the pair using the getSNMPObjectAt( ) method with argument 1<\/li>\n<\/ul>\n<p>The result of this (somewhat protracted) process is an SNMPObject subclass. The class of the returned value depends on the OID which was requested, and can be determined with the getClass( ) method defined in the Java Object universal base class (though generally the return class will be known in advance from knowledge of the OID being retrieved).<\/p>\n<p>The internal Java value can be retrieved from the SNMPObject subclass using the getValue( ) method, which returns a subclass of java.lang.Object that is appropriate to represent the value. The Java Object subclass which stores the value internally in each SNMPObject subclass is given in <a href=\"#table_1\"> Table 1<\/a> .<\/p>\n<p>The process of setting the value of an SNMP variable uses the setMIBEntry( ) method of the communication interface. This takes as arguments a String specifying the OID of the variable whose value is to be set, and an appropriate SNMPObject (of appropriate subclass) with the new value. The SNMP object can be constructed using an appropriate constructor for the object type.<\/p>\n<p>The code in <a href=\"#example_1\">Listing 1<\/a> illustrates the above get and set operations.<\/p>\n<p>The communication interface also provides a method getNextMIBEntry( ). This is used identically to the getMIBEntry( ) method, but retrieves the OID and value of the variable numerically following the supplied OID in the device&#8217;s list of variables. When this method is used, the OID will in general need to be extracted from the returned (OID, value) pair along with the value itself, to see which variable has been retrieved, since different devices will maintain different sets of variables. This can easily be obtained as the first element of the returned (OID, value) pair with the getSNMPObjectAt( ) method of the SNMPSequence class. This method is useful for performing a &#8220;treewalk&#8221; to retrieve the values of all of the variables maintained on a device, by calling the method successively using the last-retrieved OID to get the next one. The SNMP Inquisitor illustrates the use of this method in its run( ) method (<a href=\"http:\/\/jsevy.com\/snmp\/snmp_inquisitor_listing.html\">Listing 2<\/a> ) used by its treewalk thread. Note that different devices seem to react differently when there are no more variables available; some will respond with an error indication, which is reported by the SNMPv1CommunicationInterface as an SNMPGetException (see below), while others just return the MIB entry corresponding to that requested rather than the (nonexistent) next one. The SNMP Inquisitor code thus tests to see if the OID received is different from that sent, and breaks if they&#8217;re equal.<\/p>\n<h3>Exceptions<\/h3>\n<p>The Java SNMP package defines a number of exceptions to indicate problems with SNMP object construction, retrieval, and setting. An SNMPBadValueException is thrown if a constructor or setValue( ) method of an SNMP data object is supplied with a Java object of inappropriate type. The getMIBEntry( ) method of the communication interface class throws an SNMPGetException when an attempt to get the value of a variable receives an error message in response. The reason for the error could be that the specified variable is not supported by the device, or that the supplied community name has insufficient privileges to read the value; a message string supplied in the exception generally provides information specifying the reason. The setMIBEntry( ) similarly throws an SNMPSetException if a set operation fails. In addition, since the communication interface uses datagram sockets for communication, a number of standard exceptions may be thrown by methods (e.g., IOException, SocketException, etc.). The <a href=\"http:\/\/jsevy.com\/wordpress\/index.php\/snmp\/\">JavaDoc documentation<\/a> details which exceptions are thrown by which methods.<\/p>\n<h2>SNMP Datatypes and Corresponding Java Classes<\/h2>\n<p>A number of classes in the Java SNMP package serve to represent the standard SNMP datatypes as Java classes, with each datatype represented by a subclass of the abstract base class SNMPObject. The data is stored internally in an appropriate standard Java object, which may be retrieved for inspection or set to a new value. For example, the SNMP Integer datatype is represented by the snmp.SNMPInteger class, which stores the value internally in a java.math.BigInteger object (a BigInteger object is used rather than a regular Integer to correctly address the fact that there is no express upper limit placed on the size of the SNMP Integer datatype). Similarly, the SNMP octet string type is represented by the snmp.SNMPOctetString class, which has an internal byte array holding the raw octet string data.<\/p>\n<p>The only compound datatype in SNMP is the sequence, which holds a list of SNMP data elements (including nested sequences). THis is represented by the class snmp.SNMPSequence, which has an internal Vector to hold the list of SNMP objects.<\/p>\n<p>Each concrete subclass defines public functions (declared in the abstract base class) for getting and setting the internal (Java object) value, getValue( ) and setValue( ) (the latter throws an SNMPBadValueException if the wrong object type is supplied), as well as appropriate constructors, and a toString( ) method which returns a human-readable representation of the SNMP object.<\/p>\n<p>The following table lists the Java class corresponding to each standard SNMP datatype, and the class used to represent the value internally. Note that most of the Java classes use the name of the corresponding SNMP type with &#8220;SNMP&#8221; prefixed.<\/p>\n<h4><a name=\"table_1\"><\/a> Table 1: SNMP datatypes, corresponding Java SNMP classes, and internal value representations<\/h4>\n<table border=\"1\" width=\"100%\">\n<caption>\u00a0<\/caption>\n<tbody>\n<tr>\n<td><b>SNMP Datatype<\/b><\/td>\n<td><b>Java SNMP Class<\/b><\/td>\n<td><b>Java SNMP Base Class<\/b><\/td>\n<td><b>Internal value representation<\/b><\/td>\n<\/tr>\n<tr>\n<td>Integer<\/td>\n<td>SNMPInteger<\/td>\n<td>SNMPObject<\/td>\n<td>BigInteger<\/td>\n<\/tr>\n<tr>\n<td>Uinteger32<\/td>\n<td>SNMPUInteger32<\/td>\n<td>SNMPInteger<\/td>\n<td>BigInteger (but value &#8220;wraps&#8221; at 2^32)<\/td>\n<\/tr>\n<tr>\n<td>Gauge<\/td>\n<td>SNMPGauge32<\/td>\n<td>SNMPInteger<\/td>\n<td>BigInteger (but value &#8220;pegs&#8221; at 2^32 &#8211; 1)<\/td>\n<\/tr>\n<tr>\n<td>Counter32<\/td>\n<td>SNMPCounter32<\/td>\n<td>SNMPInteger<\/td>\n<td>BigInteger (but value &#8220;wraps&#8221; at 2^32)<\/td>\n<\/tr>\n<tr>\n<td>Counter64<\/td>\n<td>SNMPCounter64<\/td>\n<td>SNMPInteger<\/td>\n<td>BigInteger (but value &#8220;wraps&#8221; at 2^64)<\/td>\n<\/tr>\n<tr>\n<td>TimeTicks<\/td>\n<td>SNMPTimeTicks<\/td>\n<td>SNMPInteger<\/td>\n<td>BigInteger<\/td>\n<\/tr>\n<tr>\n<td>Octet string<\/td>\n<td>SNMPOctetString<\/td>\n<td>SNMPObject<\/td>\n<td>byte[ ]<\/td>\n<\/tr>\n<tr>\n<td>IP address<\/td>\n<td>SNMPIPAddress<\/td>\n<td>SNMPOctetString<\/td>\n<td>byte[4]<\/td>\n<\/tr>\n<tr>\n<td>NSAP address (MAC address)<\/td>\n<td>SNMPNSAPAddress<\/td>\n<td>SNMPOctetString<\/td>\n<td>byte[6]<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">Object identifier<\/td>\n<td valign=\"top\">SNMPObjectIdentifier<\/td>\n<td valign=\"top\">SNMPObject<\/td>\n<td valign=\"top\">long[ ] (contains the components of the dotted-integer representation of the OID)<br \/>\n(Note: represented as int[ ] in versions prior to 1.4)<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">Sequence<\/td>\n<td valign=\"top\">SNMPSequence<\/td>\n<td valign=\"top\">SNMPObject<\/td>\n<td valign=\"top\">Vector<\/td>\n<\/tr>\n<tr>\n<td>VarBind<\/td>\n<td>SNMPVariablePair<\/td>\n<td>SNMPSequence<\/td>\n<td>Vector<\/td>\n<\/tr>\n<tr>\n<td>VarBindList<\/td>\n<td>SNMPVarBindList<\/td>\n<td>SNMPSequence<\/td>\n<td>Vector<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">Null<\/td>\n<td valign=\"top\">SNMPNull<\/td>\n<td valign=\"top\">SNMPObject<\/td>\n<td valign=\"top\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<hr size=\"2\" width=\"100%\" \/>\n<h4><a name=\"example_1\"><\/a> Listing 1: SNMPSample.java source code<\/h4>\n<p>import snmp.*;<br \/>\nimport java.util.*;<br \/>\nimport java.math.*;<br \/>\nimport java.net.*;<\/p>\n<p>public class SNMPSample<br \/>\n{<\/p>\n<p>public static void main(String args[])<br \/>\n{<\/p>\n<p>try<br \/>\n{<\/p>\n<p>\/\/ create<br \/>\na communications interface to a remote SNMP-capable device;<br \/>\n\/\/ need<br \/>\nto provide the remote host&#8217;s InetAddress and the community<br \/>\n\/\/ name<br \/>\nfor the device; in addition, need to\u00a0 supply the version number<br \/>\n\/\/ for<br \/>\nthe SNMP messages to be sent (the value 0 corresponding to SNMP<br \/>\n\/\/ version<br \/>\n1)<br \/>\nInetAddress<br \/>\nhostAddress = InetAddress.getByName(&#8220;10.0.1.1&#8221;);<br \/>\nString<br \/>\ncommunity = &#8220;public&#8221;;<br \/>\nint version<br \/>\n= 0;\u00a0\u00a0\u00a0 \/\/ SNMPv1<\/p>\n<p>SNMPv1CommunicationInterface<br \/>\ncomInterface = new SNMPv1CommunicationInterface(version, hostAddress, community);<\/p>\n<p>\/\/ now<br \/>\nsend an SNMP GET request to retrieve the value of the SNMP variable<br \/>\n\/\/ corresponding<br \/>\nto OID 1.3.6.1.2.1.1.1.0; this is the OID corresponding to<br \/>\n\/\/ the<br \/>\ndevice identifying string, and the type is thus SNMPOctetString<br \/>\nString<br \/>\nitemID = &#8220;1.3.6.1.2.1.1.1.0&#8221;;<\/p>\n<p>System.out.println(&#8220;Retrieving<br \/>\nvalue corresponding to OID &#8221; + itemID);<\/p>\n<p>\/\/ the<br \/>\ngetMIBEntry method of the communications interface returns an SNMPVarBindList<\/p>\n<p>\/\/ object;<br \/>\nthis is essentially a Vector of SNMP (OID,value) pairs. In this case, the<\/p>\n<p>\/\/ returned<br \/>\nVector has just one pair inside it.<br \/>\nSNMPVarBindList<br \/>\nnewVars = comInterface.getMIBEntry(itemID);<\/p>\n<p>\/\/ extract<br \/>\nthe (OID,value) pair from the SNMPVarBindList; the pair is just a two-element<\/p>\n<p>\/\/ SNMPSequence<\/p>\n<p>SNMPSequence<br \/>\npair = (SNMPSequence)(newVars.getSNMPObjectAt(0));<\/p>\n<p>\/\/ extract<br \/>\nthe object identifier from the pair; it&#8217;s the first element in the sequence<\/p>\n<p>SNMPObjectIdentifier<br \/>\nsnmpOID = (SNMPObjectIdentifier)pair.getSNMPObjectAt(0);<\/p>\n<p>\/\/ extract<br \/>\nthe corresponding value from the pair; it&#8217;s the second element in the sequence<\/p>\n<p>SNMPObject<br \/>\nsnmpValue = pair.getSNMPObjectAt(1);<\/p>\n<p>\/\/ print<br \/>\nout the String representation of the retrieved value<br \/>\nSystem.out.println(&#8220;Retrieved<br \/>\nvalue: type &#8221; + snmpValue.getClass().getName() + &#8220;, value &#8221; + snmpValue.toString());<\/p>\n<p>\/\/ the<br \/>\nretrieved value can be obtained from the SNMPObject using the getValue method;<\/p>\n<p>\/\/ the<br \/>\nreturn type of the method is the generic base class Object, and must be cast<br \/>\nto<br \/>\n\/\/ the<br \/>\nappropriate actual Java type; in this case, for an SNMPOctetString, the underlying<\/p>\n<p>\/\/ Java<br \/>\ntype is a byte array[]<br \/>\nbyte[]<br \/>\njavaByteArrayValue = (byte[])snmpValue.getValue();<\/p>\n<p>\/\/ now<br \/>\nsend an SNMP GET request to retrieve the value of the SNMP variable<br \/>\n\/\/ corresponding<br \/>\nto OID 1.3.6.1.2.1.1.3.0; this is the OID corresponding to<br \/>\n\/\/ the<br \/>\nuptime of the device, and the return type is thus SNMPTimeTicks<br \/>\nitemID<br \/>\n= &#8220;1.3.6.1.2.1.1.3.0&#8221;;<\/p>\n<p>System.out.println(&#8220;Retrieving<br \/>\nvalue corresponding to OID &#8221; + itemID);<\/p>\n<p>\/\/ the<br \/>\ngetMIBEntry method of the communications interface returns an SNMPVarBindList<\/p>\n<p>\/\/ object;<br \/>\nthis is essentially a Vector of SNMP (OID,value) pairs. In this case, the<\/p>\n<p>\/\/ returned<br \/>\nVector has just one pair inside it.<br \/>\nnewVars<br \/>\n= comInterface.getMIBEntry(itemID);<\/p>\n<p>\/\/ extract<br \/>\nthe (OID,value) pair from the SNMPVarBindList; the pair is just a two-element<\/p>\n<p>\/\/ SNMPSequence<\/p>\n<p>pair =<br \/>\n(SNMPSequence)(newVars.getSNMPObjectAt(0));<\/p>\n<p>\/\/ extract<br \/>\nthe object identifier from the pair; it&#8217;s the first element in the sequence<\/p>\n<p>snmpOID<br \/>\n= (SNMPObjectIdentifier)pair.getSNMPObjectAt(0);<\/p>\n<p>\/\/ extract<br \/>\nthe corresponding value from the pair; it&#8217;s the second element in the sequence<\/p>\n<p>snmpValue<br \/>\n= pair.getSNMPObjectAt(1);<\/p>\n<p>\/\/ print<br \/>\nout the String representation of the retrieved value<br \/>\nSystem.out.println(&#8220;Retrieved<br \/>\nvalue: type &#8221; + snmpValue.getClass().getName() + &#8220;, value &#8221; + snmpValue.toString());<\/p>\n<p>\/\/ the<br \/>\nretrieved value can be obtained from the SNMPObject using the getValue method;<\/p>\n<p>\/\/ the<br \/>\nreturn type of the method is the generic base class Object, and must be cast<br \/>\nto<br \/>\n\/\/ the<br \/>\nappropriate actual Java type; in this case, for SNMPTimeTicks, which is a<br \/>\nsubclass<br \/>\n\/\/ of<br \/>\nSNMPInteger, the actual type is BigInteger (which permits arbitrarily large<br \/>\nvalues to<br \/>\n\/\/ be<br \/>\nrepresented).<br \/>\nBigInteger<br \/>\njavaIntegerValue = (BigInteger)snmpValue.getValue();<\/p>\n<p>\/\/ now<br \/>\nsend an SNMP SET request to set the value of the SNMP variable<br \/>\n\/\/ corresponding<br \/>\nto OID 1.3.6.1.2.1.1.1.0; this is the OID corresponding to<br \/>\n\/\/ the<br \/>\ndevice identifying string, and the type is thus SNMPOctetString;<br \/>\n\/\/ to<br \/>\nset a new value, a string is supplied<br \/>\nitemID<br \/>\n= &#8220;1.3.6.1.2.1.1.1.0&#8221;;<\/p>\n<p>SNMPOctetString<br \/>\nnewValue = new SNMPOctetString(&#8220;New device name&#8221;);<\/p>\n<p>System.out.println(&#8220;Setting<br \/>\nvalue corresponding to OID &#8221; + itemID);<br \/>\nSystem.out.println(&#8220;New<br \/>\nvalue: &#8221; + newValue.toString());<\/p>\n<p>\/\/ the<br \/>\nsetMIBEntry method of the communications interface returns the SNMPVarBindList<\/p>\n<p>\/\/ corresponding<br \/>\nto the supplied OID and value<br \/>\n\/\/ This<br \/>\ncall will probably cause an SNMPSetException to be thrown, since the<br \/>\n\/\/ community<br \/>\nname &#8220;public&#8221; is probably not the read\/write password of the device<br \/>\nnewVars<br \/>\n= comInterface.setMIBEntry(itemID, newValue);<\/p>\n<p>}<br \/>\ncatch(Exception e)<br \/>\n{<br \/>\nSystem.out.println(&#8220;Exception<br \/>\nduring SNMP operation:\u00a0 &#8221; + e + &#8220;\\n&#8221;);<br \/>\n}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This provides an introduction to the Java SNMP package , an open-source implementation of the SNMP protocol in a Java package. It provides support for basic SNMP client operations as defined in SNMP versions 1 and 2 (excluding the security model proposed as part of SNMP version 2, which was never widely accept or deployed). &hellip; <a href=\"https:\/\/jsevy.com\/wordpress\/index.php\/java-and-android\/snmp\/snmp-package-introduction\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Java SNMP Package Introduction<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":57,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-64","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/pages\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":7,"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/pages\/64\/revisions"}],"predecessor-version":[{"id":66,"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/pages\/64\/revisions\/66"}],"up":[{"embeddable":true,"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/pages\/57"}],"wp:attachment":[{"href":"https:\/\/jsevy.com\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}