Chapter 4. Header file
4.1. Header files
The header file generated by the 'mib2c' tool consist of five elements:
-
A context structure. It is a one to one mapping of the leaf nodes (columnar objects) in a SEQUENCE table to a C structure, with the first variable being the index tuple.
-
Functions for manipulating the context structure. These include generic functions for sorting, getting an item, checking for correct boundary conditions, and generating the index tuple.
-
Object IDentifier for the table.
-
Textual names of the leaf nodes (columnar objects) using #define.
-
#define enabling/disabling different functions of the sub-agent table manipulations.
4.1.1. Context structure
The context structure is used exclusivly by the NetSNMP API for manipulating rows of leaf nodes (columnar objects).
The first named variables of the structure is the index variable.
typedef struct netSnmpIETFWGTable_context_s { netsnmp_index index; /** THIS MUST BE FIRST!!! */ ....
The netsnmp_index is defined in net-snmp/types.h as
typedef struct netsnmp_index_s { int len; oid *oids; } netsnmp_index;
The oid is defined as unsigned long (look in net-snmp/library/asn1.h). The len is the number of entries in the *oids array, not the length of the OID in the bytes.
This netsnmp_index structure is used to place the index tuple of the row. Not the full OID (as in fully expanded OID of the table), but just the sub-set of numbers uniquely defining the row alsa known as index value.
4.1.1.1. Example of using netsnmp_index
The example uses the IETF WG table structure to set the index tuple to the string "fodo."
netsnmp_index *index; oid index_oid[5]; index = SNMP_MALLOC_TYPEDEF(netsnmp_index); index_oid[0] = 4; // The first value is the length of the string. index_oid[1] ='f'; index_oid[2] ='o'; index_oid[3] ='d'; index_oid[4] ='o'; index->oids = index_oid; index->len = 5;
This example will generate the index tuple, nothing else.
4.1.1.2. Rest of context structure
The rest of the generated structure contains columnar (leaf nodes) mapped to C types. The generator assumes the most general type of the object - therefore a TruthValue textual convention in a MIB will map to an ASN_INTEGER type - in C language this will be unsigned long. If you don't remember what textual conventions are and what their basics data types are, consult the SNMP-v2-TC MIB file.
The length of the data (if the columnar node is defined as OCTET STRING(SIZE(1..10)) is NOT taken under consideration and has to be manually changed from the maximum length. As in with : /** OCTETSTR = ASN_OCTET_STR */ char nsIETFWGName[65535]; long nsIETFWGName_len;Where nsIETFWGName is mapped to the columnar node nsIETFWGName of string size greater than one but less than thirty-two. nsIETFWGName OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..32)) MAX-ACCESS not-accessible STATUS current DESCRIPTION "The name of the IETF Working Group this table describes." ::= { netSnmpIETFWGEntry 1 }Please consult NET-SNMP-EXAMPLES-MIB.txt for the rest of the object if interested. |
Subsequent examples will demonstrate how to fully leverage the rest of the context structure. Please consult Section 5.2.6.2.
4.1.2. Functions
The 'mib2c' places the function prototypes right behind the context structure and also behind the textual names of the leaf nodes.
void init_netSnmpIETFWGTable(void); void initialize_table_netSnmpIETFWGTable(void); const netSnmpIETFWGTable_context * netSnmpIETFWGTable_get_by_idx(netsnmp_index *); const netSnmpIETFWGTable_context * netSnmpIETFWGTable_get_by_idx_rs(netsnmp_index *, int row_status); int netSnmpIETFWGTable_get_value(netsnmp_request_info *, netsnmp_index *, netsnmp_table_request_info *);
The first set of declared functions are used to:
-
Initialize the table. This function will be fully explained in Section 5.1
-
Helper functions for retrieving the secondary index value. What is a secondary index value? It is the second index in a index tuple. For detail information, please look in Section 5.1.7.1 and Section 5.2.6.2.
This function allows for the sub-agent to check (or reshape) of the column objects in a row before delievering to the user.
-
Helper functions for retrieving the data value of the columnar object in a specific row. The column number, and row is passed in to this function.
The next set of functions are controlled by a set of #define statements. These operations are for writing, deleting, creating, and retrieving secondary index of rows.
#ifdef netSnmpIETFWGTable_SET_HANDLING int netSnmpIETFWGTable_extract_index( netSnmpIETFWGTable_context * ctx, netsnmp_index * hdr ); void netSnmpIETFWGTable_set_reserve1( netsnmp_request_group * ); void netSnmpIETFWGTable_set_reserve2( netsnmp_request_group * ); void netSnmpIETFWGTable_set_action( netsnmp_request_group * ); void netSnmpIETFWGTable_set_commit( netsnmp_request_group * ); void netSnmpIETFWGTable_set_free( netsnmp_request_group * ); void netSnmpIETFWGTable_set_undo( netsnmp_request_group * ); netSnmpIETFWGTable_context * netSnmpIETFWGTable_duplicate_row( netSnmpIETFWGTable_context* ); netsnmp_index * netSnmpIETFWGTable_delete_row( netSnmpIETFWGTable_context* ); int netSnmpIETFWGTable_can_delete(netSnmpIETFWGTable_context *undo_ctx, netSnmpIETFWGTable_context *row_ctx, netsnmp_request_group * rg); #ifdef netSnmpIETFWGTable_ROW_CREATION netSnmpIETFWGTable_context * netSnmpIETFWGTable_create_row( netsnmp_index* ); #endif #endif #ifdef netSnmpIETFWGTable_IDX2 netSnmpIETFWGTable_context * netSnmpIETFWGTable_get( const char *name, int len ); #endif
There are three sets of functions:
-
For SNMP SET operations. These operations are used to write and delete (if appropiate) rows. Consult Section 5.2.5 and Section 5.2.7 for more details.
-
For creation of rows. Consult Section 5.2.6 for more details.
-
Manipulating secondary (or more) index tuple. Consult Section 5.1.7.1.
4.1.3. Object IDentifier of the table
The 'mib2c' tool also extracts the OID of the table. This sequence of numbers is used by the sub-agent when registering the table.
4.1.4. Textual names for leaf nodes
The leaf nodes object names (from the MIB) are translated to a list of #define in the format of:
#define COLUMN_<name of the leaf node> <columnar index value>
for each of the leaf nodes.
#define COLUMN_NSIETFWGNAME 1 #define COLUMN_NSIETFWGCHAIR1 2 #define COLUMN_NSIETFWGCHAIR2 3
These textual names are used in the generated C source code instead of the numerical values for developer convenience.
4.1.5. Enabling and disabling operations
The three set of #define statements disable or enable sub-agent operations.
-
Commenting out netSnmpIETFWGTable_SET_HANDLING will make the sub-agent not handle SNMP SET requests.
-
Commenting out netSnmpIETFWGTable_ROW_CREATION will not allow the sub-agent to create rows.
-
Commenting out netSnmpIETFWGTable_IDX2 disables the handling of secondary (or more) of index.
These #define statements also exist in the generated C source code to properly disable/enable certain functions. For the purpose of this tutorial assume that all of the #define have to be enabled except netSnmpIETFWGTable_IDX2 (consult Section 5.1.8 for details on the usage of this switch).