  | 
HP TCP/IP Services for OpenVMS
HP TCP/IP Services for OpenVMS
SNMP Programming 
and Reference
5.2.1 Processing *_set Routines
This following is the sequence of operations performed for
*_set
 routines
  - Every variable binding is parsed and its object is located in the 
  object table. A METHOD structure is created for each VARBIND structure. 
  These METHOD structures point to a ROW_CONTEXT structure, which is 
  useful for handling these phases. Objects in the same conceptual row 
  all point to the same ROW_CONTEXT structure. This determination is made 
  by checking the following:
  
    - The referenced objects are in the same MIB group.
    
 - The VARBIND structures have the same instance OIDs.
  
 
   - Each ROW_CONTEXT structure is loaded with the instance information 
  for that conceptual row. The ROW_CONTEXT structure context and save 
  fields are set to NULL, and the state field is set to ESNMP_SET_UNKNOWN 
  structure.
  
 - The method routine for each object is called and is passed its 
  METHOD structure with an action code of ESNMP_ACT_SET. 
If all 
  method routines return success, a single method routine (the last one 
  called for the row) is called for each row, with 
  method->action equal to ESNMP_ACT_COMMIT. 
If any row 
  reports failure, all rows that were successfully committed are told to 
  undo the phase. This is accomplished by calling a single method routine 
  for each row (the same one that was called for the commit phase), with 
  a method->action equal to ESNMP_ACT_UNDO.
   - Each row is released. The same single method routine for each row 
  is called with a method->action equal to ESNMP_ACT_CLEANUP. 
  This occurs for every row, regardless of the results of previous 
  processing.
 
The action codes are processed as follows:
  - ESNMP_ACT_SET 
