Chapter 7. Rudimentary NMS Software Components

It's one thing to talk about NMS components; it's quite another to actually build them. In this chapter we see how to build and use SNMP code components. Using some custom software in conjunction with two commercial SNMP APIs, we provide some low-level elements of an NMS. The software is far from production standard (improvements are suggested later) and was written purely as a learning aid to show some of the nuts and bolts of SNMP. Two example programs are provided: one using Microsoft Visual C++ and the other using the Sun Microsystems Java Development Management Kit (JDMK) version 4.2. It is interesting to compare the two APIs from the viewpoint of the SNMP versions supported, platform-independence, speed, and other features. Both programs are driven from user-supplied command-line parameters, and a set of DOS batch files is provided to facilitate ease of use.

The first item of prototype software we look at is a small program called snmpmgr.exe, written using the Microsoft Visual C++ V6.0 SNMPv1 API. This program provides the following services:

  • Sends a GetRequest/SetRequest to a specified SNMPv1 agent

  • Receives a GetResponse from the specified SNMPv1 agent

  • Performs a walk of a specified agent MIB table

  • Receives a Trap PDU from a specified SNMPv1 agent

The program is written so that it can be run from the command line with the user specifying:

  • The remote SNMP agent IP address or DNS name

  • The remote SNMP agent community name

  • The required MIB object identifier instance

  • The value (for SET operations only) of the object instance

To receive traps, the user just presents the word TRAP on the program command line. This registers the program to receive traps from an agent. The agent in question must be configured to send its traps to the host running the program. The configuration steps will be described.

The ability to run from the command line allows for the program to be incorporated into a batch file (i.e., a script file) so that many SNMP-based operations can be executed.

We hope that the source code examples will help to solidify some of the concepts introduced in the book so far. In order not to restrict the user to a PC (running Microsoft Windows) platform, we also provide a short sample of similar capability using the Sun Microsystems JDMK toolkit. Because the latter is built using Java, it has multiplatform capability. A noteworthy aspect of JDMK is the brevity of the example program.

All source code provided in this chapter is available for download on the Prentice Hall Web site: [PrenticeHall] in the location provided in the Preface.

Building a Rudimentary Management System

An NMS consists of a minimum of the following items:

  • SNMP manager

  • MIBs

  • Database

  • SNMP agents

We now focus on building the bare essentials of the first component only, the SNMP manager. This manager can target specific SNMP agents on any IP-reachable (and SNMP-reachable) machine for which the appropriate community rights exist. MIB objects are accessible to the manager by specifying an OID on the program command line. The program we construct in this section can be seen as the first step to producing a more complete NMS. For this reason, we don't provide a database facility but instead use the program command line as our data source. Similarly, the data sink is just the console output rather than a GUI or database. The examples use the standard SNMP services provided with the Windows NT/2000 platforms.

Configuring SNMP on Windows NT/2000

The Windows NT/2000 product line includes an SNMPv1 agent as a service. This allows the user to switch on/off and configure the operation of the agent via the Windows GUI. We will configure the SNMP Service so that the public community name rights are read-write. This allows for SNMP SET operations to be performed against the agent. On NT, please follow these steps:

  1. Click on the desktop Start button, then click on Settings

  2. Select Control Panel

  3. Select Services and scroll down to the SNMP Service

The rights for the community name can be changed from here. If the SNMP Service is not present, then it can be added as follows: double-click the Control Panel Network icon and select the Services tab. Next, click the Add button, and then scroll down to the SNMP Service item. Click OK to add the service—it may be necessary to insert the NT/2000 installation CD.

On Windows 2000, the Services are accessed by double-clicking the Control Panel Administrative Tools icon. Double-click the Services icon, then right-click the SNMP Service and select the Properties option; this allows for the community rights to be set appropriately. On both NT and Windows 2000, the agent can be configured to send SNMP traps to a specified address. The trap destination for our purposes should be set as the host PC IP address (or DNS name)—the machine on which the sample program executes.

Setup Required for the Visual C++ Program

The supplied software was tested in the following environments:

  • Windows NT Workstation Version 4.00 Build 1381 Service Pack 6a

  • Windows 2000 Version 5.0.2195 Service Pack 2 Build 2195

On both of these platforms, the TCP/IP protocol stack was functioning with the SNMP Service configured. The agent used was one both local to and remote from the host running the manager.

Building the Sample Visual C++ SNMP Manager

If it is required to build the Visual C++ program, then the files in Figure 7-1 should be downloaded from the Prentice Hall Web site [PrenHallCodeWeb]:

The Visual C++ SNMP Manager files.

