This document describes the delivery of this stack and how the stack can be used for SNMPv1, SNMPv2c and SNMPv3. The stack supports traps, authentication and privacy. As authentication protocols the stack offers MD5 and SHA1.
This document does not explain SNMP (Simple Network Management Protocol) itself. The reader is assumed to have basic knowledge of the protocol. If you want to learn more, see the Reading section.
The target applications are small applets, for that reason the stack has remained tiny. We wanted something lighter that we could just pop in a (browser) frame and leave there all day. It has no MIB (Management Information Base) browsing capabilities, you have to know the OID (Object Identifier) of what you want to monitor. There are many other packages that do MIB browsing and general network management.
The Westhawk Java SNMP stack comes with generated (javadoc) documentation and a faq. Check that documentation for the description of all methods that are not mentioned in this document or for the description of the method parameters.
The file snmp<version>.zip
contains the SNMP stack.
The file stubBrowser<version>.zip
contains the Stub Browser
application.
Both distributions can be downloaded from the
Westhawk's SNMP page.
You best unpack both deliveries in the same directory. They are released separately because of their different licence, but come from the same development source tree.
tablelayout.jar
file into
uk.westhawk.snmp.X
packages.
This jar file does not contain any examples or beans.uk.westhawk.stub
package.
You need to have Ant installed before you can build (or run) anything.
To build the snmp<version>.jar file, type on the command line:
% ant
This will compile and jar snmp<version>.jar and
snmpOracle<version>.jar in the lib/
directory.
If you set mibble.dir
property (see next section) it will
also build the stubBrowser<version>.jar file.
This target will not compile any of the examples (see
Running the applications).
Before building the stubBrowser<version>.jar file, you need to
download
Mibble (v2.5 or later)
and set the ant mibble.dir
property accordingly in
the build.xml
or build.properties
file.
Type on the command line:
% ant buildStubBrowser
This will compile and jar stubBrowser<version>.jar in the
lib/
directory.
Every PDU that is created needs a context. The same context can be used for a number of PDUs.
For SNMPv1 the context is built out of the following parameters:
The next section explains the use of the type of socket.
This SNMP stack provides three contexts for SNMPv1:
The SnmpContextPool
contains a pool of
SnmpContext
and will share any context that it can share.
This results in a reduced number of threads and other resources.
The PassiveSnmpContextPool
contains the SNMPv1
context that is needed by a PDU to send a SNMPv1 request in
environments where thread creation is unwanted, see the
nothread
notes.
The context for SNMPv2c is very similar to the SNMPv1 context. It is built out of the following parameters:
The next section explains the use of the type of socket.
This SNMP stack provides three contexts for SNMPv2c:
The SnmpContextv2cPool
contains a pool of
SnmpContextv2c
and will share any context that it can share.
This results in a reduced number of threads and other resources.
The PassiveSnmpContextv2c
contains the SNMPv2c
context that is needed by a PDU to send a SNMPv2c request in
environments where thread creation is unwanted, see the
nothread
notes.
For SNMPv3 the context is built out of the following parameters.
This SNMP stack provides two contexts for SNMPv3:
The SnmpContextv3Pool
contains a pool of
SnmpContextv3
and will share any context that it can share.
This results in a reduced number of threads and other resources.
When sending traps or receiving request PDUs with SNMPv3, please read the section about the authoritative engine.
At the moment two types of sockets can be used:
SnmpContextBasisFace.STANDARD_SOCKET
SnmpContextBasisFace.TCP_SOCKET
By default the standard socket will be used.
The TCP socket can be used for "Reliable SNMP", if your agent supports this. This socket can be used to send requests and listen for traps, however it doesn't provide the functionality to send a response back to a request, see sending a response to a request.
Sending PDUs can be done in a number of ways:
The package uk.co.westhawk.snmp.beans
contains all the beans in the stack.
Except for the UsmDiscoveryBean
and
UsmBeingDiscoveredBean
they all (still) relate to
SNMPv1.
The beans form a bridge between the uk.co.westhawk.snmp.pdu
(and
uk.co.westhawk.snmp.stack
) package(s) and any applet
or application you may want to write.
The beans work via the (asynchronous)
java.beans.PropertyChange
mechanism.
If you are using Swing, don't forget to use
javax.swing.SwingUtilities.invokeLater(java.lang.Runnable)
if you want to do any screen updates from the
propertyChange
method.
Our beans gather specific MIB information, i.e. the OID (Object
Identifier) is hard coded. The beans should be easy enough to
understand, and with little effort you can write a bean for your own purpose.
The beans SNMPBean
and SNMPRunBean
contain some general information about the beans.
The coding examples will show you how to use the
beans as well.
The package
uk.co.westhawk.snmp.pdu
contains all the public accessible
PDUs.
All the PDUs (well, except for the BlockPdu)
extend abstract
uk.co.westhawk.snmp.stack.Pdu
.
The PDUs are non blocking and work via the
java.util.Observer/java.util.Observable
mechanism.
The idea is that for each class of problem you should subclass the
abstract uk.co.westhawk.snmp.stack.Pdu
class. You will have
to implement the protected void new_value(int n, varbind
res)
and the protected void tell_them()
methods.
As example look at the uk.co.westhawk.snmp.pdu.OneIntPdu
class or any other class in that package.
In order to use a PDU do the following:
GetPdu pdu = new
GetPdu(context)
. pdu.add_oid(oid)
. pdu.addObserver(observer)
. The argument is the
object that wishes to be notified when the new value arrives.
It must implement
java.util.Observer
, that is it must have a
public void update(java.util.Observable obs, java.lang.Object obj)
method. This method will get called when the value arrives.
If you are using Swing, don't forget to use
javax.swing.SwingUtilities.invokeLater(java.lang.Runnable)
if you want to do any screen updates.pdu.send()
.update
method will get
called automatically when the data has arrived. Both the context and PDU
objects spawn their own threads, so there is nothing further to do.The stack was initially build with manager only functionality in mind, i.e. sending a request and receiving a response. It is possible to receive a request and send a response back, but the functionality is still very clunky.
Since a trap or a response does not get a reply, you can omit adding an
observer
(step 4)
and implementing update
(the last step) when sending one.
When sending traps or receiving PDUs with SNMPv3, please read the
section about the
authoritative engine.
The coding examples will show you how to use the PDUs as well.
The class uk.co.westhawk.snmp.pdu.BlockPdu
is a wrapper
class around the traditional (non blocking) PDU. It allows the user to
send either a Set request, a Get request, a GetNext request or a GetBulk
request by
specifying the type of request, see the setPduType
method. The
caller has to add the necessary OIDs with the method addOid
.
As the title suggests, the BlockPdu sends the request and waits for the response. We suggest that you only use this class if you have to; because the PDU blocks, you can not do anything else on that thread while it is waiting for a reply. If that thread is driving a UI, then the user may see a sluggish interface. If you can, use the beans or the PDUs. They are much faster as well.
There are four methods that send the request, wait for the response and
return the variables or variable bindings. They throw the
uk.co.westhawk.snmp.stack.PduException
exception:
The OIDs that are added via addOid
method for the request
will not be replaced by the OIDs from the response. This means that
every request will result in the same answer and that the GetNext does
not walk the MIB
There are different ways to receive incoming PDUs. Any combination of these ways can be used at the same time:
root
user is allowed
to open these port, you will have to run as root
in order to
listen for incoming PDUs on that port, when running on any of those
operating systems.
To receive traps, that is a Trapv1
or Trapv2
PDU, from a specific host do the following:
context.addTrapListener(listener, port)
.
The arguments are the object that wishes to be notified when the traps
arrive and the listening port.
It must implement
uk.co.westhawk.snmp.event.TrapListener
, that is it must have a
public void trapReceived(uk.co.westhawk.snmp.event.TrapEvent evt)
method. This method will get called when the trap is received.
The SnmpContext
fires
decoded
PDU events.
To receive request PDUs, that is a GetRequest
,
SetRequest
, GetNextRequest
,
GetBulkRequest
or Inform
PDU,
from a specific host do the following:
context.addRequestPduListener(listener, port)
.
The arguments are the object that wishes to be notified when the
request PDUs arrive and the listening port. It must implement
uk.co.westhawk.snmp.event.RequestPduListener
, that is it must
have a
public void requestPduReceived(uk.co.westhawk.snmp.event.RequestPduEvent evt)
method. This method will get called when the request PDU is received.
The SnmpContext
fires
decoded
PDU events. If you want to reply to the request, read the section on
sending a response.
When receiving request PDUs with SNMPv3, please read the section about the authoritative engine.
The class uk.co.westhawk.snmp.stack.ListeningContextPool
forms the base to receiving incoming packets. It contains a pool of
uk.co.westhawk.snmp.stack.ListeningContext
objects, that
prevent the user from opening more than one listening object on the same
port.
ListeningContextPool lContext
= new ListeningContextPool(port)
.
The argument is the listening port.
lContext.addRawPduListener(listener)
.
The argument is the object that wishes to be notified when the raw PDUs arrive.
It must implement
uk.co.westhawk.snmp.event.RawPduListener
, that is it must have a
public void rawPduReceived(uk.co.westhawk.snmp.event.RawPduEvent evt)
method. This method will get called when the packet is received.
The ListeningContext
fires
undecoded
PDU events.
Unhandled PDUs are raw PDUs that are received (see PDUs for all hosts) but do not match any of the contexts (see trap PDUs from a specific host and request PDUs from a specific host):
ListeningContextPool lContext
= new ListeningContextPool(port)
.
The argument is the listening port.
lContext.addUnhandledRawPduListener(listener)
.
The argument is the
object that wishes to be notified when unhandled PDUs are received.
It must implement
uk.co.westhawk.snmp.event.RawPduListener
, that is it must have a
public void rawPduReceived(uk.co.westhawk.snmp.event.RawPduEvent evt)
method. This method will get called when the packet is received and
remains unhandled.
The ListeningContext
fires
undecoded
PDU events.
There are two types of PDU events:
Decoded PDU events are fired by the SnmpContext
classes
when receiving trap PDUs from a specific host
or request PDUs from a specific host.
When receiving
trap PDUs from a specific host
the uk.co.westhawk.snmp.event.TrapEvent
will contain one of the two trap PDUs:
uk.co.westhawk.snmp.stack.TrapPduv1
- The Trap PDU for
SNMPv1uk.co.westhawk.snmp.stack.TrapPduv2
- The Trap PDU for
SNMPv2c and SNMPv3
When receiving
request PDUs from a specific host
the uk.co.westhawk.snmp.event.RequestPduEvent
will contain one of the following request PDUs:
uk.co.westhawk.snmp.stack.GetPdu
- The GetRequest PDUuk.co.westhawk.snmp.stack.SetPdu
- The SetRequest PDUuk.co.westhawk.snmp.stack.GetNextPdu
- The GetNextRequest PDUuk.co.westhawk.snmp.stack.GetBulkPdu
- The GetBulkRequest PDU (SNMPv2c and SNMPv3 only)uk.co.westhawk.snmp.stack.InformPdu
- The Inform PDU (SNMPv2c and SNMPv3 only)In both cases the event will contain the following:
snmp context
- The snmp context that decoded the PDUpdu
- The PDUport
- The port number of the host where the
PDU came from
Undecoded PDU events are fired by the ListeningContext
class
when receiving PDUs for all hosts and/or
receiving unhandled PDUs.
The uk.co.westhawk.snmp.event.RawPduEvent
will contain the following:
listening context
- The listening context that received the PDUversion
- The SNMP version number of the PDUhost address
- The IP host address of the host where the
PDU came fromport
- The port number of the host where the
PDU came frommessage
- The PDU in bytes
To decode an undecoded PDU event, you create a
context on the fly and call
Pdu pdu = context.processIncomingPdu(byte[ ] message)
.
The context should contain all the parameters needed to decode the
message. For SNMPv3 this is not so obvious.
The stack was initially build with manager only functionality in mind, i.e. sending a request and receiving a response. It is possible to receive a request by getting decoded PDU events and send a response back, but the functionality is still very clunky.
The TCP_SOCKET does not provide the functionality to send a response back. You'll have to use the standard one, see the section on socket type.
As mentioned before, the stack offers no MIB parsing to help the user
parse the request PDU. It is possible to send a
uk.co.westhawk.snmp.stack.ResponsePdu
,
but how to fill it in is up to the user. Please do not forget to use the
RequestPduEvent.getHostPort()
when creating the context for
the response.
When sending response PDUs with SNMPv3, please read the next section about the authoritative engine.
When sending traps or receiving requests the stack becomes an agent, or an authoritative engine as it is called in SNMPv3, rather than a manager, or a non-authoritative engine as it is called in SNMPv3.
In SNMPv3 the User-Based Security Model (USM) timeliness mechanism is different for authoritative and non-authoritative SNMP engines:
This distinction does not apply to SNMPv1 or SNMPv2c.
Since the stack is not a real agent, it cannot provide all the
USM synchronisation parameters. For that reason the user has to provide
an implementation of the interface
uk.co.westhawk.snmp.stack.UsmAgent
. See also the javadoc on
SnmpContextv3
. This interface provides
the stack with the following information of its authoritative engine:
Engine ID
- The authoritative SNMP Engine ID, which (at
least within an administrative domain) uniquely and unambiguously
identifies the SNMP engine (not to be confused with the context
engine id, see SNMPv3 context)
Engine Boots
- The authoritative SNMP Engine Boots,
which is a count of the number of times the SNMP engine has
re-booted/re-initialized since snmpEngineID was last configuredEngine Time
- The authoritative SNMP Engine Time, which is the number of seconds since the snmpEngineBoots counter was last incremented
The stack contains a lot of examples in the form of
applications in the package uk.co.westhawk.examplev1
.
The package uk.co.westhawk.examplev2c
contains a few examples
for SNMPv2c.
The package uk.co.westhawk.examplev3
contains a few examples
for SNMPv3.
These packages show you how to use the PDUs and beans. Note that because
we implemented SNMPv3 before SNMPv2c, there are more examples for the
former one.
How to run these examples is explained in the next section. If this example is not sufficient, check if the other examples do what you are looking for.
The next is a snippet of the
uk.co.westhawk.examplev1.get_next
example that walks
the MIB with the GetNextPdu.
The complete example is part of the source distribution.
public class get_next implements Observer { public void init() { try { context = createContext(host, port, socketType, community); GetNextPdu pdu = createPdu(context, new varbind(oid), this); pdu.send(); } catch (java.io.IOException exc) { context.destroy(); System.exit(1); } catch(uk.co.westhawk.snmp.stack.PduException exc) { context.destroy(); System.exit(1); } } protected SnmpContext createContext(String host, int port, String socketType, String community) throws java.io.IOException { SnmpContext con = new SnmpContext(host, port, socketType); con.setCommunity(community); return con; } protected GetNextPdu createPdu(SnmpContext context, varbind var, Observer obs) { GetNextPdu newPdu = new GetNextPdu(context); newPdu.addOid(var); newPdu.addObserver(obs); return newPdu; } public void update(Observable obs, Object ov) { GetNextPdu pdu = (GetNextPdu) obs; if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) { try { varbind[] vars = pdu.getResponseVarbinds(); varbind var = vars[0]; System.out.println(var.toString()); pdu = createPdu(context, new varbind(var.getOid()), this); pdu.send(); } catch(java.io.IOException exc) { System.out.println("update(): IOException " + exc.getMessage()); } catch(uk.co.westhawk.snmp.stack.PduException exc) { System.out.println("update(): PduException " + exc.getMessage()); } } else { context.destroy(); System.exit(0); } } }
To run the examples, you need to have Ant installed.
The uk.co.westhawk.examplev1
,
uk.co.westhawk.examplev2c
and
uk.co.westhawk.examplev3
directories contain example applications, that can be run
using the Ant runExample
target, defined in
example.xml
.
Type on the command line:
% ant runExample
Unless changed (see below), this target will run the
uk.co.westhawk.examplev1.get_next
application,
with the properties file
src/uk/co/westhawk/examplev1/get_next.properties
as argument.
The runExample
target has a number of properties (defined
in example.xml
) that you
can change to run another example:
package.name
; the Java package name, default set to
uk.co.westhawk.examplev1
package.dir
; the directory on disk where the package lives
(relative to example.xml
), default set
to src/uk/co/westhawk/examplev1
classname
; the application name (without the package name),
default set to get_next
propertiesfile
; the properties file that is
passed as (optional) argument, default set to
src/uk/co/westhawk/examplev1/get_next.properties
The properties file (get_next.properties
)
contains the initialisation parameters of the example, such as the hostname
and the port number.
When the argument is missing, the application will look for the
file <classname>.properties
in the used package directory.
The target first compiles the package (into the directory
classes
) and then runs it. The classpath is set to:
snmp<version>.jar
;
to change the location, alter the property snmp.jar
at
the top of the build.xml
file.
tablelayout.jar
;
to change the location, alter the property table.jar
at
the top of the build.xml
file.
The Stub Browser is an experimental piece of software that offers the user a UI to generate a PDU out of selected OIDs. It is an add-on to the Mibble Mib Browser. It is not "fool-proof", and (as always) we appreciate your feedback.
To run the Stub Browser you need to have Ant installed. You have to download
stubBrowser<version>.zip
from the
Westhawk's SNMP page
and configure the location of
mibble.dir
in the build.xml
file.
snmp<version>.jar
file, by changing
the property snmp.jar
in the build.xml
file, unless you installed both zip files in the same directory.
Now run on the command line:
% ant runStubBrowser
First select all the OIDs you want to include in your Java stub file. Select an OID be by right clicking on a leaf in the MIB tree. A small popup menu will appear with the "Add to Stubs" menu item. Each selected stub will be listed in the lower pane.
When you are happy with your list, select "Generate Stubs" from the File menu. This will bring up a second "Stub Files" frame with the Java code. Every time you generate a stub file, the new code will be added in a new tab.
You can save each tab individually to disk. The code will try to replace the classname and packagename place holders, but please check the code before trying to compile. Compilation of the new java files, is outside the scope of the Stub Browser.
Please note that the Stub Browser is not a fancy development tool. For example, when exiting the application or closing a tab, it will not check if you have saved the latest version.
Our article on Simple Times (issue Dec 2001) explains the history and design decisions of the stack.
The SimpleWeb provides links and information on network management, including software, RFCs and tutorials. The focus is on SNMP and Internet management.
For more background on SNMP we recommend the following books:
All the jar files that are needed for the core stack are delivered with the stack. A few jar files are used in other packages (mostly the examples) that do not come with the stack:
Some of the examples use the
TableLayout
layout manager. This layout manager is part of the distribution. For
those who retrieved the stack from SourceForge, the layout manager can
be downloaded from our
SNMP Technology
page as a zip file. Unzip the tablelayout.jar
file into
the lib/
directory.
The stack uses version 1.27 of the Bouncy Castle lightweight cryptography (lcrypto) API for SNMPv3 authentication and privacy. The files of this great API that are used by the stack, are distributed as part of the stack, so don't have to be downloaded separately. They are part of the SourceForge cvs as well.
The stack is freeware. The licence (see the header of each file) means that you can do whatever you like with it without cost, except
The licence requires that you acknowledge our code, by mentioning its origin in the documentation of any product that uses it (in some cases there may be no documentation).
The Stub Browser is released under the GNU GPL License, since it uses Mibble. There are no commercial licence fees, nor do we have any GPL-style open-source requirements on our stack itself.
If you would like software written that uses the stack or modifications to the stack to better suit your project, we would be happy to quote you for the work.
We also offer commercial support for organisations who want it.
17 Oct 2007
Post to the snmp mailing list or contact the snmp group at Westhawk Ltd