/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 12088 $ of $ 
 *
 * $Id:$
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "etherStatsTable.h"


/** @defgroup data_get data_get: Routines to get data
 *
 * TODO:230:M: Implement etherStatsTable get routines.
 * TODO:240:M: Implement etherStatsTable mapping routines (if any).
 *
 * These routine are used to get the value for individual objects. The
 * row context is passed, along with a pointer to the memory where the
 * value should be copied.
 *
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table etherStatsTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * RMON-MIB::etherStatsTable is subid 1 of statistics.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.16.1.1, length: 9
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement etherStatsTable data context functions.
 */


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param etherStatsIndex_val
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
etherStatsTable_indexes_set_tbl_idx(etherStatsTable_mib_index * tbl_idx,
                                    long etherStatsIndex_val)
{
    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_indexes_set_tbl_idx", "called\n"));

    /*
     * etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    tbl_idx->etherStatsIndex = etherStatsIndex_val;


    return MFD_SUCCESS;
}                               /* etherStatsTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
etherStatsTable_indexes_set(etherStatsTable_rowreq_ctx * rowreq_ctx,
                            long etherStatsIndex_val)
{
    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_indexes_set",
                "called\n"));

    if (MFD_SUCCESS !=
        etherStatsTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                            etherStatsIndex_val))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != etherStatsTable_index_to_oid(&rowreq_ctx->oid_idx,
                                          &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* etherStatsTable_indexes_set */


/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsDataSource
 * etherStatsDataSource is subid 2 of etherStatsEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.16.1.1.1.2
 * Description:
This object identifies the source of the data that
        this etherStats entry is configured to analyze.  This
        source can be any ethernet interface on this device.
        In order to identify a particular interface, this object
        shall identify the instance of the ifIndex object,
        defined in RFC 2233 [17], for the desired interface.
        For example, if an entry were to receive data from
        interface #1, this object would be set to ifIndex.1.

        The statistics in this group reflect all packets
        on the local network segment attached to the identified
        interface.

        An agent may or may not be able to tell if fundamental
        changes to the media of the interface have occurred and
        necessitate an invalidation of this entry.  For example, a
        hot-pluggable ethernet card could be pulled out and replaced
        by a token-ring card.  In such a case, if the agent has such
        knowledge of the change, it is recommended that it
        invalidate this entry.

        This object may not be modified if the associated
        etherStatsStatus object is equal to valid(1).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is OBJECTID (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.
 */
/**
 * Extract the current value of the etherStatsDataSource data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsDataSource_val_ptr_ptr
 *        Pointer to storage for a oid variable
 * @param etherStatsDataSource_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by etherStatsDataSource.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*etherStatsDataSource_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update etherStatsDataSource_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
etherStatsDataSource_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                         oid ** etherStatsDataSource_val_ptr_ptr,
                         size_t *etherStatsDataSource_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != etherStatsDataSource_val_ptr_ptr)
                   && (NULL != *etherStatsDataSource_val_ptr_ptr));
    netsnmp_assert(NULL != etherStatsDataSource_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsDataSource_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsDataSource data.
     * copy (* etherStatsDataSource_val_ptr_ptr ) data and (* etherStatsDataSource_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /*
     * make sure there is enough space for etherStatsDataSource data
     */
    if ((NULL == (*etherStatsDataSource_val_ptr_ptr)) ||
        ((*etherStatsDataSource_val_ptr_len_ptr) <
         (rowreq_ctx->data.etherStatsDataSource_len *
          sizeof(rowreq_ctx->data.etherStatsDataSource[0])))) {
        /*
         * allocate space for etherStatsDataSource data
         */
        (*etherStatsDataSource_val_ptr_ptr) =
            malloc(rowreq_ctx->data.etherStatsDataSource_len *
                   sizeof(rowreq_ctx->data.etherStatsDataSource[0]));
        if (NULL == (*etherStatsDataSource_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*etherStatsDataSource_val_ptr_len_ptr) =
        rowreq_ctx->data.etherStatsDataSource_len *
        sizeof(rowreq_ctx->data.etherStatsDataSource[0]);
    memcpy((*etherStatsDataSource_val_ptr_ptr),
           rowreq_ctx->data.etherStatsDataSource,
           rowreq_ctx->data.etherStatsDataSource_len *
           sizeof(rowreq_ctx->data.etherStatsDataSource[0]));

    return MFD_SUCCESS;
}                               /* etherStatsDataSource_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsDropEvents
 * etherStatsDropEvents is subid 3 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.3
 * Description:
The total number of events in which packets
        were dropped by the probe due to lack of resources.
        Note that this number is not necessarily the number of
        packets dropped; it is just the number of times this
        condition has been detected.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsDropEvents data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsDropEvents_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsDropEvents_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                         u_long * etherStatsDropEvents_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsDropEvents_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsDropEvents_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsDropEvents data.
     * copy (* etherStatsDropEvents_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsDropEvents_val_ptr) =
        rowreq_ctx->data.etherStatsDropEvents;

    return MFD_SUCCESS;
}                               /* etherStatsDropEvents_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsOctets
 * etherStatsOctets is subid 4 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.4
 * Description:
The total number of octets of data (including
        those in bad packets) received on the
        network (excluding framing bits but including
        FCS octets).

        This object can be used as a reasonable estimate of
        10-Megabit ethernet utilization.  If greater precision is
        desired, the etherStatsPkts and etherStatsOctets objects
        should be sampled before and after a common interval.  The
        differences in the sampled values are Pkts and Octets,
        respectively, and the number of seconds in the interval is
        Interval.  These values are used to calculate the Utilization
        as follows:

                         Pkts * (9.6 + 6.4) + (Octets * .8)
         Utilization = -------------------------------------
                                 Interval * 10,000

        The result of this equation is the value Utilization which
        is the percent utilization of the ethernet segment on a
        scale of 0 to 100 percent.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsOctets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsOctets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsOctets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                     u_long * etherStatsOctets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsOctets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsOctets_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsOctets data.
     * copy (* etherStatsOctets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsOctets_val_ptr) = rowreq_ctx->data.etherStatsOctets;

    return MFD_SUCCESS;
}                               /* etherStatsOctets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts
 * etherStatsPkts is subid 5 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.5
 * Description:
The total number of packets (including bad packets,
        broadcast packets, and multicast packets) received.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                   u_long * etherStatsPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts data.
     * copy (* etherStatsPkts_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts_val_ptr) = rowreq_ctx->data.etherStatsPkts;

    return MFD_SUCCESS;
}                               /* etherStatsPkts_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsBroadcastPkts
 * etherStatsBroadcastPkts is subid 6 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.6
 * Description:
The total number of good packets received that were
        directed to the broadcast address.  Note that this
        does not include multicast packets.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsBroadcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsBroadcastPkts_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsBroadcastPkts_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                            u_long * etherStatsBroadcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsBroadcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsBroadcastPkts_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsBroadcastPkts data.
     * copy (* etherStatsBroadcastPkts_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsBroadcastPkts_val_ptr) =
        rowreq_ctx->data.etherStatsBroadcastPkts;

    return MFD_SUCCESS;
}                               /* etherStatsBroadcastPkts_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsMulticastPkts
 * etherStatsMulticastPkts is subid 7 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.7
 * Description:
The total number of good packets received that were
        directed to a multicast address.  Note that this number
        does not include packets directed to the broadcast

        address.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsMulticastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsMulticastPkts_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsMulticastPkts_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                            u_long * etherStatsMulticastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsMulticastPkts_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsMulticastPkts_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsMulticastPkts data.
     * copy (* etherStatsMulticastPkts_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsMulticastPkts_val_ptr) =
        rowreq_ctx->data.etherStatsMulticastPkts;

    return MFD_SUCCESS;
}                               /* etherStatsMulticastPkts_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsCRCAlignErrors
 * etherStatsCRCAlignErrors is subid 8 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.8
 * Description:
The total number of packets received that
        had a length (excluding framing bits, but
        including FCS octets) of between 64 and 1518
        octets, inclusive, but had either a bad
        Frame Check Sequence (FCS) with an integral
        number of octets (FCS Error) or a bad FCS with
        a non-integral number of octets (Alignment Error).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsCRCAlignErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsCRCAlignErrors_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsCRCAlignErrors_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                             u_long * etherStatsCRCAlignErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsCRCAlignErrors_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsCRCAlignErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsCRCAlignErrors data.
     * copy (* etherStatsCRCAlignErrors_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsCRCAlignErrors_val_ptr) =
        rowreq_ctx->data.etherStatsCRCAlignErrors;

    return MFD_SUCCESS;
}                               /* etherStatsCRCAlignErrors_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsUndersizePkts
 * etherStatsUndersizePkts is subid 9 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.9
 * Description:
The total number of packets received that were
        less than 64 octets long (excluding framing bits,
        but including FCS octets) and were otherwise well
        formed.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsUndersizePkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsUndersizePkts_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsUndersizePkts_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                            u_long * etherStatsUndersizePkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsUndersizePkts_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsUndersizePkts_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsUndersizePkts data.
     * copy (* etherStatsUndersizePkts_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsUndersizePkts_val_ptr) =
        rowreq_ctx->data.etherStatsUndersizePkts;

    return MFD_SUCCESS;
}                               /* etherStatsUndersizePkts_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsOversizePkts
 * etherStatsOversizePkts is subid 10 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.10
 * Description:
The total number of packets received that were
        longer than 1518 octets (excluding framing bits,
        but including FCS octets) and were otherwise
        well formed.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsOversizePkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsOversizePkts_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsOversizePkts_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                           u_long * etherStatsOversizePkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsOversizePkts_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsOversizePkts_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsOversizePkts data.
     * copy (* etherStatsOversizePkts_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsOversizePkts_val_ptr) =
        rowreq_ctx->data.etherStatsOversizePkts;

    return MFD_SUCCESS;
}                               /* etherStatsOversizePkts_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsFragments
 * etherStatsFragments is subid 11 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.11
 * Description:
The total number of packets received that were less than
        64 octets in length (excluding framing bits but including
        FCS octets) and had either a bad Frame Check Sequence
        (FCS) with an integral number of octets (FCS Error) or a
        bad FCS with a non-integral number of octets (Alignment
        Error).

        Note that it is entirely normal for etherStatsFragments to
        increment.  This is because it counts both runts (which are
        normal occurrences due to collisions) and noise hits.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsFragments data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsFragments_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsFragments_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                        u_long * etherStatsFragments_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsFragments_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsFragments_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsFragments data.
     * copy (* etherStatsFragments_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsFragments_val_ptr) = rowreq_ctx->data.etherStatsFragments;

    return MFD_SUCCESS;
}                               /* etherStatsFragments_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsJabbers
 * etherStatsJabbers is subid 12 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.12
 * Description:
The total number of packets received that were
        longer than 1518 octets (excluding framing bits,
        but including FCS octets), and had either a bad
        Frame Check Sequence (FCS) with an integral number
        of octets (FCS Error) or a bad FCS with a non-integral
        number of octets (Alignment Error).

        Note that this definition of jabber is different
        than the definition in IEEE-802.3 section 8.2.1.5
        (10BASE5) and section 10.3.1.4 (10BASE2).  These
        documents define jabber as the condition where any
        packet exceeds 20 ms.  The allowed range to detect
        jabber is between 20 ms and 150 ms.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsJabbers data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsJabbers_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsJabbers_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                      u_long * etherStatsJabbers_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsJabbers_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsJabbers_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);
    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsJabbers data.
     * copy (* etherStatsJabbers_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsJabbers_val_ptr) = rowreq_ctx->data.etherStatsJabbers;

    return MFD_SUCCESS;
}                               /* etherStatsJabbers_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsCollisions
 * etherStatsCollisions is subid 13 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.13
 * Description:
The best estimate of the total number of collisions
        on this Ethernet segment.

        The value returned will depend on the location of the
        RMON probe. Section 8.2.1.3 (10BASE-5) and section
        10.3.1.3 (10BASE-2) of IEEE standard 802.3 states that a
        station must detect a collision, in the receive mode, if
        three or more stations are transmitting simultaneously.  A
        repeater port must detect a collision when two or more

        stations are transmitting simultaneously.  Thus a probe
        placed on a repeater port could record more collisions
        than a probe connected to a station on the same segment
        would.

        Probe location plays a much smaller role when considering
        10BASE-T.  14.2.1.4 (10BASE-T) of IEEE standard 802.3
        defines a collision as the simultaneous presence of signals
        on the DO and RD circuits (transmitting and receiving
        at the same time).  A 10BASE-T station can only detect
        collisions when it is transmitting.  Thus probes placed on
        a station and a repeater, should report the same number of
        collisions.

        Note also that an RMON probe inside a repeater should
        ideally report collisions between the repeater and one or
        more other hosts (transmit collisions as defined by IEEE
        802.3k) plus receiver collisions observed on any coax
        segments to which the repeater is connected.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsCollisions data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsCollisions_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsCollisions_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                         u_long * etherStatsCollisions_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsCollisions_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsCollisions_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsCollisions data.
     * copy (* etherStatsCollisions_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsCollisions_val_ptr) =
        rowreq_ctx->data.etherStatsCollisions;

    return MFD_SUCCESS;
}                               /* etherStatsCollisions_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts64Octets
 * etherStatsPkts64Octets is subid 14 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.14
 * Description:
The total number of packets (including bad
        packets) received that were 64 octets in length
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts64Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts64Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts64Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                           u_long * etherStatsPkts64Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts64Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts64Octets_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts64Octets data.
     * copy (* etherStatsPkts64Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts64Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts64Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts64Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts65to127Octets
 * etherStatsPkts65to127Octets is subid 15 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.15
 * Description:
The total number of packets (including bad
        packets) received that were between
        65 and 127 octets in length inclusive
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts65to127Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts65to127Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts65to127Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                                u_long *
                                etherStatsPkts65to127Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts65to127Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts65to127Octets_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts65to127Octets data.
     * copy (* etherStatsPkts65to127Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts65to127Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts65to127Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts65to127Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts128to255Octets
 * etherStatsPkts128to255Octets is subid 16 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.16
 * Description:
The total number of packets (including bad
        packets) received that were between
        128 and 255 octets in length inclusive
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts128to255Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts128to255Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts128to255Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                                 u_long *
                                 etherStatsPkts128to255Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts128to255Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts128to255Octets_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts128to255Octets data.
     * copy (* etherStatsPkts128to255Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts128to255Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts128to255Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts128to255Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts256to511Octets
 * etherStatsPkts256to511Octets is subid 17 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.17
 * Description:
The total number of packets (including bad
        packets) received that were between
        256 and 511 octets in length inclusive
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts256to511Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts256to511Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts256to511Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                                 u_long *
                                 etherStatsPkts256to511Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts256to511Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts256to511Octets_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts256to511Octets data.
     * copy (* etherStatsPkts256to511Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts256to511Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts256to511Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts256to511Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts512to1023Octets
 * etherStatsPkts512to1023Octets is subid 18 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.18
 * Description:
The total number of packets (including bad
        packets) received that were between
        512 and 1023 octets in length inclusive
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts512to1023Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts512to1023Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts512to1023Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                                  u_long *
                                  etherStatsPkts512to1023Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts512to1023Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts512to1023Octets_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts512to1023Octets data.
     * copy (* etherStatsPkts512to1023Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts512to1023Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts512to1023Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts512to1023Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsPkts1024to1518Octets
 * etherStatsPkts1024to1518Octets is subid 19 of etherStatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.16.1.1.1.19
 * Description:
The total number of packets (including bad
        packets) received that were between
        1024 and 1518 octets in length inclusive
        (excluding framing bits but including FCS octets).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the etherStatsPkts1024to1518Octets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsPkts1024to1518Octets_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsPkts1024to1518Octets_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                                   u_long *
                                   etherStatsPkts1024to1518Octets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsPkts1024to1518Octets_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsPkts1024to1518Octets_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsPkts1024to1518Octets data.
     * copy (* etherStatsPkts1024to1518Octets_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsPkts1024to1518Octets_val_ptr) =
        rowreq_ctx->data.etherStatsPkts1024to1518Octets;

    return MFD_SUCCESS;
}                               /* etherStatsPkts1024to1518Octets_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsOwner
 * etherStatsOwner is subid 20 of etherStatsEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.16.1.1.1.20
 * Description:
The entity that configured this entry and is therefore
        using the resources assigned to it.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   0
 *   settable   1
 *
 * Ranges:  0 - 127;
 *
 * Its syntax is OwnerString (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 127)
 */
/**
 * Extract the current value of the etherStatsOwner data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsOwner_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param etherStatsOwner_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by etherStatsOwner.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*etherStatsOwner_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update etherStatsOwner_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
etherStatsOwner_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                    char **etherStatsOwner_val_ptr_ptr,
                    size_t *etherStatsOwner_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != etherStatsOwner_val_ptr_ptr)
                   && (NULL != *etherStatsOwner_val_ptr_ptr));
    netsnmp_assert(NULL != etherStatsOwner_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsOwner_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsOwner data.
     * copy (* etherStatsOwner_val_ptr_ptr ) data and (* etherStatsOwner_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /*
     * make sure there is enough space for etherStatsOwner data
     */
    if ((NULL == (*etherStatsOwner_val_ptr_ptr)) ||
        ((*etherStatsOwner_val_ptr_len_ptr) <
         (rowreq_ctx->data.etherStatsOwner_len *
          sizeof(rowreq_ctx->data.etherStatsOwner[0])))) {
        /*
         * allocate space for etherStatsOwner data
         */
        (*etherStatsOwner_val_ptr_ptr) =
            malloc(rowreq_ctx->data.etherStatsOwner_len *
                   sizeof(rowreq_ctx->data.etherStatsOwner[0]));
        if (NULL == (*etherStatsOwner_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*etherStatsOwner_val_ptr_len_ptr) =
        rowreq_ctx->data.etherStatsOwner_len *
        sizeof(rowreq_ctx->data.etherStatsOwner[0]);
    memcpy((*etherStatsOwner_val_ptr_ptr),
           rowreq_ctx->data.etherStatsOwner,
           rowreq_ctx->data.etherStatsOwner_len *
           sizeof(rowreq_ctx->data.etherStatsOwner[0]));

    return MFD_SUCCESS;
}                               /* etherStatsOwner_get */

/*---------------------------------------------------------------------
 * RMON-MIB::etherStatsEntry.etherStatsStatus
 * etherStatsStatus is subid 21 of etherStatsEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.16.1.1.1.21
 * Description:
The status of this etherStats entry.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  valid(1), createRequest(2), underCreation(3), invalid(4)
 *
 * Its syntax is EntryStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the etherStatsStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param etherStatsStatus_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
etherStatsStatus_get(etherStatsTable_rowreq_ctx * rowreq_ctx,
                     u_long * etherStatsStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != etherStatsStatus_val_ptr);


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsStatus_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the etherStatsStatus data.
     * copy (* etherStatsStatus_val_ptr ) from rowreq_ctx->data
     */
    (*etherStatsStatus_val_ptr) = rowreq_ctx->data.etherStatsStatus;

    return MFD_SUCCESS;
}                               /* etherStatsStatus_get */



/** @} */