Figure 7-1. The Visual C++ SNMP Manager files.

The purpose of these files is now briefly described:

  1. Get.bat executes a single SNMP GET operation against the agent.

  2. Set.bat executes a single SNMP SET operation against the agent.

  3. Walk.bat walks the contents of a specified agent MIB table.

  4. Gettraps.bat prepares the program for receiving SNMP traps.

  5. Getnext.bat executes a single SNMP getNext operation against the agent.

  6. snmpdefs.h is a header file containing data types, global variables, and function declarations.

  7. snmpmgr.c contains the C code for the program.

  8. snmpmgr.exe contains the executable file for the program.

The program snmpmgr.exe was built using Microsoft Visual C++ Version 6.0. To build the source code, the simplest method is to search Visual C++ for an SNMP example program called snmputil. Our example was originally based on this Microsoft sample program (our source code is a completely rewritten version). Open the Microsoft example and delete the C and header files (one of each), and then select Add Files and choose our two files (snmpmgr.c and snmpdefs.h). Change the target executable to snmpmgr.exe. The project should then build successfully.

To run the example (without building it), copy snmpmgr.exe into a directory called debug located immediately underneath the location of the above files. If the program is built using Visual C++, then the debug directory should be created automatically along with the target executable. In either case, the batch files should run successfully.

Our two files snmpdefs.h and snmpmgr.c are now described.

The Source Code Components of snmpmgr.exe

The files snmpdefs.h and snmpmgr.c provide the codebase for our elementary management system. We now describe the principal elements of this program: The source code listing is contained in Appendix D, “Visual C++ Sample Program Source C.” The contents of the header file snmpdefs.h are illustrated in Figure 7-2. We added line numbers and section headings to make it easier to follow the description that follows. The header file snmpdefs.h is made up of three sections.

Example 7-2. snmpdefs.h: The API for our rudimentary management system.

    /****************** SECTION 1 ******************/
1  #define TIMEOUT 6000 /* milliseconds */
2  #define RETRIES 3
3  #define MAX_OID_NAME_LENGTH 50
4  #define FUNCTION_SUCCESS 0
5  #define FUNCTION_FAILED -1

/****************** SECTION 2 ******************/
6  enum Operations { GET, GETNEXT, SET, WALK, TRAP };
7  char * operationsArray[5] = { "GET", "GETNEXT", "SET", "WALK", "TRAP" };
8  INT programMode, operation;
9  LPSTR SNMPAgentName, SNMPCommunity, OIDstring;
10 RFC1157VarBindList variableBindings;
11 LPSNMP_MGR_SESSION SNMPsession;
12 AsnAny retrievedInstanceValue;
13 INT timeout = TIMEOUT;
14 INT retries = RETRIES;
15 BYTE requestType;
16 AsnInteger errorStatus, errorIndex;

/****************** SECTION 3 ******************/
17 int allocateResources(LPSTR agentName, LPSTR community, char *objectIdentifier);
18 int deallocateResources();
19 int prepareForOp(enum Operations reqOperation, LPSTR agentName, LPSTR community, char
snmpdefs.h: The API for our rudimentary management system. *objectIdentifier, char *objectValue);
20 int prepareDataForOperation(enum Operations reqOperation, unsigned char *newObjectValue);
21 int prepareSetOperation(unsigned char *newObjectValue);
22 int prepareGetOperation();
23 int prepareGetNextOperation();
24 int dispatchOperation(int programMode, char * argumentVector[]);
25 int createSNMPSession();
26 int executeRequest();
27 int displayMIBInstanceValue();
28 int doSnmpOperation(enum Operations reqOperation, LPSTR agentName, LPSTR community,
snmpdefs.h: The API for our rudimentary management system. char *objectIdentifier, char *objectValue);
29 int executeMibWalk();
30 int waitForTraps();
31 int startupRoutine (int argc, char *argv []);

Snmpdefs.h Lines 1 to 5

Section 1 provides five symbolic constants for SNMP operations, comprised of the following:

  • Line 1Timeouts occur when an operation (such as a GET) is executed and for some reason no response is received. There are many reasons for this; for example, the agent or network may be down, or the message may have been rejected due to incorrect security information. Timeouts are used to allow the manager to close down an operation rather than wait indefinitely.

  • Line 2Retries are needed for situations in which a message is lost or rejected due to some temporary problem. An example is a busy agent. Another is a lost message—remember that SNMP uses UDP, an unreliable datagram service. Typically, retries work in conjunction with timeouts, as we'll see in Figure 7-11.

  • Line 3Maximum length permitted for an object identifier.

  • Lines 4–5Function success and failure codes.

