Function templates are skeletons that require the programmer to fill in implementation-specific code. The access functions source contains that portion of the agent that accesses the attributes of the managed resource, to modify those attributes in response to a SET request from a manager, or to retrieve current values in response to a GET request from a manager. This code is specific to your implementation because it depends upon the particular instrumentation available in the managed resource, such as application-specific APIs or UNIX system calls.
To generate the source code file containing the access functions for your agent, you target the MIB compiler/code generator ( where When you run the MIB compiler/code generator with this command, the code generator reads the Normally the This section describes the function templates that are created by the code generator.
This function is called once by the agent the first time any object in the This function returns SNMP_SUCCESS if successful and SNMP_FAILURE if not successful. If this function returns a failure, the agent or subagent always returns "NO SUCH NAME" for any object in this MIB group or table.
This function has no return value for MIB groups with scalar objects. For tabular objects, the function returns either SNMP_SUCCESS or SNMP_FAILURE. If SNMP_FAILURE is returned, no SNMP operation can be performed on objects in that table for the next refresh period.
One such refresh function is generated for the MIB group or table that is the target passed to the code generator when generating an access functions skeleton file.
This refresh function is responsible for updating the agent cache by directly accessing the managed resource - for example, using an API or system calls - to obtain current values of the attributes of the managed resource. Accordingly, you must edit the For example, if your MIB group has a scalar object The object values for a given MIB group are cached in the record For each field This field should contain the status of the corresponding Also, for each field The structures that constitute the agent's cache of current object values are used by the For each scalar or columnar object that is defined as read-write in the MIB, a The syntax of the test function depends upon the type of For scalar objects that are OIDs, strings, or IP addresses:
For scalar objects other than strings, OIDs or IP addresses:
For columnar objects that are strings, OIDs, or IP addresses:
For columnar objects other than OIDs, strings, or IP addresses:
The test function should return SNMP_SUCCESS if and only if the requested set value is valid for the target. Otherwise, the function returns SNMP_FAILURE.
If an SNMP agent receives an SNMP SET request containing more than one variable, the agent either sets all the objects in the SET request or else none are set. This behavior is known as atomic set and is one of the requirements of the SNMP standard. Atomic sets are supported using two-phase commit. In order to implement this, for each read-write object a test and a set function is generated as part of the access functions file.
On receiving a SET request from the management station, the SNMP agent first invokes the test function corresponding to each object involved in the SET request. If all test functions return success, only then does the agent invoke the set For string objects or IP addresses, To support SNMP SET requests, a The syntax of this function depends upon the type of For scalar objects other than OIDs, strings, or IP addresses:
For scalar objects that are strings, OIDs, or IP addresses:
For columnar objects that are strings, IP addresses, or OIDs:
For columnar objects other than strings, IP addresses, or OIDs:
This function should always return SNMP_SUCCESS.
The agent executes a If an SNMP agent receives an SNMP set request containing more than one variable, the agent either sets all the objects in the SET request or else none are set. This "atomic set" behavior is one of the requirements of the SNMP standard. Atomic sets are supported using two-phase commit. In order to implement this, for each read-write object a test and a set function is generated as part of the access functions file. On receiving a For string objects or IP addresses, Returns SNMP_SUCCESS if enough object values have been provided to set an entire row in the table and the values are appropriate for the target objects. Returns SNMP_FAILURE otherwise.
The agent cache maintains a record When a row creation request is received, the values are first loaded into the A SET request from a master agent to a subagent may fail to contain values for all of the columnar objects in the row. It is the responsibility of the This function should always return SNMP_SUCCESS.
The agent cache maintains a record When a SET request for a non-existent row is received, the values are first loaded into the The validity of the object values is indicated to the This section describes user-modifiable constant values and the generated agent cache structure variable, This constant is defined in the header file, This constant is defined in the header file, For objects of type string in the MIB group or table, a maximum string length constant is defined in the You can modify the value of this constant as appropriate.
This variable specifies in seconds the smallest interval at which the refresh function, When a manager sends a GET request to the agent, If the value of Example:
This is a structure of type The agent stores the most recently retrieved values of managed objects in these structures. When a
Note:
Normally you will not need to modify this structure declaration.
The first field in the structure is always:
and the second field in the structure must always be:
The structure contains a component:
for each object in the target MIB group or table. For each such component there is another component:
that contains the status of the object in the cache. The status may be set to either SNMP_VALID or SNMP_INVALID. If If which specifies the length of the string in bytes. Each component in a table row structure corresponding to the MIB INDEX clause must have a valid value if table-handing is to work correctly. Because the INDEX specifies an instance of the table entry (row) object, the value of INDEX affects the OID of all the objects in the row.
The following is an example declaration of a structure for a MIB table object, beaExTable:
The constants This section describes generated functions that normally do not need to be modified by the programmer.
These functions retrieve the current value of The syntax of the get functions depends on the type of For columnar objects that are strings or OIDs:
For columnar objects other than strings or OIDs:
For scalar objects that are OIDs or strings:
For scalar objects other than OIDs or strings:
The function returns SNMP_VALID if the appropriate value of the object is made available in the location pointed to by If imibgenall
) at a MIB group or table with the following command:
imibgenall
MIBRootName
MIBRootName
is the target MIB group or table.
my.asn1
file and generates access function skeletons corresponding to the target MIB objects. The code is created in a file named MIBRootName
.c
. The code generator also creates a declaration for a C structure that is used by the agent to cache the current values of the managed objects. This structure, v_
MIBRootName
, is declared in the header file, MIBRootName
.h
.
v_
MIBRootName
cache structure and the get_
ObjectName
functions do not need to be modified by the programmer.
Function Templates
init_MIBRootName
MIBRootName
group or table is polled. You need to fill in this function skeleton with your initialization code. It is recommended that you print a reason for failure in case SNMP_FAILURE is returned.
Syntax
int init_
MIBRootName
()
Return Value
refresh_MIBRootName
Syntax
int refresh_
MIBRootName
()
Return Value
refresh_
MIBRootName
function to add the code that directly accesses the managed resource and updates the object values in the agent cache.
myQEntryCount
under the myQ
MIB group, there will be a line in the generated code such as the following:
v_myQ.val_myQEntryCount =
dummy_value
;v_
MIBRootName
- in this example, v_myQ
. This record is an instance of a structure of type s_
MIBRootName
, defined in the header file. You will need to replace dummy_value
with the code that provides the actual value accessed from the managed resource - in this example, this might involve a call to the queue system's API.
val_
ObjectName
in the cache structure, there is also a status field sts_ObjectName
. For the previous example, there would be a line in the generated code that looks something like this:
v_myQ.sts_myQEntryCount =
dummy_value
;val_
ObjectName
field. If the value of ObjectName
is not available, your code should set v_
MIBRootName
.sts_
ObjectName
to SNMP_INVALID. For example:
v_myQ.sts_myQEntryCount = SNMP_INVALID;
val_
ObjectName
in the structure that is of type string, there will be a corresponding field len_
ObjectName
, which should contain the length of the string in bytes.
get_
ObjectName
functions to retrieve object values in response to a GET request from a management station. The agent tracks the age of the cache. Before calling the get_
ObjectName
functions to respond to manager GET requests, the agent checks to determine whether the cache is older than the refresh rate. If it is older, the agent calls refresh_
MIBRootName
to update the cache before calling the get_
ObjectName
functions for that MIB group. For more information about the refresh rate, see the following section, "Constants and Variables."
test_ObjectName
test_
ObjectName
function skeleton is generated in the access functions file. You must flesh out each of these functions with code that checks to determine whether the value in the set request is valid for the target attribute in the managed resource.
ObjectName
.
Syntax
int test_
ObjectName
(value, length)
u_char *value;
int length;int test_
ObjectName
(value)
int value;int test_
ObjectName
(row_index, value, length)
int row_index;
u_char *val_ptr;
int length;int test_
ObjectName
(row_index,value)
int row_index;
int value; Return Value
functions corresponding to these objects. Otherwise, no set function is called.
length
is the length in bytes. For OIDs, length
is the number of nodes in the absolute path from the root of the OID tree.
set_ObjectName
set_
ObjectName
function skeleton is generated in the access functions file for each scalar or columnar MIB object that is defined as read-write. You need to add the necessary code to directly access the managed resource, such as API function calls.
ObjectName
.
Syntax
int set_
ObjectName
(value)
int value;int set_
ObjectName
(value, length)
u_char *value;
int length;int set_
ObjectName
(row_index, value, length)
int row_index;
u_char *value;
int length;int set_
ObjectName
(row_index, value)
int row_index;
int value; Return Value
set_
ObjectName
function if and only if a call to the corresponding test_
ObjectName
function returns SNMP_SUCCESS. The programmer must fill out the set_
ObjectName
function to directly access the managed resource to modify the specified attribute.
set
request from the management station, the SNMP agent first invokes the test function corresponding to each object involved in the set request. If all test functions return success, only then does the agent invoke the set functions corresponding to these objects. This function must always return either SNMP_SUCCESS or SNMP_FAILURE for an atomic set to work properly.
length
is the length in bytes. For OIDs, length
is the number of nodes in the absolute path from the root of the OID tree.
test_TableName_row_create
Syntax
int test_
TableName
_row_create(row_index)
int row_index; Return Value
v_
TableName
for each row in a table. In this record, the field val_
ObjectName
stores the value of the columnar object while sts_
ObjectName
stores the status of the object. If the value of an object cannot be provided, the status should be assigned SNMP_INVALID. If sts_
ObjectName
is set to SNMP_INVALID, the corresponding value is ignored.
v_
TableName
record and then the agent calls the test_
TableName
_row_create
to determine if the values are acceptable for the target objects. If this function returns SNMP_SUCCESS, set_
TableName
_row_create
is called. Both of these functions are passed an index to the newly created row structure in the cache. If test_
TableName
_row_create
returns SNMP_FAILURE, the newly created row structure is removed from the agent cache.
test_
TableName
_row_create
function to ensure that a sufficient number of columnar object values have been provided to create a row. The validity of the object values is indicated to the set_
TableName
_create_row
function by the sts_
ObjectName
field corresponding to the object in the v_
TableName
structure being assigned a value of SNMP_VALID.
set_TableName_row_create
Syntax
int set_
TableName
_row_create(row_index)
int row_index; Return Value
v_
TableName
for each row in a table. In this record, the field val_
ObjectName
stores the value of the columnar object while sts_
ObjectName
stores the status of the object. If the value of an object cannot be provided, the status should be assigned SNMP_INVALID. If sts_
ObjectName
is set to SNMP_INVALID, the corresponding value is ignored.
v_
TableName
record and then the agent calls the test_
TableName
_row_create
to determine if the values are acceptable for the target objects. If this function returns SNMP_SUCCESS, set_
TableName
_row_create
is called. Both of these functions are passed an index to the newly created row structure in the cache. If test_
TableName
_row_create
returns SNMP_FAILURE, the newly created row structure is removed from the agent cache.
set_
TableName
_create_row
function by the sts_
ObjectName
field corresponding to the object in the v_
TableName
structure being assigned a value of SNMP_VALID.
Constants and Variables
v
_MIBRootName
.
DELTA_TableName_ENTRIES
MIBRootName
.h
, when the code generator is targeted at a table. Each row in a table is stored in memory in a structure v_
TableName
, which is of type s_
TableName. This type is defined in the MIBRootName
.h
header file. Objects within a table are stored in this structure. The number of rows in the table are dynamically adjusted. Whenever it is necessary to add more rows, the value of the constant DELTA_TableName_ENTRIES determines the amount of space that is added incrementally to provide space for additional rows.
INIT_TableName_ENTRIES
MIBRootName
.h
, when the code generator is targeted at a table. Each row in a table is stored in memory in a structure v_
TableName
, which is of type s_
TableName
. This type is defined in the MIBRootName
.h
header file. Objects within a table are stored in this structure. The number of rows in the table are dynamically adjusted. However, when the table is created it is initially allocated a number of rows equal to the constant INIT_TableName_ENTRIES.
MAX_StringObjectName
MIBRootName
.h
header file. For example:
#define MAX_beaExStrRO 256 /* length of beaExStrRO in bytes */
MIBRootName_refresh_rate
refresh_
MIBRootName
, is called within the agent. The value of this variable is set in the access functions source file, MIBRootName
.c
.
get_
ObjectName
functions are called to retrieve the current value from the agent cache. The get_
ObjectName
functions do not directly access the managed resource. Direct access of the managed resource is the work of the refresh_
MIBRootName
function, which updates the agent cache. The agent tracks the age of the cache. Before calling the get_
ObjectName
functions, the agent checks to determine whether the cache is older than the refresh rate. If it is older, the agent calls the function refresh_
MIBRootName
before calling the get_
ObjectName
functions for that MIB group.
MIBRootName
_refresh_rate
is set to 0, the refresh function is called every time an object is queried by a management station. In that case, the refresh function is not invoked if no requests are received by the agent for these objects.
int beaExTable_refresh_rate = 10 /* seconds */;
v_MIBRootName
s_
MIBRootName
, declared in the MIBRootName
.h
header file. A structure of this sort is declared for each MIB group or table entry (row).
get_
ObjectName
function retrieves a value in response to a GET request from a management station, it retrieves the value from this agent cache.
int index_oid[MAX_INDEX_OID];
int oid_len;
v_
MIBRootName
.val_
ObjectName
v_
MIBRootName
.sts_
ObjectName
val_
ObjectName
contains a valid value, the corresponding sts_
ObjectName
should be set to SNMP_VALID. If the value of ObectName
cannot be provided, sts_
ObjectName
must be set to SNMP_INVALID.
ObjectName
is of type string, there will be a component:
v_
MIBRootName
.len_
ObjectName
struct s_beaExTable {
oid index_oid[MAX_INDEX_OID];/* must be the first element */
int oid_len; /* must be the second element */
int row_status; /* only for internal use */
int val_beaExTblIndex;
int sts_beaExTblIndex;
int val_beaExTblIntRO;
int sts_beaExTblIntRO;
int val_beaExTblIntRW;
int sts_beaExTblIntRW;
char val_beaExTblStrRO[MAX_beaExTblStrRO];
int len_beaExTblSrRO;
int sts_beaExTblStrRO;
int val_beaExTblStrRW[MAX_beaTblStrRW];
int len_beaExTblStrRW;
int sts_beaExTblStrRW;
};
extern struct s_beaExTable *v_beaExTable;MAX_beaExTblStrRO
and MAX_beaExTblStrRW
define the length, in bytes, of string objects. These constants are also defined in the header file.
Generated Functions
get_ObjectName
ObjectName
from the agent cache. These functions do not directly access the managed resource. Normally it is not necessary to modify these functions.
ObjectName
.
Syntax
int get_
ObjectName
(row_index, val_ptr, val_len)
int row_index:
u_char **val_ptr;
int *val_len;int get_
ObjectName
(row_index,val_ptr)
int row_index;
int *val_ptr;int get_
ObjectName
(val_ptr,val_len)
u_char **val_ptr;
int *val_len;int get_
ObjectName
(val_ptr) Return Value
val_ptr
. Otherwise, the function returns SNMP_INVALID and the contents of the location pointed to by val_ptr
are undefined.
ObjectName
is a string or IP address, the length of the object in bytes is pointed to by the input argument val_len
. If ObjectName
is an OID, val_len
points to the number of nodes in the absolute OID path from root. If ObjectName
is a columnar object, row_index
refers to the row number in the table; 0 is the first row.