Digital TCP/IP Services for OpenVMS
eSNMP Programming and Reference


Previous | Contents

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 hierarchial 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 yeilds 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:ucx$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"); 
    } 
     
    

    esnmp_poll

    Processes a pending message that sent by the master agent.

    Format

    int esnmp_poll ()


    DESCRIPTION

    This routine is called after the select() call has indicated data is ready on the eSNMP socket. (This socket was returned from the call to the esnmp_init routine.

    If a received message indicates a problem, an entry is made to the syslog file and an error status is returned.

    If the received message is a request for eSNMP data, the object table is checked and the appropriate method routines are called.


    Return Values

    ESNMP_LIB_OK The esnmp_poll routine completed successfully.
    ESNMP_LIB_BAD_REG The master agent failed in a previous registration attempt. See the log file.
    ESNMP_LIB_DUPLICATE An OPEN error occurred. A duplicate subagent identifier has already been received by the master agent.
    ESNMP_LIB_NO_CONNECTION The master agents OPEN request failed. Restart the connection after a delay. See the log file.
    ESNMP_LIB_CLOSE A CLOSE message was received. Restart the connection after a delay.
    ESNMP_LIB_NOTOK An eSNMP protocol error occurred and the packet was discarded.
    ESNMP_LIB_LOST_CONNECTION Communication with the master agent was lost. Restart the connection.

    esnmp_are_you_there

    Sends ICMP ECHO_REQUEST packets (ping) to the master agent.

    Format

    int esnmp__are_you_there ()


    DESCRIPTION

    The esnmp_are_you_there routine does not block waiting for a response. It is intended to cause the master agent to reply immediately. The response should be processed by calling the esnmp_poll routine.

    If no response is received within the timeout period, the application code restarts the eSNMP protocol by calling the esnmp_init routine. There are no timers maintained by the eSNMP library.


    Return Values

    ESNMP_LIB_OK The ICMP ECHO_REQUEST was sent.
    ESNMP_LIB_LOST_CONNECTION The ICMP ECHO_REQUEST packet cannot be sent because the master agent is down.

    esnmp_trap

    Sends a trap message to the master agent.

    Format

    int esnmp_trap (int *generic_trap, int specific_trap, char *enterprise, varbind *vb)


    ARGUMENTS

    generic_trap

    A generic trap code.

    specific_trap

    A specific trap code.

    enterprise

    An enterprise OID string in dot notation.

    vb

    A VARBIND list of data (a null pointer indicates no data).

    DESCRIPTION

    This function can be called any time. If eSNMP has not initialized through the master agent, traps are queued and sent when communication is possible.

    The trap message is actually sent to the master agent after it responds to the esnmp_init routine. This occurs with every API call and for most esnmp_register routines. The quickest process to send traps to the master agent is to call the esnmp_init, esnmp_poll, and esnmp_trap routines.

    The master agent formats the trap into an eSNMP trap message and sends it to management stations based on its current configuration.

    The master agent does not respond to the content of the trap. However, the master agent does return a value that indicates whether the trap was received successfully.


    Return Values

    ESNMP_LIB_OK The routine has completed successfully.
    ESNMP_LIB_LOST_CONNECTION Could not send the trap message to master agent.
    ESNMP_LIB_NOTOK Something failed and the message could not be generated.

    esnmp_term

    Sends a close message to the master agent and shuts down eSNMP.

    Format

    void esnmp_term (void)


    DESCRIPTION

    Subagents should call this routine when terminating, so that the master agent can update its MIB registry more quickly.

    Return Values

    ESNMP_LIB_OK The esnmp_term always returns ESNMP_LIB_OK even if the packet could not be sent.

    esnmp_sysuptime

    Converts UNIX system time obtained from gettimeofday into a value with the same time base as sysUpTime.

    Format

    unsigned int esnmp_sysuptime (struct timeval *timestamp)


    ARGUMENT

    *timestamp

    A pointer to struct timeval contains a value obtained from the gettimeofday system call. The structure is defined in include/sys/time.h.


    Previous | Next | Contents