DIGITAL TCP/IP Services for OpenVMS
eSNMP Programming and Reference


Previous Contents Index


Chapter 4
Creating a Subagent Using the eSNMP API

This chapter describes how to use the eSNMP API to create a MIB subagent that manages entities or applications. Topics included in this chapter are:

Note

To use this eSNMP API to create a subagent, you must have a C compiler running on your host system.

4.1 Creating a MIB Specification

The creation of a management information base (MIB) begins with data gathering. During this phase, the developer identifies the information to manage based on what entities the network manager needs to manipulate. After gathering the data, the developer uses Abstract Syntax Notation One (ASN.1) to specify the objects in the MIB.

4.2 The Structure of Management Information

The structure of management information (SMI), which is specified in RFC 1155, defines the general framework within which a MIB can be defined and constructed. The SMI framework identifies the data types that can be used in the MIB and how resources within the MIB are represented and named.

SMI avoids complex data types to simplify the task of implementation and to enhance interoperability. To provided a standard representation of management information, the SMI provides standard techniques for the following:

4.2.1 Assigning Object Identification Codes

Associated with each object in a MIB is an identifier of the ASN.1 type called an object identifier (OID). OIDs are unique integers that follow a hierarchical naming convention.

Each OID has two parts: a pre-assigned portion and a developer-assigned portion. The pre-assigned portion, is always represented on the SMI tree as 1.3.6.1 or iso (1), org (3), dod (6), Internet (1). The second portion is for private development of MIBs.

Note

Your organization may require you to register all newly assigned OIDs.

In addition to an OID, you should also assign a name to each object to help with human interpretation.

Figure 4-1 illustrates the SMI hierarchical tree arrangement as specified in RFC 1155.

4.2.2 Defining Objects

The consistency of the MIB module is addressed in RFC 1212 which provides textual definitions within object-type macros. These object-type macros consist of the following elements:

Each resource that a MIB manages is represented by an object.

Figure 4-1 MIB-II in SMI Tree Structure


4.3 Creating a MIB Source File

Creating the MIB source files is basically a four-step process and is described in the following sections:
  1. Writing the ASN.1 input files ( Section 4.3.1)
  2. Processing the input files with the MIB compiler ( Section 4.3.2)
  3. The Subtree_TBL.H output files ( Section 4.3.3)
  4. The Subtree_TBL.C output files ( Section 4.3.4)

4.3.1 Writing the ASN.1 Input Files

Once you have assigned names and OIDs to all of the objects in the MIB, create an ASN.1 source file using ASCII statements.

Note

Providing information on ASN.1 syntax and programming is beyond the scope of this guide. For more information on ASN.1 programming, refer to one or more of the documents on this subject provided by the International Organization for Standardization (ISO).

4.3.2 Processing the Input Files with the MIB Compiler

The next step is to process each ASN.1 source file with the MIB compiler which generates modules used by the subagent developer. You should run the MIB compiler once for each set of MIB source files that relate to a specific subagent. This means that you should run the MIB compiler once for all of the MIBs associated with a particular subagent. Processing files in this manner allows you to process all of a subagent's MIB by issuing a single command. To update a MIB, you must re-issue the command and all of the associated MIBs.

Each ASN.1 input file that is processed in the MIB compiler yields two output files: a <subtree>_TBL.H file and a <subtree>_TBL.C file.

The syntax for the MIBCOMP command that processes the input file is as follows:


$ MIBCOMP  <MIB-source-files>  <subtree> 
[/PREFIX=<name>] [/PRINT]

Table 4-1 defines the MIBCOMP command qualifiers.

Table 4-1 MIBCOMP Command Definition
Qualifier/Option Definition
<MIB-source-files> A list of MIB source files, specified in the order of hierarchy precedence.
<subtree> The subtree on which you wish to the base the OID structure.
/PREFIX=<name> String with which you wish to prefix all generated names.
/PRINT Display entire MIB subtree.