The SNMP API uses the first three constants.

Snmpdefs.h Lines 6 to 16

Section 2 provides global variables. It is not necessary for many of these to have global scope, but they are made global in this example for simplicity. Some of the data objects are specific to the Microsoft SNMP API:

  • Line 6Operation indicator to store the SNMP operation type (GET, SET, etc.).

  • Line 7Operation array to store the SNMP operation name, (GET, SET, etc.).

  • Line 8Program mode integer.

  • Line 8Program operation integer.

  • Line 9String for storing the remote SNMP agent IP address or DNS name.

  • Line 9String for storing the SNMP community name.

  • Line 9String for storing the specified object identifier.

  • Line 10Container for the SNMP PDU variable bindings.

  • Line 11SNMP session pointer.

  • Line 12Container for retrieved objects.

  • Line 13Timeout global variable.

  • Line 14Global variable for storing the number of permitted retries.

  • Line 15Request type global variable for storing the required SNMP operation type.

  • Line 16SNMP error indicator—tells us if an error or exception occurred.

  • Line 16SNMP error offset value—tells us the variable bindings offset with which the problem is associated.

Snmpdefs.h Lines 17 to 31

Section 3 lists the available function calls and is comprised of the following:

  • Line 17allocateResources() dynamically allocates required memory, creates an SNMP session, and sets up the variable bindings structure for the SNMP operations.

  • Line 18deallocateResources() deallocates memory, destroys the SNMP session object, and frees up the variable bindings structure.

  • Line 19prepareForOp() calls the allocateResources function and prepares for the specific operation (GET, GETNEXT, etc.).

  • Line 20prepareDataForOperation() sets up program mode for the required SNMP operation.

  • Line 21prepareSetOperation() indicates to the API to expect a SET operation and populates a variable bindings object ready for transmission to a remote SNMP agent as part of a SET operation.

  • Line 22prepareGetOperation() indicates to the API to expect a GET operation.

  • Line 23prepareGetNextOperation() indicates to the API to expect a GETNEXT operation.

  • Line 24dispatchOperation() issues the final call to the API for the required operation.

  • Line 25doSnmpOperation() makes the operation-specific call.

  • Line 26createSNMPSession() opens an SNMP session with the remote agent.

  • Line 27executeRequest() is the final port of call—the SNMP API is entered, and SET/GET message traffic is sent across the network.

  • Line 28displayMIBInstanceValue() presents the retrieved data to the user, showing the operation type, data type, and value.

  • Line 29executeMibWalk() carries out a lexicographic MIB walk using the supplied OID as the root.

  • Line 30waitForTraps() prepares the program for receiving incoming traps and displays them as they occur.

  • Line 31startupRoutine() parses the command line for program mode and any required parameter strings.

The Structure of the Sample Visual C++ Program

The sample program is not complex; it has a main() structure made up of just the following two lines:

startupRoutine (argumentCount, argumentVector);
dispatchOperation(programMode, argumentVector);

The first function validates the command-line parameters and determines the program mode (GET, SET, etc.). The second function executes the required operation. The full source code listing is included in Appendix A, “Terminal Server Serial Ports.”

The Supported Operations

Five operations are allowed with this manager:

  • GET

  • GETNEXT

  • SET

  • WALK

  • TRAP

The required operation is specified on the program command line. Overall, the external API provided by this program is a single function called:

int doSnmpOperation(enum Operations reqOperation, LPSTR agentName, LPSTR community, char
The Supported Operations *objectIdentifier, char *objectValue)

The program is invoked for a GET operation on the ipInReceives object value as follows, with a three-line response (commands typed by the user are shown in bold; system responses are delimited by angle brackets):

Debugsnmpmgr.exe GET myHostPC public .iso.org.dod.internet.mgmt.mib-2.ip.ipInReceives.0 NULL
< ***** THE SYSTEM RESPONSE NOW FOLLOWS ***** >
< SNMP Operation Type GET >
< MIB Object Instance = ip.ipInReceives.0 >
< Value    = Counter32 4929873 >

The parameters for this are as follows:

  • snmpmgr.exethe program name

  • GETthe required SNMP operation type

  • myHostPCthe target IP address or DNS name of the remote SNMP agent host

  • publicthe SNMP community name

  • .iso.org.dod.internet.mgmt.mib-2.ip.ipInReceives.0the required MIB object instance

  • NULLvalue for SET; not required for GET, hence the value is NULL

The remote (or local) agent responds to the message and the data sent back to snmpmgr.exe is presented as:

