<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML ><HEAD ><TITLE >Header file</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK REL="HOME" TITLE="NetSNMP subagent development manual" HREF="book1.html"><LINK REL="PREVIOUS" TITLE="Understanding the sub-agent" HREF="c167.html"><LINK REL="NEXT" TITLE="C code" HREF="c299.html"><link rel="stylesheet" href="/openhpi.css" type="text/css"> </head ><BODY CLASS="CHAPTER" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><div id="banner"><div><h1>The OpenHPI Project</h1><small>Open Hardware Platform Interface</small></div></div><table><tr> <!--#include virtual="/sidebar.html" --> <td id="maincolumn"><div class="mainsegment"> <DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >NetSNMP subagent development manual</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="c167.html" ACCESSKEY="P" ><<< Previous</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="c299.html" ACCESSKEY="N" >Next >>></A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="CHAPTER" ><H1 ><A NAME="AEN188" ></A >Header file</H1 ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="AEN190" >Header files</A ></H1 ><P > The header file generated by the 'mib2c' tool consist of five elements: </P ><P ></P ><UL ><LI STYLE="list-style-type: opencircle" ><P >A <I CLASS="EMPHASIS" >context</I > 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. </P ></LI ><LI STYLE="list-style-type: opencircle" ><P > Functions for manipulating the <I CLASS="EMPHASIS" >context</I > structure. These include generic functions for sorting, getting an item, checking for correct boundary conditions, and generating the index tuple. </P ></LI ><LI STYLE="list-style-type: opencircle" ><P > Object IDentifier for the table. </P ></LI ><LI STYLE="list-style-type: opencircle" ><P > Textual names of the leaf nodes (columnar objects) using #define. </P ></LI ><LI STYLE="list-style-type: opencircle" ><P > #define enabling/disabling different functions of the sub-agent table manipulations. </P ></LI ></UL ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="CONTEXT_STRUCTURE" >Context structure</A ></H2 ><P > The <I CLASS="EMPHASIS" >context</I > structure is used exclusivly by the NetSNMP API for manipulating rows of leaf nodes (columnar objects). </P ><P > The first named variables of the structure is the <I CLASS="EMPHASIS" >index</I > variable. </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > typedef struct netSnmpIETFWGTable_context_s { netsnmp_index index; /** THIS MUST BE FIRST!!! */ .... </PRE ></TD ></TR ></TABLE ><P >The <I CLASS="EMPHASIS" >netsnmp_index</I > is defined in <I CLASS="EMPHASIS" >net-snmp/types.h</I > as </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > typedef struct netsnmp_index_s { int len; oid *oids; } netsnmp_index; </PRE ></TD ></TR ></TABLE ><P > The <I CLASS="EMPHASIS" >oid</I > is defined as unsigned long (look in net-snmp/library/asn1.h). The <I CLASS="EMPHASIS" >len</I > is the number of entries in the *oids array, <I CLASS="EMPHASIS" >not</I > the length of the OID in the bytes. </P ><P > This <I CLASS="EMPHASIS" >netsnmp_index</I > 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. </P ><DIV CLASS="SECT3" ><H3 CLASS="SECT3" ><A NAME="AEN223" >Example of using netsnmp_index</A ></H3 ><P > The example uses the IETF WG table structure to set the index tuple to the string "fodo." </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > 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; </PRE ></TD ></TR ></TABLE ><P > This example will generate the index tuple, nothing else. </P ></DIV ><DIV CLASS="SECT3" ><H3 CLASS="SECT3" ><A NAME="AEN228" >Rest of context structure</A ></H3 ><P > 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 <I CLASS="EMPHASIS" >TruthValue</I > textual convention in a MIB will map to an ASN_INTEGER type - in C language this will be <I CLASS="EMPHASIS" >unsigned long</I >. If you don't remember what textual conventions are and what their basics data types are, consult the SNMP-v2-TC MIB file. </P ><DIV CLASS="NOTE" ><P ></P ><TABLE CLASS="NOTE" WIDTH="100%" BORDER="0" ><TR ><TD WIDTH="25" ALIGN="CENTER" VALIGN="TOP" ><IMG SRC="./stylesheet-images/note.gif" HSPACE="5" ALT="Note"></TD ><TD ALIGN="LEFT" VALIGN="TOP" ><P > The length of the data (if the columnar node is defined as <I CLASS="EMPHASIS" > OCTET STRING(SIZE(1..10))</I > is NOT taken under consideration and has to be manually changed from the maximum length. As in with : <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > /** OCTETSTR = ASN_OCTET_STR */ char nsIETFWGName[65535]; long nsIETFWGName_len; </PRE ></TD ></TR ></TABLE > Where <I CLASS="EMPHASIS" >nsIETFWGName</I > is mapped to the columnar node <I CLASS="EMPHASIS" >nsIETFWGName</I > of string size greater than one but less than thirty-two. <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" >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 }</PRE ></TD ></TR ></TABLE > Please consult <I CLASS="EMPHASIS" >NET-SNMP-EXAMPLES-MIB.txt</I > for the rest of the object if interested. </P ></TD ></TR ></TABLE ></DIV ><P > Subsequent examples will demonstrate how to fully leverage the rest of the context structure. Please consult <A HREF="x406.html#DEVELOPER_ROW_CREATION" >the Section called <I >Developer row creation</I > in the Chapter called <I >C code</I ></A >. </P ></DIV ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN243" >Functions</A ></H2 ><P > The 'mib2c' places the function prototypes right behind the context structure and also behind the textual names of the leaf nodes. </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" >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 *); </PRE ></TD ></TR ></TABLE ><P > The first set of declared functions are used to: </P ><P ></P ><UL ><LI STYLE="list-style-type: closedcircle" ><P > Initialize the table. This function will be fully explained in <A HREF="c299.html#INITIALIZE_TABLE" >the Section called <I >Initializiation process of sub-agent</I > in the Chapter called <I >C code</I ></A > </P ></LI ><LI STYLE="list-style-type: closedcircle" ><P > 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 <A HREF="c299.html#N_TUPLE_INDEXES" >the Section called <I >Helper functions to handle n-tuple indexes</I > in the Chapter called <I >C code</I ></A > and <A HREF="x406.html#DEVELOPER_ROW_CREATION" >the Section called <I >Developer row creation</I > in the Chapter called <I >C code</I ></A >. </P ><P > This function allows for the sub-agent to check (or reshape) of the column objects in a row before delievering to the user. </P ></LI ><LI STYLE="list-style-type: closedcircle" ><P > 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. </P ></LI ></UL ><P > 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. </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" >#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</PRE ></TD ></TR ></TABLE ><P > There are three sets of functions: </P ><P ></P ><UL ><LI ><P > For SNMP SET operations. These operations are used to write and delete (if appropiate) rows. Consult <A HREF="x406.html#DELETE_ROWS" >the Section called <I >Deleting rows</I > in the Chapter called <I >C code</I ></A > and <A HREF="x406.html#WRITE_ROW" >the Section called <I >Writing to a row</I > in the Chapter called <I >C code</I ></A > for more details. </P ></LI ><LI ><P > For creation of rows. Consult <A HREF="x406.html#CREATE_ROWS" >the Section called <I >Creating rows</I > in the Chapter called <I >C code</I ></A > for more details. </P ></LI ><LI ><P > Manipulating secondary (or more) index tuple. Consult <A HREF="c299.html#N_TUPLE_INDEXES" >the Section called <I >Helper functions to handle n-tuple indexes</I > in the Chapter called <I >C code</I ></A >. </P ></LI ></UL ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN273" >Object IDentifier of the table</A ></H2 ><P > The 'mib2c' tool also extracts the OID of the table. This sequence of numbers is used by the sub-agent when registering the table. </P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN276" >Textual names for leaf nodes</A ></H2 ><P > The leaf nodes object names (from the MIB) are translated to a list of #define in the format of: </P ><P > #define COLUMN_<name of the leaf node> <columnar index value> </P ><P > for each of the leaf nodes. </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" >#define COLUMN_NSIETFWGNAME 1 #define COLUMN_NSIETFWGCHAIR1 2 #define COLUMN_NSIETFWGCHAIR2 3 </PRE ></TD ></TR ></TABLE ><P > These textual names are used in the generated C source code instead of the numerical values for developer convenience. </P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN283" >Enabling and disabling operations</A ></H2 ><P > The three set of #define statements disable or enable sub-agent operations. </P ><P ></P ><UL ><LI ><P >Commenting out <I CLASS="EMPHASIS" >netSnmpIETFWGTable_SET_HANDLING</I > will make the sub-agent not handle SNMP SET requests. </P ></LI ><LI ><P >Commenting out <I CLASS="EMPHASIS" >netSnmpIETFWGTable_ROW_CREATION</I > will not allow the sub-agent to create rows. </P ></LI ><LI ><P >Commenting out <I CLASS="EMPHASIS" >netSnmpIETFWGTable_IDX2</I > disables the handling of secondary (or more) of index. </P ></LI ></UL ><P >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 <I CLASS="EMPHASIS" >netSnmpIETFWGTable_IDX2</I > (consult <A HREF="c299.html#NETSNMPIETFWGTABLE_IDX2" >the Section called <I >Generic compare function</I > in the Chapter called <I >C code</I ></A > for details on the usage of this switch). </P ></DIV ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="c167.html" ACCESSKEY="P" ><<< Previous</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="book1.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="c299.html" ACCESSKEY="N" >Next >>></A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Understanding the sub-agent</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" > </TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >C code</TD ></TR ></TABLE ></DIV ></BODY ></HTML >