Each object's method routine is called during the 
  SET phase, until all objects are processed or a method routine returns 
  an error status value. (This is the only phase during which each 
  object's method routine is called.) For variable bindings in the same 
  conceptual row, method->row points to a common ROW_CONTEXT. 
  
The method->flags bitmask has the ESNMP_LAST_IN_ROW bit 
  set, if this is the last object being called for this ROW_CONTEXT. This 
  enables you to do a final consistency check, because you have seen 
  every variable binding for this conceptual row. 
The method 
  routine's job in this phase is to determine whether the
Set
 request will work, to return the correct SNMP error code if it does 
 not, and to prepare any context data it needs to actually perform the
Set
request during the COMMIT phase. 
The 
method->row->context field is private to the method 
routine;
libesnmp
 does not use it. A typical use is to store the address of an emitted 
 structure that has been loaded with the data from the VARBIND for the 
 conceptual row.
   - ESNMP_ACT_COMMIT 
Even though several variable bindings may be 
  in a conceptual row, only the last one in order of the
Set
 request is processed. Of all the method routines that point to a common 
 row, only the last method routine is called. 
This method routine 
 must have available to it all necessary data and context to perform the 
 operation. It must also save a snapshot of current data or whatever it 
 needs to undo the
Set
operation, if required. The method->row->save field is 
intended to hold a pointer to whatever data is needed to accomplish 
this. A typical use is to store the address of a structure that has 
been loaded with the current data for the conceptual row. The structure 
is one that has been automatically generated by the MIBCOMP command. 
The method->row->save field is also private to the 
method routine;
libesnmp
 does not use it. 
If this operation succeeds, return
ESNMP_MTHD_noError
; otherwise, return a value of
ESNMP_MTHD_commitFailed
. 
If any errors were returned during the COMMIT phase,
libesnmp
 enters the UNDO phase; if not, it enters the CLEANUP phase.
  Note 
If the
Set
 request spans multiple subagents and another subagent fails, the UNDO 
 phase may occur even if the
Set
 operation is successful 
     | 
  
   - ESNMP_ACT_UNDO 
For each conceptual row that was successfully 
  committed, the same method routine is called with 
  method->action equal to ESNMP_ACT_UNDO. The ROW_CONTEXT 
  structures that have not yet been called for the COMMIT phase are not 
  called for the UNDO phase; they are called for CLEANUP phase. 
The 
  method routine should attempt to restore conditions to what they were 
  before it executed the COMMIT phase. (This is typically done using the 
  data pointed to by the method->row->save field.) 
If 
  successful, return ESNMP_MTHD_noError; otherwise, return 
  ESNMP_MTHD_undoFail.
   - ESNMP_ACT_CLEANUP 
Regardless of what else has happened, at this 
  point each ROW_CONTEXT participates in cleanup phase. The same method 
  routine that was called for in the COMMIT phase is called with 
  method->action equal to ESNMP_ACT_CLEANUP. 
This 
  indicates the end of processing for the
set
request. The method routine should perform whatever cleanup is 
required; for instance, freeing dynamic memory that might have been 
allocated and stored in method->row->context and 
method->row->save fields, and so on. 
The function 
return status value is ignored for the CLEANUP phase.
 
5.2.2 Method Routine Applications Programming
You must write the code for the method routines declared in the 
subtree_TBL.H file. Each method routine has one argument, 
which is a pointer to the METHOD structure, as follows:
  
    
       
      
int mib_group_get( 
        METHOD *method int mib_group_set( 
        METHOD *method ); 
 | 
The
Get
 method routines are used to perform
Get
,
GetNext
, and
GetBulk
 operations.
The
Get
 method routines perform the following tasks:
  - Extract the instance portion of the requested OID. You can do this 
  manually by comparing the method->object->oid field (the 
  object's base OID) to the method->varbind->name 
  field (the requested OID). You can use the
oid2instance
 support routine to do this.
  
 - Determine the instance validity. The instance OID can be null or 
  any length, depending on what was requested and how your object was 
  selected. You may be able to reject the request immediately by checking 
  on the instance OID.
  
 - Extract the data. Based on the instance OID and 
  method->action field, determine what data, if any, is to be 
  returned.
  
 - Load the response OID back into the method routine's VARBIND 
  structure. Set the method->varbind field with the OID of 
  the actual MIB variable instance you are returning. This is usually 
  accomplished by loading an array of integers with the instance OID you 
  wish to return and calling the
instance2OID
 support routine.
  
 - Load the response data back into the method routine's VARBIND 
  structure. 
Use one of the support routines with the corresponding 
  data type to load the method->varbind field with the data 
  to return:
  
    - 
o_integer
    
 - 
o_string
    
 - 
o_octet
    
 - 
o_oid
  
 
    
These routines make a copy of the data you specify. The
libesnmp
function manages any memory associated with copied data. The method 
routine must manage the original data's memory. 
The routine does 
any necessary conversions to the type defined in the object table for 
the MIB variable and copies the converted data into the 
method->varbind field. See Section 5.2.3 for information on 
data value representation.
   - Return the correct status value, as follows:
  
    | 
      ESNMP_MTHD_noError
     | 
    
      The routine completed successfully or no errors were found.
     | 
  
  
    | 
      ESNMP_MTHD_noSuchInstance
     | 
    
      There is no such instance of the requested object.
     | 
  
  
    | 
      ESNMP_MTHD_noSuchObject
     | 
    
      No such object exists.
     | 
  
  
    | 
      ESNMP_MTHD_ genErr
     | 
    
      An error occurred and the routine did not complete successfully.
     | 
  
 
5.2.3 Value Representation
The values in a VARBIND structure for each data type are represented as 
follows. (Refer to the ESNMP.H file for a definition of the OCT and OID 
structures.)
  - ESNMP_TYPE_Integer32 (varbind->value.sl field) 
This 
  is a 32-bit signed integer. Use the
o_integer
 routine to insert an integer value into the VARBIND structure. Note 
 that the prototype for the value argument is unsigned long; therefore, 
 you may need to cast this to a signed integer.
   - ESNMP_TYPE_DisplayString, ESNMP_TYPE_Opaque
ESNMP_TYPE_OctetString (varbind->value.oct field) 
This 
is an octet string. It is contained in the VARBIND structure as an OCT 
structure that contains a length and a pointer to a dynamically 
allocated character array. 
The displaystring is different 
only in that the character array can be interpreted as ASCII text, but 
the octetstring can be anything. If the octetstring 
contains bits or a bit string, the OCT structure contains the following:
  
    - A length equal to the number of bytes needed to contain the value 
    that is ((qty-bits - 1)/8 + 1)
    
 - A pointer to a buffer containing the bits of the bitstring in the 
    form bbbbb..bb, where the bb octets represent the 
    bitstring itself, bit 0 comes first, and so on. Any unused bits in the 
    last octet are set to zero.
  
 
    
Use the
o_string
 support routine to insert a value into the VARBIND structure, which is 
 a buffer and a length. New space is allocated and the buffer is copied 
 into the new space. 
Use the
o_octet
 routine to insert a value into the VARBIND structure, which is a 
 pointer to an OCT structure. New space is allocated and the buffer 
 pointed to by the OCT structure is copied.
   - ESNMP_TYPE_ObjectId (varbind->value.oid and the 
  varbind->name fields) 
This is an object identifier. It 
  is contained in the VARBIND structure as an OID structure that contains 
  the number of elements and a pointer to a dynamically allocated array 
  of unsigned integers, one for each element. 
The 
  varbind->name field is used to hold the object identifier 
  and the instance information that identifies the MIB variable. Use the
OID2Instance
 function to extract the instance elements from an incoming OID on a 
 request. Use the
instance2oid
function to combine the instance elements with the MIB variable's base 
OID to set the VARBIND structure's name field when building a response. 
Use the
o_oid
 function to insert an object identifier into the VARBIND structure when 
 the OID value to be returned as data is in the form of a pointer to an 
 OID structure. 
Use the
o_string
 function to insert an OID into the VARBIND structure when the OID value 
 to be returned as data is in the form of a pointer to an ASCII string 
 containing the OID in dot format; for example: 1.3.6.1.2.1.3.1.1.2.0.
   - ESNMP_TYPE_NULL 
This is the NULL, or empty, type. This is used 
  to indicate that there is no value. The length is zero and the value in 
  the VARBIND structure is zero filled. 
The incoming VARBIND 
  structures on a
Get
,
GetNext
, and
GetBulk
 will have this data type. A method routine should never return this 
 value. An incoming
Set
 request never has this value in a VARBIND structure.
   - ESNMP_TYPE_IpAddress (varbind->value.oct field) 
  
This is an IP address. It is contained in the VARBIND structure in 
  an OCT structure that has a length of 4 and a pointer to a dynamically 
  allocated buffer containing the 4 bytes of the IP address in network 
  byte order. 
Use the
o_integer
 function to insert an IP address into the VARBIND structure when the 
 value is an unsigned integer in network byte order. 
Use the
o_string
 function to insert an IP address into the VARBIND structure when the 
 value is a byte array (in network byte order). Use a length of 4.
   - ESNMP_TYPE_Integer32
ESNMP_TYPE_Counter32
ESNMP_TYPE_<Gauge32 (varbind->value.ul field) 
The 
32-bit counter and 32-bit gauge data types are stored in the VARBIND 
structure as an unsigned integer. 
Use the
o_integer
 function to insert an unsigned value into the VARBIND structure.
   - ESNMP_TYPE_TimeTicks (varbind->value.ul field) 
The 
  32-bit
timeticks
 type values are stored in the VARBIND structure as an unsigned integer. 
 
Use the
o_integer
 function to insert an unsigned value into the VARBIND structure.
   - ESNMP_TYPE_Counter64 (varbind->value.ul64 field) 
  
The 64-bit counter is stored in a VARBIND structure as an unsigned 
  longword, which, on an OpenVMS Alpha system, has a 64-bit value. 
  
Use the
o_integer
 function to insert an unsigned longword (64 bits) into the VARBIND 
 structure.
 
5.3 Support Routines 
The support routines are provided as a convenience for developers 
writing method routines that handle specific MIB elements. The 
following support routines are provided:
  
    | Routine  | 
    Function  | 
  
  
    | 
      
      o_integer
      
     | 
    
      Loads an integer value.
     | 
  
  
    | 
      
      o_octet
      
     | 
    
      Loads an octet value.
     | 
  
  
    | 
      
      o_oid
      
     | 
    
      Loads an OID value.
     | 
  
  
    | 
      
      o_string
      
     | 
    
      Loads a string value.
     | 
  
  
    | 
      
      o_counter64
      
     | 
    
      Loads a Counter64 variable into the
      
      varbind
      
              .
     | 
  
  
    | 
      
      str2oid
      
     | 
    
      Converts a string OID to dot notation.
     | 
  
  
    | 
      
      sprintoid
      
     | 
    
      Converts an OID into a string.
     | 
  
  
    | 
      
      instance2oid
      
     | 
    
      Creates a full OID for a value.
     | 
  
  
    | 
      
      oid2instance
      
     | 
    
      Extracts an instance and loads an array.
     | 
  
  
    | 
      
      inst2ip
      
     | 
    
      Returns an IP address for an OID.
     | 
  
  
    | 
      
      cmp_oid
      
     | 
    
      Compares two OIDs.
     | 
  
  
    | 
      
      cmp_oid_prefix
      
     | 
    
      Compares an OID's prefix.
     | 
  
  
    | 
      
      clone_oid
      
     | 
    
      Makes a copy of an OID.
     | 
  
  
    | 
      
      free_oid
      
     | 
    
      Frees a buffer.
     | 
  
  
    | 
      
      clone_buf
      
     | 
    
      Duplicates a buffer.
     | 
  
  
    | 
      
      mem2oct
      
     | 
    
      Converts a string to an
      
      oct
      
               structure.
     | 
  
  
    | 
      
      cmp_oct
      
     | 
    
      Compares two octets.
     | 
  
  
    | 
      
      clone_oct
      
     | 
    
      Makes a copy of an
      
      oct
      
               structure.
     | 
  
  
    | 
      
      free_oct
      
     | 
    
      Frees a buffer attached to an
      
      oct
      
               structure.
     | 
  
  
    | 
      
      free_varbind_date
      
     | 
    
      Frees the fields in the
      
      VARBIND
      
               structure.
     | 
  
  
    | 
      
      set_debug_level
      
     | 
    
      Sets the logging level.
     | 
  
  
    | 
      
      is_debug_level
      
     | 
    
      Tests the logging level.
     | 
  
  
    | 
      
      ESNMP_LOG
      
     | 
    
      Directs log messages.
     | 
  
  
    | 
      
      print_varbind
      
     | 
    
      Displays the
      
      varbind
      
               and its structure.
     | 
  
  
    | 
      
      set_select_limit
      
     | 
    
      Sets the error limit for SNMP client requests.
     | 
  
  
    | 
      
      __set_progname
      
     | 
    
      Sets the program name to be displayed in log messages.
     | 
  
  
    | 
      
      __restore_progname
      
     | 
    
      Resets the program name back to the previous name.
     | 
  
  
    | 
      
      __parse_progname
      
     | 
    
      Parses the application file name to determine the program name.
     | 
  
  
    | 
      
      esnmp_cleanup
      
     | 
    
      Closes a socket that is used by a subagent for communicating with the 
      master agent.
     | 
  
o_integer
Loads an integer value into the VARBIND structure with the appropriate 
type. This function does not allocate the VARBIND structure.
Format
int o_integer ( VARBIND *vb, 
 OBJECT *obj, 
 
unsigned long value );
Arguments
vb
A pointer to the VARBIND structure that is supposed to receive the data.
obj
A pointer to the
OBJECT
 structure for the MIB variable associated with the
OID
 in the VARBIND structure.
value
The value to be inserted into the VARBIND structure.
The real type as defined in the object structure must be one of the 
following; otherwise, an error is returned.
  
    | 
      ESNMP_TYPE_Integer32
     | 
    
      32-bit integer
     | 
  
  
    | 
      ESNMP_TYPE_Counter32
     | 
    
      32-bit counter (unsigned)
     | 
  
  
    | 
      ESNMP_TYPE_Gauge32
     | 
    
      32-bit gauge (unsigned)
     | 
  
  
    | 
      ESNMP_TYPE_TimeTicks
     | 
    
      32-bit timeticks (unsigned)
     | 
  
  
    | 
      ESNMP_TYPE_UInteger32
     | 
    
      32-bit integer (unsigned)
     | 
  
  
    | 
      ESNMP_TYPE_Counter64
     | 
    
      64-bit counter (unsigned)
     | 
  
  
    | 
      ESNMP_TYPE_IpAddress
     | 
    
      Implicit octet string (4)
     | 
  
  Note 
If the real type is
IpAddress
, then eSNMP assumes that the 4-byte integer is in network byte order 
and packages it into an octet string. 
     | 
  
Return Values
  
    | 
      ESNMP_MTHD_noError
     | 
    
      The routine completed successfully.
     | 
  
  
    | 
      ESNMP_MTHD_genErr
     | 
    
      An error has occurred.
     | 
  
Example
  
    
       
      
 
#include <esnmp.h> 
#include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition 
VARBIND     *vb       = method->varbind; 
OBJECT      *object   = method->object; 
ipNetToMediaEntry_type *data; 
: 
: assume buffer and structure member assignments occur here 
: 
switch(arg) { 
case I_atIfIndex: 
return o_integer(vb, object, data->ipNetToMediaIfIndex); 
 
 | 
o_octet
Loads an octet value into the VARBIND structure with the appropriate 
type. This function does not allocate the VARBIND structure.
Format
int o_octet ( VARBIND *vb, 
 OBJECT *obj, 
 
unsigned long value );
Arguments
vb
A pointer to the VARBIND structure that is supposed to receive the data.
If the original value in the vb field is not null, this 
routine attempts to free it. So if you dynamically allocate memory or 
issue the
malloc
 command to allocate your own VARBIND structure, fill the structure with 
 zeros before using it.
obj
A pointer to the OBJECT structure for the MIB variable associated with 
the OID in the VARBIND structure.
value
The value to be inserted into the VARBIND structure.
The real type as defined in the object structure must be one of the 
following; otherwise, an error is returned.
  
    | 
      ESNMP_TYPE_OCTET_STRING
     | 
    
      Octet string (ASN.1)
     | 
  
  
    | 
      ESNMP_TYPE_IpAddress
     | 
    
      Implicit octet string (4) (in octet form, network byte order)
     | 
  
  
    | 
      ESNMP_TYPE_DisplayString
     | 
    
      DisplayString (textual convention)
     | 
  
  
    | 
      ESNMP_TYPE_Opaque
     | 
    
      Implicit octet string
     | 
  
Return Values
  
    | 
      ESNMP_MTHD_noError
     | 
    
      The routine completed successfully.
     | 
  
  
    | 
      ESNMP_MTHD_genErr
     | 
    
      An error occurred.
     | 
  
Example
  
    
       
      
 
#include <esnmp.h> 
#include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition 
VARBIND     *vb       = method->varbind; 
OBJECT      *object   = method->object; 
ipNetToMediaEntry_type *data; 
: 
: assume buffer and structure member assignments occur here 
: 
switch(arg) { 
 case I_atPhysAddress: 
 return o_octet(vb, object, &data->ipNetToMediaPhysAddress); 
 
 |