< SNMP Operation Type GET >
< MIB Object Instance = ip.ipInReceives.0 >
< Type and Value =  Counter32 4929873 >

The last two lines indicate the required MIB object instance and its value (in this case, the object is our old friend ipInReceives.0 and has the value 4929873). The supplied DOS batch files automate the process of running the program, freeing the user from having to type complex command lines. The batch files and their use are described in the following sections.

Using the Rudimentary Management System

The sample program can, if required, be run on the same host as the SNMP agent, as illustrated in Figure 7-3.

Processes and hosts in the rudimentary management system.

Figure 7-3. Processes and hosts in the rudimentary management system.

Alternatively, the program can be run using an SNMP agent on a remote machine.

Please Note For Running The Visual C++ Program

  1. We use just a single SNMP community string called public. Normally, you can expect to see at least two community strings—one for gets, called public, and one for sets, called private. We omitted this to reduce the complexity. Changing the batch files for this would be a good exercise because it would also be required to create the private community string in the agent configuration and to assign read-write capability.

  2. Only one change is required—the user must supply the IP address or DNS name for the SNMP agent host in each of the supplied batch files. For example, in the batch file Get.bat (see Figure 7-5), replace the word myHostPC with the IP address or DNS name of your SNMP agent host.

  3. The required platform for running the program is either Windows 2000 or NT.

MIB Table Used in the Examples

The MIB-II system table is used in our examples and is illustrated in Figure 7-4.

The MIB-II system table.

Figure 7-4. The MIB-II system table.

Figure 7-4 can be consulted during the following sections. The syntax for specifying MIB objects in the Microsoft SNMP API is to prefix each leaf with a period, starting with .iso. This is seen in the next section.

An SNMP GET

Double-clicking the batch file Get.bat (or running it from a command line) should result in a display similar to that shown in Figure 7-5.

Example 7-5. GET operation on system.sysContact.0.

Debugsnmpmgr.exe GET myHostPC public  .iso.org.dod.internet.mgmt.mib-2.system.sysContact.0
< SNMP Operation Type GET >
< MIB Object Instance = system.sysContact.0 >
< Type and Value = String StephenM >

Figure 7-5 illustrates a GET operation on a specific instance (zero in this case) of a columnar object from the standard system table—in this case, system.sysContact. We must specify the instance explicitly by appending a zero. The value of the returned object is illustrated as StephenM.

An SNMP GETNEXT

Double-clicking the batch file GetNext.bat (or running it from a command line) should result in a display similar to that shown in Figure 7-6.

Example 7-6. GETNEXT operation on system.sysContact.0.

Debugsnmpmgr.exe GETNEXT myHostPC public .iso.org.dod.internet.mgmt.mib-2.system.sysContact.0
< SNMP Operation Type GETNEXT >
< MIB Object Instance = system.sysName.0 >
< Type and Value = String myHostPC >

Figure 7-6 illustrates a GETNEXT operation on the sysContact object. Instead of returning StephenM, as in the last example, we receive the host system name. This is the lexical successor to the sysContact object, as can be seen from Figure 7-4.

An SNMP SET

We now move to a different category of SNMP operation, that of setRequest. This pushes data into the MIB of the remote agent. Interestingly, providing a set capability like this is often considered controversial because of security fears. These fears are generally well-founded, but we present sets here only in order to describe the principles, leaving aside any political issues. In this example, we set the value of the sysContact name to be StephenMorris. Recall from the GET example above that the value of this object is currently StephenM. Double-clicking the batch file Set.bat (or running it from a command line) should result in a display similar to that shown in Figure 7-7. We can verify that the operation succeeded by simply running Get.bat again.

Example 7-7. SET operation on the system.sysContact.0.

Debugsnmpmgr.exe SET myHostPC public .iso.org.dod.internet.mgmt.mib-2.system.sysContact.0
SET operation on the system.sysContact.0. StephenMorris
< SNMP Operation Type SET >
< MIB Object Instance = system.sysContact.0 >
< Type and Value = String StephenMorris >

Figure 7-7 illustrates a SET operation on the system.sysContact.0 object.

Walking a MIB Table

Suppose we want to get an idea of the MIB objects supported by a given agent, starting at a specific point in the tree. An SNMP walk provides this capability by traversing the MIB tree leaf objects until the end of that branch is reached. This is useful for retrieving tables (of unknown extent). Double-clicking the batch file Walk.bat (or running it from a command line) should result in a display similar to that shown in Figure 7-8. This is achieved by a dialog between the manager and the agent in which the former keeps sending GETNEXT messages until the end of the MIB table is reached.

Example 7-8. A MIB WALK on the system table.

