

<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.net-snmp.org/wiki/index.php?action=history&amp;feed=atom&amp;title=MFD%3AifTable%3AData_Structures</id>
		<title>MFD:ifTable:Data Structures - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.net-snmp.org/wiki/index.php?action=history&amp;feed=atom&amp;title=MFD%3AifTable%3AData_Structures"/>
		<link rel="alternate" type="text/html" href="http://www.net-snmp.org/wiki/index.php?title=MFD:ifTable:Data_Structures&amp;action=history"/>
		<updated>2026-05-04T21:20:19Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.26.3</generator>

	<entry>
		<id>http://www.net-snmp.org/wiki/index.php?title=MFD:ifTable:Data_Structures&amp;diff=5160&amp;oldid=prev</id>
		<title>Wes: Created page with &quot;{{MFDTutorial}}  == MFD Data Structures == There are a few basic data structures that the MFD template code uses extensively.           === Registration Pointer === The first str...&quot;</title>
		<link rel="alternate" type="text/html" href="http://www.net-snmp.org/wiki/index.php?title=MFD:ifTable:Data_Structures&amp;diff=5160&amp;oldid=prev"/>
				<updated>2011-07-13T17:28:06Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{MFDTutorial}}  == MFD Data Structures == There are a few basic data structures that the MFD template code uses extensively.           === Registration Pointer === The first str...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{MFDTutorial}}&lt;br /&gt;