The following is an example of processing input files with the MIB compiler:


 
$ mibcomp  RFC1442.MY, CHESS_MIB.MY  DEC 
 
Processing RFC1442.MY 
Processing CHESS_MIB.MY 
11 objects written to dec_tbl.c 
11 objects written to dec_tbl.h 
 
 
$ mibcomp RFC1442.MY, CHESS_MIB.MY dec /print 
 
Processing RFC1442.MY 
Processing CHESS_MIB.MY 
Dump of objects in lexical order 
    -- This file created by program 'snmpi -p' 
 
ccitt                                    0 
iso                                      1 
 internet                                1.3.6.1 
  directory                              1.3.6.1.1 
  mgmt                                   1.3.6.1.2 
  experimental                           1.3.6.1.3 
  private                                1.3.6.1.4 
   enterprises                           1.3.6.1.4.1 
    dec                                  1.3.6.1.4.1.36 
     ema                                 1.3.6.1.4.1.36.2 
      sysobjectids                       1.3.6.1.4.1.36.2.15 
       decosf                            1.3.6.1.4.1.36.2.15.2 
        chess                            1.3.6.1.4.1.36.2.15.2.99 
 
                                .     .     . 
 
  security                               1.3.6.1.5 
  snmpV2                                 1.3.6.1.6 
   snmpDomains                           1.3.6.1.6.1 
   snmpProxys                            1.3.6.1.6.2 
   snmpModules                           1.3.6.1.6.3 
joint_iso_ccitt                          2 
-------------------------- 
11 objects written to dec_tbl.c 
11 objects written to dec_tbl.h 
 
$ 
 

4.3.3 The Subtree_TBL.H Output Files

The file <subtree>_TBL.H contains the following information:

The first section of the file is a declaration of the subtree structure. The subtree is automatically initialized by code in the <subtree>_TBL.C file. A pointer to this structure is passed to the esnmp_register routine to register a subtree with the master agent. All access to the object table for this subtree is through this pointer. The declaration has the following form:

extern SUBTREE subtree subtree;

The second section of the file contains index definitions for each MIB variable in the SUBTREE of the form:

#define I_ mib-variable nnn

These values are unique for each MIB variable within a subtree and are the index into the object table for this MIB variable. These values are also generally used to differentiate between variables that are implemented in the same method routine so they can be used in a switch operation.

The third section contains enumeration definitions for those integer MIB variables that are defined with enumerated values, as follows:

#define D_ mib-variable_enumeration-name value

These are useful since they describe the value that enumerated integer MIB variables may take on. For example:


/* enumerations for gameEntry group */ 
   #define   D_gameStatus_complete         1 
   #define   D_gameStatus_underway         2 
   #define   D_gameStatus_delete           3 

The next section contains the MIB group data structure definitions of the form: typedef structxxx{


     type        mib-variable; 
   . 
   . 
   . 
     char        mib-variable_mark; 
   . 
   . 
   . 
     } mib-group_type 

One of these data structures is emitted by the MIB compiler for each MIB group within the subtree. Each structure definition contains a field representing each MIB variable within the group. In addition to the MIB variable fields, the structure includes a 1-byte mib-variable_mark field for each variable. You can use these for maintaining status of a MIB variable. For example, the following is the group structure for the chess MIB:


typedef struct _chess_type { 
    OID   ches; 
    int   chessMaxGames; 
    int   chessNumGames; 
 
    char chessProductID_mark; 
    char chessMaxGames_mark; 
    char chessNumGames_mark; 
} chess_type; 

Although MIB group structures are provided for your use, you are not required to use them. You can use the structure that works best with your method routines.

The next section describes the method routine prototypes. Each MIB group within the subtree has a method routine prototype defined. A MIB group is a collection of MIB variables that are leaf nodes that share a common parent node.

There is always a function prototype for the method routine that handles the Get, GetNext, and GetBulk operations. If the group contains any writeable variables, there is also a function prototype for the method routine that handles Set operations. Pointers to these routines appear in the subtree's object table which is initialized in the <subtree>_TBL.C module. You must write method routines for each prototype that is defined, as follows:

