You can build JAVA applets as well using much the same methods as we did for applications. However, there are a couple of small differences to keep in mind.
Let's build a simple applet to receive and print SNMP traps. Our applet will have only a label and a text area for printing the traps we receive. This will illustrate the use of callbacks for received PDUs.
Applets need to implement the init(), start(), stop() and destroy() methods. As the names indicate, they're used by the browser (or appletviewer) to initialize, start, stop and destroy the applet that runs in the browser. The browser usually initializes an applet only once, when the class is loaded.
Start is run when the applet is visited, or shown on screen. Stop is called when applet is no longer on the screen. Destroy is called when applet is no longer needed and will not be re-visited without loading classes again.
We wish to use the callback facility which is ideal for our application where we just print traps that come in. For this we need to implement the SnmpClient interface in the SNMP Package.
So we begin with the class definition which extends applet (as all applets) and implements SnmpClient. We need a few variables in multiple methods, including the SnmpAPI and the TextArea, which we define.
We allow the user to specify two configurable parameters via the applet's HTML file. These are the port number and the MIB file to be loaded.
/** The import clauses */
import java.lang.*;
import java.util.*;
import java.awt.*;
import java.applet.*;
import java.net.URL;
import java.io.InputStream;
import Snmp.*;
public class viewTrap extends Applet implements SnmpClient {
/** Some of the widgets in the main applet window. */
TextArea text;
Label header;
/** The SNMP API instance */
SnmpAPI api;
We'll use the init method to implement initilization of the SnmpAPI class. We also setup a font, a header label, and a text area for the applet in this function. The AWT is the windowing toolkit for Java, and we're using classes from the AWT to implement these GUI elements. BorderLayout is a class in the AWT used for setting up a particular type of layout of the elements in a GUI Window. Consult your JDK Package documentation for details. Here, we just have two elements we want to stack, and BorderLayout let's us do that easily.
/** The applets init method sets up the GUI */
public void init() {
/** The font to be used */
Font fontb = new Font("Helvetica",Font.BOLD,16);
// Now the GUI elements
header = new Label("INCOMING TRAPS");
header.setFont(fontb);
text = new TextArea("Start\n\n");
text.setEditable(false);
text.setFont(fontb);
setLayout(new BorderLayout());
add("North", header);
add("Center", text);
The following instantiates the SnmpAPI class, and sets the SnmpClient instance that will be used. This applet implements the SnmpClient interface and will be used to provide the callback.
// Start SNMP API
api = new SnmpAPI();
api.client = this;
} // end of init
The next function we need to implement is the start method. The start method first starts the SnmpAPI instance.
It then loads a MIB module via an URL (which in this case is just the name of the file, which is a relative URL on the applet host in the applet directory). MIB loading and parsing is slow and will cause the applet to be blank for some time before it paints it's screen. Not a good way to start really!
/** The start method, used when applet is started */
public void start() {
api.start();
// Next deal with MIBs
MibModule m1, m2;
try { // Open the MIB modules you want to use
String mib = getParameter("mib");
if (mib == null) mib = "rfc1213-MIB";
text.appendText("Loading MIB file: " + mib + "\n");
URL url = new URL(getDocumentBase(),mib);
InputStream stream = url.openStream();
m1= new MibModule(stream, api,api.DEBUG);
text.appendText("Done.");
} catch(Exception e) { System.err.println(e); }
// Open session and set local port
SnmpSession session = new SnmpSession(api);
See if the port parameter has been specified in the applet tag. We use a port number above 1024 to avoid the need for root priviledges. To use the standard SNMP TRAP port (162), we'd need to run as root on many systems. When we're using SAS, to use port 162 the SAS server would need to run as root on your Web Server - not something we recommend.
if (getParameter("port") != null)
try { session.local_port = Integer.parseInt(getParameter("port")); }
catch (NumberFormatException ex) { System.err.println("Invalid Integer
Arg"); }
else session.local_port = 4321;
We supply the applet instance (this) to the open method in our session, since we want to use SAS if needed and available. SAS will be used by the SNMP API if it is available, and if not, the API will try local access to sockets. So this application should work for both local loading and network loading of classes.
// Open the session
try { session.open(this); }
catch (SnmpException e) {
System.err.println(e);
System.exit(1);
}
text.appendText("Opened socket to listen for traps on port: " + session.local_port + "\n\n");
} // end of start()
The stop method stops the SnmpAPI instance and closes the sessions attached to it - in out case only one.
/** The stop method, used when applet is no longer on screen */
public void stop() {
if (api == null) return;
api.stop();
// close each session
for (Enumeration e = api.sessionList.elements();e.hasMoreElements();)
((SnmpSession)e.nextElement()).close();
}
This callback method is invoked by the API whenever a valid SNMP PDU comes in. We'll use it to simply print the trap and return.
public boolean callback(SnmpSession session, SnmpPDU pdu, int reqid) {
if (pdu.command != api.TRP_REQ_MSG)
System.err.println("Non trap PDU received, printing anyway.");
text.appendText("Trap received from: "
+pdu.address+", community: " + pdu.community + "\n");
pdu.enterprise.getNode(api); // See if we have the MIB node
text.appendText("Enterprise: " + pdu.enterprise + "\n");
text.appendText("Agent: " + pdu.agent_addr + "\n");
text.appendText("TRAP_TYPE: " + pdu.trap_type + "
");
text.appendText("SPECIFIC NUMBER: " + pdu.specific_type +
"\n");
text.appendText("Time: " + pdu.time+"\nVARBINDS:\n");
for (Enumeration e = pdu.variables.elements() ; e.hasMoreElements()
;)
text.appendText(((SnmpVarBind) e.nextElement()).toTagString() + "\n");
text.appendText(""); // a blank line between traps
return true; // need no more processing
} // end of callback()
Although, we need to implement the other methods in SnmpClient, we don't have to actually do anything, except ensure a true return on authenticate if we want PDUs to pass authentication.
/** We need to implement the other methods in the SnmpClient interface */
public void debugPrint(String s) {}
public boolean authenticate(SnmpPDU pdu, String community) {return true;}
}
To test this applet, use the snmptrap Java application or any other trap generator application and send traps to the port we've used (4321 if you haven't changed it). Remember, if you're using SAS the trap port is on your Web Server. The MIB Browser applet provides a more detailed example of an applet using the Snmp Package.