&lt;br /&gt;
== MFD Data Structures ==&lt;br /&gt;
There are a few basic data structures that the MFD template code uses&lt;br /&gt;
extensively.&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
=== Registration Pointer ===&lt;br /&gt;
The first structure is the &amp;#039;&amp;#039;registration pointer&amp;#039;&amp;#039;. This&lt;br /&gt;
pointer is supplied by the implementor in the module&amp;#039;s initialization&lt;br /&gt;
routine. It is never used by the MFD code, but is passed as a parameter&lt;br /&gt;
to virtually every generated function. It is for the convenience of the&lt;br /&gt;
implementor. By default it will be a &amp;#039;&amp;#039;netsnmp_data_list&amp;#039;&amp;#039;&lt;br /&gt;
pointer.&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
=== Data Context ===&lt;br /&gt;
The next structure is the &amp;#039;&amp;#039;data context&amp;#039;&amp;#039;. This structure&lt;br /&gt;
should contain all the data for a particular row. By default, mib2c&lt;br /&gt;
will generate this data structure, and it will contain storage&lt;br /&gt;
for each column in the table. Running mib2c on the&lt;br /&gt;
ifTable table results in this data context structure:&lt;br /&gt;
    &amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
          &amp;lt;td width=20&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td bgcolor=CCCCCC&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * data context&lt;br /&gt;
     */&lt;br /&gt;
    /*&lt;br /&gt;
     * This structure contains storage for all the columns defined in the&lt;br /&gt;
     * ifTable.&lt;br /&gt;
     */&lt;br /&gt;
    typedef struct ifTable_data_s {&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifDescr(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H&lt;br /&gt;
         */&lt;br /&gt;
        char            ifDescr[255];&lt;br /&gt;
        size_t          ifDescr_len;    /* # of char elements, not bytes */&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifType(3)/IANAifType/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifType;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifMtu(4)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        long            ifMtu;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifSpeed(5)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifSpeed;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifPhysAddress(6)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/H&lt;br /&gt;
         */&lt;br /&gt;
        char            ifPhysAddress[65535];&lt;br /&gt;
        size_t          ifPhysAddress_len;      /* # of char elements, not bytes */&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifAdminStatus;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOperStatus(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOperStatus;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifLastChange(9)/TICKS/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifLastChange;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInOctets(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInOctets;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInUcastPkts(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInUcastPkts;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInNUcastPkts(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInNUcastPkts;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInDiscards(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInDiscards;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInErrors(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInErrors;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifInUnknownProtos(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifInUnknownProtos;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutOctets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutOctets;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutUcastPkts(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutUcastPkts;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutNUcastPkts(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutNUcastPkts;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutDiscards(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutDiscards;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutErrors(20)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutErrors;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifOutQLen(21)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        u_long          ifOutQLen;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifSpecific(22)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/d/h&lt;br /&gt;
         */&lt;br /&gt;
        oid             ifSpecific[128];&lt;br /&gt;
        size_t          ifSpecific_len; /* # of oid elements, not bytes */&lt;br /&gt;
 &lt;br /&gt;
    } ifTable_data;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
      &amp;lt;/table&amp;gt;&lt;br /&gt;
If you have an existing data structure that contains all the data for&lt;br /&gt;
your table, you can use that instead (we&amp;#039;ll cover that in a later&lt;br /&gt;
tutorial).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MIB Index ===&lt;br /&gt;
When a MIB table is defined, it has an INDEX clause that defines how&lt;br /&gt;
the data in the table is ordered when queried. mib2c generates a&lt;br /&gt;
&amp;#039;&amp;#039;MIB index&amp;#039;&amp;#039; structure with sufficent storage to represent&lt;br /&gt;
the index for a table row. Running mib2c on the&lt;br /&gt;
ifTable table results in this MIB index structure:&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
          &amp;lt;td width=20&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td bgcolor=CCCCCC&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     * This structure is used to represent the index for a table.&lt;br /&gt;
     */&lt;br /&gt;
    typedef struct ifTable_mib_index_s {&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H&lt;br /&gt;
         */&lt;br /&gt;
        long            ifIndex;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    } ifTable_mib_index;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Row Request Context ===&lt;br /&gt;
The next structure is the &amp;#039;&amp;#039;row context&amp;#039;&amp;#039;. This structure is&lt;br /&gt;
used during the processing of a SNMP request. It is contains all the&lt;br /&gt;
previous structures, and a few additional items.&lt;br /&gt;
Running mib2c on the ifTable table results in&lt;br /&gt;
this row request context structure:&lt;br /&gt;
    &amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
          &amp;lt;td width=20&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td bgcolor=CCCCCC&amp;gt;&lt;br /&gt;
    /*&lt;br /&gt;
     *********************************************************************&lt;br /&gt;
     * Row request context&lt;br /&gt;
     * When your functions are called, you will be passed a&lt;br /&gt;
     * ifTable_rowreq_ctx pointer.&lt;br /&gt;
     */&lt;br /&gt;
    typedef struct ifTable_rowreq_ctx_s {&lt;br /&gt;
 &lt;br /&gt;
    /** this must be first for container compare to work */&lt;br /&gt;
        netsnmp_index   oid_idx;&lt;br /&gt;
        oid             oid_tmp[MAX_OID_LEN];   /* xxx-rks: shrink this */&lt;br /&gt;
 &lt;br /&gt;
        ifTable_mib_index tbl_idx;&lt;br /&gt;
 &lt;br /&gt;
        ifTable_data    data;&lt;br /&gt;
        ifTable_undo_data *undo;&lt;br /&gt;
        unsigned int    set_flags;&lt;br /&gt;
 &lt;br /&gt;
    /** implementor&amp;#039;s context pointer provided during registration */&lt;br /&gt;
        ifTable_registration_ptr ifTable_reg;&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * TODO:&lt;br /&gt;
         * add any other useful data&lt;br /&gt;
         *       (e.g. flags for when a column has been set)&lt;br /&gt;
         */&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
         * storage for future expansion&lt;br /&gt;
         */&lt;br /&gt;
        netsnmp_data_list *ifTable_data_list;&lt;br /&gt;
 &lt;br /&gt;
    } ifTable_rowreq_ctx;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
      &amp;lt;/table&amp;gt;&lt;br /&gt;
The registration pointer (&amp;#039;&amp;#039;ifTable_reg&amp;#039;&amp;#039; in this&lt;br /&gt;
example), mib index (&amp;#039;&amp;#039;tbl_idx&amp;#039;&amp;#039;) and data context&lt;br /&gt;
(&amp;#039;&amp;#039;data&amp;#039;&amp;#039;) were discussed above. The oid varaibles&lt;br /&gt;
&amp;#039;&amp;#039;oid_idx&amp;#039;&amp;#039; and &amp;#039;&amp;#039;oid_tmp&amp;#039;&amp;#039; are used internally,&lt;br /&gt;
and will likely go away in the future. The data_list&lt;br /&gt;
is a generic way of dynamically storing one or more pointers, using&lt;br /&gt;
a string as the storage and retrieval key. It is not currently used&lt;br /&gt;
internally, but may be in the future. For the implementor, it is&lt;br /&gt;
a convienent way of storing additional data for a row request, without&lt;br /&gt;
having to modify the row request structure itself.&lt;/div&gt;</summary>
		<author><name>Wes</name></author>	</entry>

	</feed>