Debugsnmpmgr.exe WALK myHostPC public .iso.org.dod.internet.mgmt.mib-2.system
< Variable = system.sysDescr.0 >
< Value    = String Hardware: x86 Family 6 Model 8 >
< Variable = system.sysObjectID.0 >
< Value    = ObjectID 1.3.6.1.4.1.311.1.1.3.1.1 >
< Variable = system.sysUpTime.0 >
< Value    = TimeTicks 1889968 > 
< Variable = system.sysContact.0 >
< Value    = String StephenMorris >
< Variable = system.sysName.0 >
< Value    = String myHostPC >
< Variable = system.sysLocation.0 >
< Value    = String Europe >
< Variable = system.sysServices.0 >
< Value    = Integer32 76 >
< End of MIB subtree. >

Figure 7-8 illustrates a WALK of the system table. Referring to Figure 7-4, it can be seen that all the columns in this table are retrieved up to and including the last object, sysServices.

An SNMP TRAP

The manager program can also be configured to listen for SNMP traps. This is illustrated by running the batch file GetTraps.bat. This puts the manager into listening mode, as can be seen in Figure 7-9. Next, we must simulate a trap. This can be done by simply stopping and starting the SNMP service, which results in the agent sending three traps, as illustrated in the bottom half of Figure 7-9.

Example 7-9. Listening for and receiving SNMP traps.

Debugsnmpmgr.exe TRAP
< snmputil: listening for traps. >
***** THE PROGRAM IS NOW AWAITING THE ARRIVAL OF TRAPS *****
***** WE NOW STOP AND THEN START THE SNMP SERVICE *****
snmputil: trap generic=0 specific=0  from -> 127.0.0.1  *** TRAP 1
snmputil: trap generic=3 specific=0  from -> 127.0.0.1  *** TRAP 2
Variable = interfaces.ifTable.ifEntry.ifIndex.1
Value    = Integer32 1
snmputil: trap generic=3 specific=0  from -> 127.0.0.1  *** TRAP 3
Variable = interfaces.ifTable.ifEntry.ifIndex.16777219
Value    = Integer32 16777219

Let's take a closer look at what's going on in Figure 7-9. Trap 1 has both generic and specific code values of zero, indicating that this is a coldStart, that is, the agent has restarted. This is a direct response to stopping and starting the SNMP service. The origin of this trap is the loopback IP address (127.0.0.1), indicating that the agent is located on the same host as the manager. Traps 2 and 3, respectively, have generic and specific codes of three and zero, indicating linkUp events. These relate to entries in the host system interfaces MIB table (ifTable). Two interfaces are present on the host machine (indicated by the MIB object ifNumber, which has the value 2 and is not shown); one is the software loopback interface (127.0.0.1), and the other is an Ethernet interface (16777219). When these interfaces go into the up state, the agent detects it and emits traps 2 and 3.

Combining the Batch Files

