# Compaq TCP/IP Services for OpenVMS
SNMP Programming and Reference

Previous | Contents | Index

### 3.3.2.4 The subtree_TBL.C Output Files

The subtree_TBL.C file file contains the following sections:

1. An array of integers representing the OIDs for each MIB variable
2. An array of OBJECT structures
3. An initialized SUBTREE structure
4. Routines for allocating and freeing the `mib_group_type`

The following sections describe each section of the subtree_TBL.C file.

1. Array of Integers Section

The first section of the subtree_TBL.C file is an array of integers used to represent the OID of each MIB variable in the subtree. For example:

    static unsigned int elems[] = {
          1, 3, 6, 1, 4, 1, 36, 2, 15, 2, 99,    /* chess */
          1, 3, 6, 1, 4, 1, 36, 2, 15, 2, 99, 1, 0, /* chessProductID */
    ...
          1, 3, 6, 1, 4, 1, 36, 2, 15, 2, 99, 5, 1, 4, 0, /* moveStatus */
    };

The first line represents the root of the tree; the other lines represent specific variables. The latter groups are all terminated by a zero, a programming convenience in internal implementations of API routines.

2. Array of OBJECT Structures Section

The second section of the subtree_TBL.C file is an array of OBJECT structures. Each MIB variable within the subtree has one OBJECT. The chess example produces the following:

    static OBJECT objects[] = {
       {I_chessProductID             ,{12, &elems[ 11]}, ESNMP_TYPE_ObjectId   ,chess_get, NULL},
    ...

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

- `object_index` --- The constant I_mib-variable from the subtree_TBL.H file, which identifies this variable (in the chess example, `I_chessProductID` .)
- `oid` --- The variable's OID (points to a part of `elems[]` ).
  This variable is of type OID, which is a structure containing two elements: the number of elements in the OID and a pointer to the correct starting place in the array of elements ( `elems[]` in the chess example).
  In the chess example, `oid` is designated by `{12, &elemens[ 11]}` . This indicates that:
  - The OID has 12 integers separated by dots in the ASCII text representation ( `"1.3.6.1.4.1.36.2.15.2.99.2"` )
  - The integer with index 11 in the array `elems[]` is the first element.
- `type` --- The variable's eSNMP data type.
- `getfunc` --- The address of the method routine to call for `Get` requests (null if no routine exists).
- `setfunc` --- The address of the method routine to call for `Set` requests (null if no routine exists).

The master agent does not access object tables or MIB variables directly. It only maintains a registry of subtrees. When a request for a particular MIB variable arrives, it is processed as shown in the following steps (where the MIB variable is `mib_var` and the subtree is `subtree_1` ):

1. The master agent finds `subtree_1` as the authoritative region for the `mib_var` in the register of subtrees. The authoritative region is determined as the registered MIB subtree that has the longest prefix and the highest priority.
2. The master agent sends a message to the subagent that registered `subtree_1` .
3. The subagent consults its list of registered subtrees and locates `subtree_1` .
   It searches the object table of `subtree_1` and locates the following:
   - `mib_var` (for `Get` and `Set` routines)
   - The first object lexicographically after `mib_var` (for `Next` or `Bulk` routines)
4. 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 successfully or the table is exhausted. In either case, a response is returned.
5. 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` until a subagent returns a value or the registry of subtrees is exhausted.

3. Initialized Subtree Structure Section

The third section of the subtree_TBL.C file 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 following table describes the elements of the SUBTREE structure, the definition of each element in the header file (subtree_TBL.H)), and the element in the chess example:

Description | Header File Representation | Example
--- | --- | ---
The name of the subtree's base element. | `name` | `"chess"`
The ASCII string representation of the subtree's OID. This is what actually gets registered. | `dots` | `"1.3.6.1.4.1.36.2.15.2.99"`
The OID structure for the base node of the subtree. This points back to the array of integers. | `oid` | `11, &elems[0] }`
A pointer to the array of objects in the object table. It is indexed by the `I_ xxxx` definitions found in the subtree_TBL.H file. | `object_oid` | `objects`
The index of the last object in the object_TBL file. This is used to determine when the end of the table has been reached. | `last` | `I_moveStatus`

4. Routines Section

The final section of the subtree_TBL.C file. contains short routines for allocating and freeing the `mib_group_type` . These are provided as a convenience and are not a required part of the API.

# 3.4 Including the Routines and Building the Subagent

The MIB compiler does not generate code for implementing the method routines for your subagent. This includes code for processing `get` , `set` , and other SNMP requests as well as for generating traps. You must write this code yourself. See the CHESS_MIB.C module for an example.

To produce executable subagent code, follow these steps:

1. Compile the C modules generated by the MIB compiler, along with your implementation code. Use a command in the following format (derived from the sample provided for building the chess example in TCPIP$BUILD_CHESS.COM):

       $ CC /INCLUDE=TCPIP$SNMP /PREFIX=ALL /STANDARD=VAX CHESS_METHOD.C, -
       _$ CHESS_MIB.C, CHESS_TBL.C

   Depending on the version of the Compaq C compiler you are using, you might see warnings that you can ignore. Portions of these warnings are as follows:

       %CC-I-SIGNEDKNOWN   In this declaration, DEC C recognizes the ANSI
                           keyword "signed".  This differs from the VAX C behavior.

       %CC-I-INTRINSICINT  In this statement, the return type for intrinsic
                           "strlen" is being changed from "size_t" to "int".

2. Link the object modules using a command and options in the following format (derived from the chess example):

       $ LINK SYS$INPUT/OPTIONS
       CHESS_METHOD.OBJ
       CHESS_MIB.OBJ
       CHESS_TBL.OBJ
       SYS$SHARE:TCPIP$ESNMP_SHR.EXE/SHARE

   To link with the eSNMP object library, enter the following command:

       $ LINK SYS$INPUT/OPTIONS
       CHESS_METHOD.OBJ
       CHESS_MIB.OBJ
       CHESS_TBL.OBJ
       TCPIP$SNMP:TCPIP$ESNMP.OLB/LIBRARY
       TCPIP$LIBRARY:TCPIP$LIB.OLB/LIBRARY

   Alternatively, you can link your subagent with the eSNMP API shareable image (TCPIP$ESNMP_SHR.EXE). The resulting executable image is smaller and can be run without relinking against any future versions of the shareable image. To link the example object with the shareable image, enter the following command:

       $ LINK SYS$INPUT/OPTIONS
       CHESS_METHOD.OBJ
       CHESS_MIB.OBJ
       CHESS_TBL.OBJ
       SYS$SHARE:TCPIP$ESNMP_SHR.EXE/SHARE

# 3.5 Including Extension Subagents in the Startup and Shutdown Procedures

You can add your custom subagents to the SNMP startup and shutdown procedures by editing the following files:

File Name | Edit Required
--- | ---
TCPIP$EXTENSION_MIB_STARTUP.COM | Edit the example lines to include an INSTALL CREATE command for custom images that need to be installed, possibly with privileges. Remove extra example lines, and adjust the GOTO statement.
TCPIP$EXTENSION_MIB_RUN.COM | Edit the example lines to include a RUN command for custom images. Remove extra example lines, and adjust the GOTO statement.
TCPIP$EXTENSION_MIB_SHUTDOWN.COM | Edit the example lines to: Include symbols for the detached processes that are running custom images. Use the same process names specified in TCPIP$EXTENSION_MIB_RUN.COM. Modify the IF and THEN statements to include the new symbols. Include an INSTALL DELETE command for images installed in TCPIP$EXTENSION_MIB_STARTUP.COM. Remove extra example lines, and adjust the GOTO statement.

# Chapter 4
Using the SNMP Utilities

TCP/IP Services includes the following programs, which are useful for testing applications and for analyzing SNMP problems:

- TCPIP$SNMP_REQUEST (MIB browser) ( Section 4.1)
- TCPIP$SNMP_TRPSND (trap sender) ( Section 4.2)
- TCPIP$SNMP_TRPRCV (trap receiver) ( Section 4.2)

These programs can be invoked by commands that are defined by the SYS$STARTUP:TCPIP$DEFINE_COMMANDS.COM command procedure.

This chapter describes how to use the supplied SNMP utilities.

# 4.1 Using the MIB Browser

TCP/IP Services provides the `snmp_request` MIB browser that acts as a simple client to handle single SNMP requests for reading and writing to a MIB. The browser sends SNMP Version 1 and SNMP Version 2 request PDUs to an agent and displays the agent's response.

To run the MIB browser, follow these steps:

1. Define a foreign command for the program:

       $ snmp_request == "$SYS$SYSTEM:TCPIP$SNMP_REQUEST"

   Alternatively, you can run the SYS$MANAGER:TCPIP$DEFINE_COMMANDS.COM procedure to define all the foreign commands available with TCP/IP Services.
2. Enter the command using the following format.

       snmp_request agent "community" request_type [flags] variable [data-type value]

   Section 4.1.1 describes the parameters. Section 4.1.2 describes the flags.

## 4.1.1 MIB Browser Parameters

Table 4-1 describes the `snmp_request` parameters.

Table 4-1 snmp_request Command Parameters
Parameter | Function
--- | ---
`agent` | The host name or IP address (in dot notation) of the managed node to query. If you specify 0, 0.0.0.0., 127.0.0.1, or "localhost," the server on the browser's host is queried.
`"community"` | The community string to be used in the query. This parameter is case sensitive. Typically, agents are configured to permit read access to the community string "public". For accurate interpretation, be sure to enclose the name in quotation marks (" "). Note that if you do not use quotation marks, the name is changed to lowercase.
`request-type` | PDU type to send. Can be one of the following SNMP requests:
`Get` | Sends a Get-Request PDU.
`GetNext` | Sends a GetNext-Request PDU.
`GetBulk` | Sends a GetBulk-Request PDU (SNMP Version 2 only).
`Set` | Sends a Set-Request PDU.
`variable` | An object identifier (OID) in ASN.1 notation that is associated with an object in a MIB. For example:
    $ snmp_request host1 "public" getnext -d 1.3.6.1.6.3.1.1.6
`data-type` | Data type of the value. This parameter can be specified for `Set` requests. The data types are described in Section 4.1.3.
`value` | The value to which to set the contents of the OID. This parameter is used for `set` requests.

For `Set` requests, you can specify more than one group of the following:

- `variable-name`
- `data-type`
- `value`

For other requests, you can specify more than one variable name, except when you specify the `-l` or `-t` flag; these flags are valid only with a `GetNext` or `GetBulk` request, for which only one OID is permitted.

## 4.1.2 MIB Browser Flags

Flags are specified in UNIX format.

Because flags and data types are case sensitive, you should always enter them in the case that is specified. If a letter or value is specified as uppercase, you must enclose it in quotation marks. In general, if you use uppercase letters where lowercase is specified, the results are unpredictable. For example, the flag `"-v2C"` functions correctly but the flag `"-V2c"` does not, because the flag character ( `v` ) must be lowercase.

If you do not specify a flag, or if you specify an invalid flag, a usage message is displayed. You must place the flags after the `request-type` parameter.

Table 4-2 describes the flags for the `snmp_request` command.

Table 4-2 Flags for the snmp_request Command
Flag | Description
--- | ---
`-d` | Specifies hexadecimal dump mode. Before displaying a return value, displays a hexadecimal dump of SNMP packets sent and received. For example:
    $ snmp_request host1 "public" getnext -d -v 2c 1.3.6.1.6.3.1.1.6

    Sent:

    30290201 01040670 75626C69 63A11C02 0).....public...

    047BE9C1 BD020100 02010030 0E300C06 .{.........0.0..

    082B0601 06030101 060500 .+.........

    Received:

    30820033 02010104 06707562 6C6963A2 0..3.....public.

    2602047B E9C1BD02 01000201 00308200 &..{.........0..

    16308200 12060A2B 06010603 01010601 .0.....+........

    00020478 D917FC ...x...

    1.3.6.1.6.3.1.1.6.1.0 = 2027493372
`-i max_ignores` | Specifies the number of times the MIB browser listens for a reply packet to a request if it receives an invalid packet (caused by an invalid packet identifier, version, or SNMP version and command combination). Specify a positive integer for the value ( max_ignores). If you specify a negative value, it will be converted to an unsigned positive integer. If you specify 0, no retries are attempted. If, after an invalid reply packet is received, a valid reply packet is received, the ignore counter is reset to the value of max_ignores. If a timeout occurs after an invalid packet is received, the packet is resent, the resend counter is decremented, and the ignore counter is reset to the value of max_ignores. You cannot use the `-i` flag when you perform a query with the `-l` or `-t` flags to automatically increment the input OID and continue querying a server after a general SNMP error has occurred, as may happen with a faulty server. In this case, the query is terminated even though the end of the MIB selection has not been reached. You must manually increment the input OID to skip the error and continue with the query.
`-l` | Specifies loop mode. Note that this flag is the letter l, not the number 1. Valid only if `request-type` is `GetNext` or `GetBulk` (where flag `n` is set to 0, and flag `m` is set to a number greater than 0). Causes the master agent to traverse all the MIBs registered with the master agent, starting at the first OID after the one specified in the command. (Note that you can specify only one `variable-name` [OID].) Responses are received one at a time, and for each one, the OID returned by the master agent is used in a subsequent request. Corresponds to the behavior of standard `mibwalk` programs. The MIB browser reads and displays responses, and issues requests until the master agent has no more data, times out, or you press Ctrl/Y or Ctrl/C. If specified with the `GetBulk` request, the `-n` and `-m` flags and associated values are ignored, and the behavior is identical to that of `GetNext` . When the last OID handled by the master agent is reached, you receive a response similar to the following for a query on OID 1.3.6.1.6.3.1.1.6.1 using SNMP Version 1:
    1.3.6.1.6.3.1.1.6.1.0 = 693056825

    - no such name - returned for variable 1
For a query using SNMP Version 2, the example response is:
    1.3.6.1.6.3.1.1.6.1.0 = 693056825

    1.3.6.1.6.3.1.1.6.1.0 = - end of mib view -
These examples assume that: OID 1.3.6.1.6.3.1.1.6.1.0 is the last OID supported on the target host. The target host is running an SNMP Version 2 agent. The statement `end of mib view` refers to OIDs for all MIBs registered with the master agent.
`-m max_repetitions` | Specifies the number of repetitions requested for repeating variables. Applies only to the `GetBulk` and `GetNext` requests. Note that the resulting display can be confusing because the results for the repeater OIDs are interleaved. That is, the OIDs are displayed in alternate progression for faster memory throughput. If you specify `GetBulk` without specifying both the `-m` and `-n` flags, the results are unpredictable.
`-n non_repeaters` | Specifies the number of variables for which no repetition is requested. Applies only to the `GetBulk` request. If you specify `GetBulk` without specifying both the `-m` and `-n` flags, the results are unpredictable.
`-p port` | Specifies the port where the request is to be sent. If not specified, the request is sent to well-known SNMP port 161.
`-r max_retries` | Specifies the number of times the MIB browser resends a request packet if it times out before receiving a reply. Specify a positive integer for the value ( max_retries). If you specify a negative value, it will be converted to an unsigned positive integer. If you specify 0, no retries are tried. If, after a timeout and a resend, a reply packet is received, the resend counter is reset. After another timeout, the specified number of max_retries is sent.
`-s sleep_interval` | Specifies the number of seconds between iterations of sending a request (for the `-r` flag) and listening for a reply (for the `-i` ) flag. The default is 1 second. This flag is ignored if neither the `-r` flag nor the `-i` flag are specified. The `-s` flag is useful for specifying a time to wait between resends, which might be necessary when a server agent is starting up.
`-t` | Specifies tree mode. Valid only if `request-type` is `GetNext` or `GetBulk` (where flag `n` is set to 0 and flag `m` is set to a number greater than 0). Similar to the `-l` flag. Directs the agent to perform a MIB walk for the subtree with the `variable_name` as its root. The program reads and prints responses and issues requests until the agent has no more data for the specified subtree, times out, or is interrupted by a user.
`-v version` | Specifies the SNMP version to use for sending the PDU. The versions are: `2c` or `1` (default). Not case sensitive. You can specify the flag without a space ( `-v2c` and `-v1` ). If `request_type` is `getbulk` , the version defaults to SNMP Version 2. If you specify `-v 2c` to send a message to an SNMP Version 1 agent or subagent, it is unlikely to respond.
`-w max_wait` | Specifies the maximum seconds the `snmp_request` program waits for a reply before timing out. Cannot be 0. The default is 3.

Previous | Next | Contents | Index