  | 
		
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);
 |   
 
  
  
		 |