It is easy enough to chain these batch files together (or write entirely new ones) to carry out multiple operations in sequence—for example, to execute a SET followed by a GET. A real NMS tends to use a rich mix of all types of SNMP operations, for example, manipulating a range of scalar and tabular objects on a number of agents (as we'll see in Chapter 8).

A Security Violation

Security is increasingly important in network management. We now acknowledge this with a specific example of a simple security violation by using the wrong community name. This is equivalent to entering the wrong password during a login procedure. Modifying the community name in one of the batch files achieves the desired result. The remote agent should do two things:

  • Discard the message so that no reply should occur—this gives no clue to a hacker that he or she has supplied an incorrect community name.

  • Emit an authenticationFailure(4) trap—this informs the NMS operator that an intruder alert has occurred.

In a real network with stronger security (such as SNMPv3), the intruder might be attempting more sophisticated actions, such as replaying a captured message into an agent. In this case, the security system in the agent would rely on more advanced protection facilities, such as message timeliness checking. However, we illustrate the simple (wrong community string) case just to give a flavor of what might occur in a real network.

To see this, we must configure one session of the program to listen for traps and another to issue an improper SNMP Get. Figure 7-10 illustrates the GET with a modified (and invalid) community string of public1 (instead of public).

Example 7-10. Security failure and associated actions.

Debugsnmpmgr.exe GET myHostPC public1 .iso.org.dod.internet.mgmt.mib-2.system.sysContact.0
< error on SnmpMgrRequest 8 >
< SNMP Operation Type GET >
< MIB Object Instance = system.sysContact.0 >
< Type and Value = Null value >

In Figure 7-10, we see a Microsoft Visual C++ SNMP API error value of 8, indicating a problem with the submitted message.

If we initiate another instance of the program in trap mode (before running the Get in Figure 7-10), we see an interesting sequence of events, as illustrated in Figure 7-11. Four traps are received from the loopback address. So, what's happening here, and why do we see four traps?

Example 7-11. Security violations and retries.

Debugsnmpmgr.exe TRAP
< snmputil: listening for traps... >
< snmputil: trap generic=4 specific=0 from -> 127.0.0.1 >
< snmputil: trap generic=4 specific=0 from -> 127.0.0.1 >
< snmputil: trap generic=4 specific=0 from -> 127.0.0.1 >
< snmputil: trap generic=4 specific=0 from -> 127.0.0.1 >

Recall from Figure 7-2 that the program implements a retry mechanism (the RETRIES symbolic constant in snmpdefs.h). A maximum of three retries is allowed. So, the first GetRequest is sent to the agent. This message has an invalid community string and is discarded. The agent also issues a trap with a generic code of 4 (indicating an authenticationFailure). This explains the first trap. Our manager code is not very sophisticated and fails to correlate the authentication failure trap with the bad GetRequest message. Having failed to get the expected response, the manager then transparently (via the SNMP library code) retries the operation a total of three more times; this results in three more traps before the manager code finally gives up. This explains the sequence of four traps in Figure 7-11. One final point about Figure 7-11 is that the timeout mechanism is also initiated as a result of the (attempted) security breaches. Again from Figure 7-2, we note that there is a timeout defined as 6,000 milliseconds or 6 seconds. This is the time between retries and explains the small delays between the occurrence of the traps in Figure 7-11.

A Note On Security

The preceding discussion leads into another very important area: that of attacks against networks and management system components. The sheer quantity of attacks against networks is surprising—thousands are independently recorded annually. An entire book could be dedicated to this subject. Networks can be subjected to the following types of attacks, among many others:

  • HackingAttempting to gain unauthorized access to agent data (as above)

  • Denial of serviceFlooding an agent with bogus messages, such as GetRequests

  • Message interceptionListening for and capturing messages in transit

  • Message modificationModifying the contents of messages in transit

  • Message replayCapturing and then resending messages

It is surprising how unprotected many networks are [CERTWeb], and the emphasis on security is certain to increase. Protection must be applied throughout the network from the very top of the management system software pyramid (introduced in Chapter 1) to the NEs and agents deployed in the network.

We now move onto our second sample program, this time using Java.

The Sample JDMK Java SNMP Manager

Evaluation copies of the JDMK toolkit can be downloaded from Sun Microsystems' Web site [SunMicrosystems]. Included with JDMK is a rich mix of sample Java programs that use the internal class library. In this section, we describe a handcrafted program that uses JDMK to implement the following SNMP requests:

  • GetRequest

  • GetNext

In effect, this is a cutback version of our earlier Visual C++ program. JDMK programs can interact with either the JDMK sample agent provided by Sun or with any other legacy agent. To illustrate this interoperability, we use the standard Windows 2000/NT SNMP agent as the target of our JDMK SNMP Get/GetNext messages (rather than using the JDMK sample agent). This is an interesting illustration of the mature and standard nature of SNMP technology in general. The full source code for the Java program is located in Appendix B, “Some Simple IP Routing Experiments.”

Just as for the C++ sample, we provide companion DOS batch files to simplify use of the program.

Installing JDMK

A number of Sun Microsystems' software applications are needed for our Java example. The following installation steps were followed (for Windows NT) in order to set up JDMK:

  1. Install the Java Development Kit (JDK)We used the Java 2 SDK Standard Edition v1.3.1_02.

  2. Install JDMKWe used JDMK 4.2 for JDK 1.1.8.

  3. Install JDMKWe used JDMK 4.2 for Java 2 Platform.

Step 2 may not be necessary.

Installation of JDMK involves running two downloaded batch files called Setup.bat—this extracts the JDMK class files (jdmk42_nt_12.class and jdmk42_nt_11.class, respectively).

Next, the environment variables must be set. We created one variable (JDMKPATH) and modified two others for this:

  1. JDMKPATH

  2. The system PATH

  3. The Java CLASSPATH

The values we assigned to these variables are:

JDMKPATH=C:Program FilesSUNWjdmkjdmk4.21.2
PATH=%JDMKPATH%in;C:jdk1.3.1_02in
CLASSPATH=%JDMKPATH%libcollections.jar;%JDMKPATH%libjdmkrt.jar;%JDMKPATH%libjdmktk.jar;.

The syntax %JDMKPATH% is simply a shorthand form for the fully expanded contents of JDMKPATH. One last point is to make sure to include the period (for the current directory) at the end of the CLASSPATH.

Last Steps in the Setup

To use the NT SNMP agent, make sure to apply NT Service Pack 6a. Also, ensure that the SNMP agent has two configured community strings (the Visual C++ program used just one community string):

  • public (read-only)

  • private (read-write)

It should be possible to successfully run the examples once these steps have been taken. Please note that the two managers were run only on a Windows NT Workstation (Version 4.00 Build 1381) with Service Pack 6a. Windows 2000 was used only for the agent.

Building the Sample Java Manager

If it is required to build the Java program, then the files in Figure 7-12 should be downloaded from the Prentice Hall Web site [PrenHallCodeWeb]:

The JDMK SNMP manager project files.

Figure 7-12. The JDMK SNMP manager project files.

The purpose of these files is now briefly described:

  1. mib_II.txt contains the definition of the MIB II standard objects.

  2. SynchronousManager.java contains the Java class that sends either an SNMP GET or getNext message.

  3. Get.bat executes a single SNMP GET operation against the agent.

  4. GetNext.bat executes a single SNMP getNext operation against the agent.

Once the Java class files are created in the next section, it is possible to run the batch files.

To Build the Java Program

Two commands are required to build the Java program:

  1. mibgen -mo -d . mib_II.txt

  2. javac -d . *.java

The first command builds a file called RFC1213_MIBOidTable.java. The second command creates the bytecode file SynchronousManager.class. The latter is the binary (executable) file for the examples that follow.

An SNMP GET

To run the program, double-click on Get.bat to invoke Java and execute a GetRequest operation. This should result in a display similar to that shown in Figure 7-13.

Example 7-13. GET operation on the system.sysContact.0.

java SynchronousManager GET myHostPC public sysContact.0 NULL 161
< Sent GET request to agent on myHostPC port 161 >
< Result: [Object ID : 1.3.6.1.2.1.1.4.0  (Syntax : String) >
< Value : StephenMorris] >

Figure 7-13 illustrates a GET operation on the sysContact object from the standard system table. The object instance is hardcoded (i.e., there is no way for the value to be changed other than by a program source code change) internally to the program. The value of system.sysContact.0 is illustrated as StephenMorris. Recall that this object instance was set to its current value in Figure 7-7.

An SNMP GETNEXT

To run the program, double-click on GetNext.bat to invoke Java and execute a GetRequest operation. This should result in a display similar to that shown in Figure 7-14.

Example 7-14. GETNEXT operation on system.sysContact.0.

java SynchronousManager GETNEXT myHostPC public sysContact.0 NULL 161
< Sent GETNEXT request to agent on myHostPC port 161 >
< Result: [Object ID : 1.3.6.1.2.1.1.5.0  (Syntax : String) >
< Value : myHostPC] >

Figure 7-14 illustrates a GETNEXT operation on the sysContact object from the standard system table. As was the case with the C++ program, the GETNEXT response provides the lexical successor to the system.sysContact.0 object. This is the system.sysName.0 object and has the value myHostPC.

The Structure of the Synchronous Manager

The Java program is very simple indeed. All of the code is contained in one file that in turn contains a Java class called SynchronousManager. The command-line parameters are validated, and the required operation type is recorded as either GET or GETNEXT. The next nine lines prepare the API for making SNMP calls. The actual SNMP request is made in the method called:

public static void issueRequest(SnmpPeer agent, String operation, 
            SnmpVarBindList list, SnmpSession session, 
            String host, String port)

It is this method that issues the message and processes the agent response. Any exceptions that occur are caught in an overall try/catch block.

The Synchronous Java Manager

The JDMK API provides both synchronous and asynchronous operation. Synchronous operation simply waits for responses from the network, whereas asynchronous operation uses callbacks to allow the program to proceed with other tasks. A production-standard NMS tends to use asynchronous operation, or it may use synchronous calls in conjunction with multiple threads. In either case, the NMS should not simply block until a response is received. As we've seen, there is generally much ongoing work to be done by a given NMS as it strives to keep up to date with the managed network. So, execution time should never be squandered waiting for (possibly) tardy devices to respond.

Our examples are all synchronous in nature in order to illustrate the software components in as simple a fashion as possible.

Comparing the Visual C++ and JDMK 4.2 APIs

Table 7-1 shows a brief comparison between the Visual C++ and JDMK APIs.

Table 7-1. API Feature Comparisons

SNMP API

MULTI-PLATFORM

SNMPv1

SNMPv2

SNMPv3

JDMK 4.2

Yes – Java

Yes

Yes

No[*]

Visual C++

No

Yes

No

No

[*] SNMPv3 support is provided as part of JDMK 5.0.

An interesting exercise in interoperability is to mix and match the operation of the two programs, for example,

  1. Set the C++ program to listen for traps.

  2. Execute a security violation (using the wrong community name) with the Java program.

  3. Watch the traps coming back from the SNMP agent.

To compare the performance of the two APIs, a new batch file can be written to make multiple calls (e.g., 10 GETs) to one of the example batch files. The system time can be printed at the beginning and end of the new batch file, and from this, a very simple idea of the overall execution time can be derived.

In this case, the agent is (happily) communicating with two entities, one written in C++ and the other in Java. Though a relatively trivial test, this shows the platform-independent power of standardized protocols.

Ways to Improve the Two Sample Programs

Our two efforts are far from being production-standard code! There are many ways in which they both can be materially improved:

  • Make the operations asynchronous to free up resources when waiting on replies.

  • Move the parameters off the command line or provide them in encrypted form.

  • Make the programs independent of MIB object specifications—the existing structure is inflexible because a MIB change would require a code change.

  • Provide a facility for adding support for new MIBs.

  • Allow multiple OIDs in one PDU—this reduces traffic for multi-object operations.

  • Move all SNMP API code into a separate module or even a separate server. The latter would help to thin down the client programs.

  • Remove global variables.

  • Provide a non-debug version of the C++ program (faster and smaller).

  • Allow table-based operations, such as for getting and setting rows in a MIB table.

  • Provide an external data source other than the command line.

  • Support SNMPv3.

It is better to fulfill the above from the ground up, that is, before writing any code. The examples were written purely to try to make concrete some of the major SNMP concepts.

Extending the Sample SNMP Programs

The C++ or Java program samples can form the foundation of a more complex product. NMS typically take the form of a server with a number of distinct (possibly distributed) components, such as (in the FCAPS order):

  • A fault server that listens for traps from the managed network

  • A configuration (or provisioning) server that executes SNMP SET and GET operations

  • An accounting server that can apply rules (such as quotas or limits) to specific MIB object counters, such as setting an upper limit on the value of ipInReceives

  • A performance server that can perform mediation and also read the various counters supported in the NE MIBs

  • A security server that can be used to manage community strings, access control rights, encryption, and authentication details

Figure 7-15 illustrates one such arrangement with a central NMS server and multiple clients. Each client is dedicated to a specific network management function that it executes using the services of the central server. Client 1 is tasked with SLA reporting; that is, it retrieves data from the network relevant to SLAs. This data is then presented as reports, for instance, in HTML format. Client 2 configures the managed NEs by issuing requests (via the central server) to set and get managed objects in the network. Client 3 provides a billing/accounting function—usually this amounts to reading many objects. Clients 2 and 3 access the server using IPSec, and Client 1 uses HTTPS; all the clients are employing secure communications.

Extended snmpmgr.c handles multiple clients.

Figure 7-15. Extended snmpmgr.c handles multiple clients.

The important point to note about Figure 7-15 is that it is relatively straightforward to build a complex management system once the basic agent and manager entities are in place. Additional server components are:

  • Topology manager to handle icons, network maps, and device status

  • An access server that provides a queuing mechanism for handling simultaneous requests from more than one client user (this server could be part of the server in Figure 7-15)

The last two points move us out of the SNMP domain and are included just for completeness.

Summary

We've now seen two simple programs that were used to interact with the Windows NT/2000 SNMP agents. Written in Visual C++ and Java, respectively, these programs provide what might be considered the low-level bricks or widgets that can be brought together to form a more complex product. The latter could in turn be built upon to become an NMS. The choice of programming languages was driven by considerations such as multiplatform support (Visual C++ is restricted to Windows, Java is multiplatform), the version of SNMP that can be used, and so on. It is surprisingly straightforward to produce such software programs. Once written, the two example programs can be combined using the target SNMP agent as a type of programming language-independent traffic cop; for example, set the C++ program to receive traps, then send a bad getRequest from the Java program, and the agent will send an authentication failure trap message to the C++ program. In effect, the agent is indifferent to the sending program just as long as the messages it receives conform to the SNMP protocol.

We saw a security violation caused by the use of an incorrect community string. The receiving agent discards the message and emits an authentication failure trap. The manager should not then resend the erroneous message because the same failure will occur. In a sense, this could be construed as a type of unintentional attack on the agent.

The example programs can be extended and made into more complex NMS components that use, for example, database services and a multiclient GUI. An important design goal is providing support for SNMPv3—JDMK allows this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.93.137