extern int<mib-group>_ get(METHOD *method)

extern int<mib-group>_ set(METHOD *method)

For example:


 
extern int chess_get(METHOD *method); 
 
extern int chess_set(METHOD *method); 
 

4.3.4 The Subtree_TBL.C Output Files

The <subtree>_TBL.C file contains the following three sections:

The first section is an array of integers used as the OID of each MIB variable in the subtree, for example:


static unsigned int elems[] = { ... 

The next section is an array of OBJECT structures. There is one OBJECT for each MIB variable within the subtree.

An OBJECT represents a MIB variable and has the following fields:

The master agent has no knowledge of object tables or MIB variables. It only maintains a registry of subtrees. When a request for a particular MIB variable arrives, it is processed as shown in the following example (where the MIB variable is mib_var and the subtree is subtree_1):

  1. The master agent finds which subagent registered subtree_1 contains (for Get or Set routines or might contain (for GetNext routines mib_var).
  2. The master agent sends an eSNMP message to the subagent who registered subtree_1):
  3. The subagent consults its list of registered subtrees and locates subtree_1.
  4. The subagent searches the object table of subtree_1 and locates the following:
  5. Then the appropriate method routine is called. If the method routine completes successfully, the data is returned to the master agent. If the method routine fails when doing a Get or Set, an error is returned. If the method routine fails when doing a GetNext, the code keeps trying subsequent objects in the object table of subtree_1 until either a method routine returns success or the table is exhausted. In either case, a response is returned.
  6. If the master agent detects that subtree_1 could not return data on a Next routine, it recursively tries the subtree lexicographically after subtree_1.

The last section is the SUBTREE structure itself. A pointer to this structure is passed to the eSNMP library routine esnmp_register to register the subtree. It is through this pointer that the library routines find the object structures. The following is an example of the chess subtree structure:


SUBTREE chess_subtree = { "chess", "1.3.6.1.4.1.36.2.15.2.99", 
                        { 11, &elems[0] }, objects, I_moveStatus}; 

The SUBTREE structure has the following elements:

4.4 Including the Routines and Building the Subagent

After you finish defining the objects in your MIB and running the method routines through the MIB compiler to flush out the Set and Get routines, do the following to create the MIB subagent:

  1. Set up eSNMP handshake by running the main routine.
  2. Use the cc/include command to compile.
  3. Link the method routines with the library routines by running the following command:
    link <subtree>_TBL.C sys$lib:tcpip$esnmp_shr.exe


Chapter 5
Reviewing the Developer's Kit

This chapter provides reference information about the routines in the eSNMP developer's kit. This chapter provides the following sections:

5.1 Interface Routines

The interface routines are provided to developers writing the portion of the application programming interface (API) that handles the connection between the agent and the subagent. The interface routines include the following:


esnmp_init

Initializes the Extensible SNMP (eSNMP) subagent locally, and initiates communication with the master agent.

Format

int esnmp_init (int *socket, char *sub-agent_identifier)


Arguments

socket

The address of the integer that receives the socket descriptor used by eSNMP.

sub-agent_identifier

The address of a null-terminated string that uniquely identifies this subagent (usually a program name).

Description

Call this routine during program initialization or to restart the eSNMP protocol. If you are restarting, the esnmp_init routine clears all registrations so each subtree must be registered again.

You should attempt to create a unique subagent identifier, perhaps using the program name argv[0] and additional descriptive text. The master agent does not open communications with a subagent whose subagent identifier is already in use.

This routine does not block waiting for a response from the master agent. After calling the esnmp_init routine, call the esnmp_register routine for each subtree that is to be handled by the subagent.


Return Values

Status ESNMP_LIB_NO_CONNECTION Could not initialize or communicate with the master agent. Try again after a delay.
ESNMP_LIB_OK The esnmp_init routine has completed successfully.

esnmp_(un)register

Requests registration of a single MIB subtree.

Format

int esnmp_register (subtree *subtree, int timeout, int priority *sub-agent_identifier)


Arguments

subtree

A pointer to a subtree structure corresponding to the subtree to be handled. The code emitted by the MIB compiler files (xxx_tbl.c and xxx_tbl.h, where xxx is the subtree name) externally declare and initialize the subtree structures.

timeout

The number of seconds the master agent should wait for responses when requesting data in this subtree. This value must be between 0 and 10. If the value is 0, the default timeout is 3 seconds. DIGITAL recommends you use the default.

priority

This is the registration priority. The entry with the largest number has the highest priority. The range is 0 to 65535. The subagent that registers a subtree with the highest priority over a range of object identifiers OIDs gets all requests for that range of OIDs.

Subtrees registered with the same priority are ranked in order by time of registration. The most recent registration has the highest priority.

The MIB-II subtrees registered by the os_mibs module provided with eSNMP software register at priority 1.


Description

Before the master agent can pass eSNMP requests on to the subagent, it must register the willingness to process all messages for MIB variables subordinate to a subtree identifier.

Call the initialization routine esnmp_init prior to calling the esnmp_register. Call the esnmp_register function for each subtree structure corresponding to each subtree to be handled. At any time, subtrees can be unregistered by calling esnmp_unregister and then be reregistered by calling the esnmp_register.

When restarting the eSNMP protocol by calling esnmp_init, all registrations are cleared. All subtrees must be reregistered.

A subtree is identified by the base MIB name and its corresponding OID number of the node that is the parent of all MIB variables contained in the subtree. For example: The MIB-II tcp subtree has an OID of 1.3.6.1.2.1.6. All elements subordinate to this have the same first seven digits and are included in the subtree's object table. The subtree can also be a single MIB object (a leaf node) or even a specific instance.

By registering a subtree, the subagent indicates that it will process eSNMP requests for all MIB variables (or OIDs) within that subtree's range. Therefore, a subagent should register the most fully qualified (longest) subtree that still contains its instrumented MIB variables.

The master agent does not permit a subagent to register the same subtree more than once. However, subagents may register subtrees with ranges that overlap the OID ranges of subtrees previously registered and subagents may also register subtrees registered by other subagents.

For example, TCP/IP for OpenVMS supports MIB-II. In the eSNMP environment, the product ships a subagent that does not register MIB-II (1.3.6.1.2.1). Instead eSNMP registers the following MIBs: system, interfaces, at, ip, icmp, tcp, udp, and snmp.

In addition to these MIBs, TCP/IP for OpenVMS also registers the Host Resource MIB.

All of these MIBs are registered at priority 1. Any subagent that registers at a higher priority (greater than 1), will override these registrations.


Return Values

Note

This status indicates only the initiation of the request. The actual status returned in the master agent's response is returned in a subsequent call to the esnmp_poll routine.
ESNMP_LIB_OK The esnmp_register routine has completed successfully.
ESNMP_LIB_BAD_REG The esnmp_init routine has not been called, the timeout parameter is invalid, or the subtree has already been queued for registration.
ESNMP_LIB_LOST_CONNECTION The subagent has lost communications with the master agent.

Example


 
#include <esnmp.h> 
#define RESPONSE_TIMEOUT     0    /* use the default time set 
                                     in OPEN message */ 
#define REGISTRATION_PRIORITY 10  /* priority at which subtrees 
                                     will register */ 
 
extern SUBTREE ipRouteEntry_subtree; 
 
status = esnmp_register( &ipRouteEntry_subtree, 
                         RESPONSE_TIMEOUT, 
                         REGISTRATION_PRIORITY ); 
if (status != ESNMP_LIB_OK) {" 
    printf ("Could not queue the 'ipRouteEntry' \\n"); 
    printf ("subtree for registration\\n"); 
} 
 


Previous Next Contents Index