/*
 * 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 "dot3StatsTable.h"


/** @defgroup data_get data_get: Routines to get data
 *
 * TODO:230:M: Implement dot3StatsTable get routines.
 * TODO:240:M: Implement dot3StatsTable 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 dot3StatsTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * EtherLike-MIB::dot3StatsTable is subid 2 of dot3.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.10.7.2, length: 9
 */

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


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param dot3StatsIndex_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
dot3StatsTable_indexes_set_tbl_idx(dot3StatsTable_mib_index * tbl_idx,
                                   long dot3StatsIndex_val)
{
    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsTable_indexes_set_tbl_idx", "called\n"));

    /*
     * dot3StatsIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H 
     */
    tbl_idx->dot3StatsIndex = dot3StatsIndex_val;


    return MFD_SUCCESS;
}                               /* dot3StatsTable_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
dot3StatsTable_indexes_set(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                           long dot3StatsIndex_val)
{
    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsTable_indexes_set",
                "called\n"));

    if (MFD_SUCCESS !=
        dot3StatsTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                           dot3StatsIndex_val))
        return MFD_ERROR;

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

    return MFD_SUCCESS;
}                               /* dot3StatsTable_indexes_set */


/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsAlignmentErrors
 * dot3StatsAlignmentErrors is subid 2 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.2
 * Description:
A count of frames received on a particular
                    interface that are not an integral number of
                    octets in length and do not pass the FCS check.

                    The count represented by an instance of this
                    object is incremented when the alignmentError
                    status is returned by the MAC service to the
                    LLC (or other MAC user). Received frames for
                    which multiple error conditions pertain are,
                    according to the conventions of IEEE 802.3
                    Layer Management, counted exclusively according

                    to the error status presented to the LLC.

                    This counter does not increment for group
                    encoding schemes greater than 4 bits per group.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 5 minutes if
                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a
                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsAlignmentErrors object for 10 Gb/s
                    or faster interfaces.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsAlignmentErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsAlignmentErrors_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
dot3StatsAlignmentErrors_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                             u_long * dot3StatsAlignmentErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsAlignmentErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsAlignmentErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsAlignmentErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsFCSErrors
 * dot3StatsFCSErrors is subid 3 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.3
 * Description:
A count of frames received on a particular
                    interface that are an integral number of octets
                    in length but do not pass the FCS check.  This
                    count does not include frames received with
                    frame-too-long or frame-too-short error.

                    The count represented by an instance of this
                    object is incremented when the frameCheckError
                    status is returned by the MAC service to the
                    LLC (or other MAC user). Received frames for
                    which multiple error conditions pertain are,
                    according to the conventions of IEEE 802.3
                    Layer Management, counted exclusively according
                    to the error status presented to the LLC.

                    Note:  Coding errors detected by the physical
                    layer for speeds above 10 Mb/s will cause the
                    frame to fail the FCS check.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 5 minutes if

                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a
                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsFCSErrors object for 10 Gb/s or
                    faster interfaces.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsFCSErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsFCSErrors_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
dot3StatsFCSErrors_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                       u_long * dot3StatsFCSErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsFCSErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsFCSErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsFCSErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsSingleCollisionFrames
 * dot3StatsSingleCollisionFrames is subid 4 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.4
 * Description:
A count of frames that are involved in a single
                    collision, and are subsequently transmitted
                    successfully.

                    A frame that is counted by an instance of this
                    object is also counted by the corresponding
                    instance of either the ifOutUcastPkts,
                    ifOutMulticastPkts, or ifOutBroadcastPkts,
                    and is not counted by the corresponding
                    instance of the dot3StatsMultipleCollisionFrames
                    object.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsSingleCollisionFrames data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsSingleCollisionFrames_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
dot3StatsSingleCollisionFrames_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                                   u_long *
                                   dot3StatsSingleCollisionFrames_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsSingleCollisionFrames_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsSingleCollisionFrames_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsSingleCollisionFrames_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsMultipleCollisionFrames
 * dot3StatsMultipleCollisionFrames is subid 5 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.5
 * Description:
A count of frames that are involved in more

                    than one collision and are subsequently
                    transmitted successfully.

                    A frame that is counted by an instance of this
                    object is also counted by the corresponding
                    instance of either the ifOutUcastPkts,
                    ifOutMulticastPkts, or ifOutBroadcastPkts,
                    and is not counted by the corresponding
                    instance of the dot3StatsSingleCollisionFrames
                    object.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsMultipleCollisionFrames data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsMultipleCollisionFrames_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
dot3StatsMultipleCollisionFrames_get(dot3StatsTable_rowreq_ctx *
                                     rowreq_ctx,
                                     u_long *
                                     dot3StatsMultipleCollisionFrames_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsMultipleCollisionFrames_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsMultipleCollisionFrames_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsMultipleCollisionFrames_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsSQETestErrors
 * dot3StatsSQETestErrors is subid 6 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.6
 * Description:
A count of times that the SQE TEST ERROR
                    is received on a particular interface. The
                    SQE TEST ERROR is set in accordance with the
                    rules for verification of the SQE detection
                    mechanism in the PLS Carrier Sense Function as
                    described in IEEE Std. 802.3, 2000 Edition,
                    section 7.2.4.6.

                    This counter does not increment on interfaces
                    operating at speeds greater than 10 Mb/s, or on
                    interfaces operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsSQETestErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsSQETestErrors_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
dot3StatsSQETestErrors_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                           u_long * dot3StatsSQETestErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsSQETestErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsSQETestErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsSQETestErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsDeferredTransmissions
 * dot3StatsDeferredTransmissions is subid 7 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.7
 * Description:
A count of frames for which the first
                    transmission attempt on a particular interface
                    is delayed because the medium is busy.

                    The count represented by an instance of this
                    object does not include frames involved in
                    collisions.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsDeferredTransmissions data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsDeferredTransmissions_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
dot3StatsDeferredTransmissions_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                                   u_long *
                                   dot3StatsDeferredTransmissions_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsDeferredTransmissions_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsDeferredTransmissions_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsDeferredTransmissions_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsLateCollisions
 * dot3StatsLateCollisions is subid 8 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.8
 * Description:
The number of times that a collision is
                    detected on a particular interface later than
                    one slotTime into the transmission of a packet.

                    A (late) collision included in a count
                    represented by an instance of this object is
                    also considered as a (generic) collision for
                    purposes of other collision-related
                    statistics.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsLateCollisions data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsLateCollisions_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
dot3StatsLateCollisions_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                            u_long * dot3StatsLateCollisions_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsLateCollisions_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsLateCollisions_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsLateCollisions_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsExcessiveCollisions
 * dot3StatsExcessiveCollisions is subid 9 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.9
 * Description:
A count of frames for which transmission on a
                    particular interface fails due to excessive
                    collisions.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsExcessiveCollisions data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsExcessiveCollisions_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
dot3StatsExcessiveCollisions_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                                 u_long *
                                 dot3StatsExcessiveCollisions_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsExcessiveCollisions_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsExcessiveCollisions_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsExcessiveCollisions_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsInternalMacTransmitErrors
 * dot3StatsInternalMacTransmitErrors is subid 10 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.10
 * Description:
A count of frames for which transmission on a
                    particular interface fails due to an internal
                    MAC sublayer transmit error. A frame is only
                    counted by an instance of this object if it is
                    not counted by the corresponding instance of
                    either the dot3StatsLateCollisions object, the
                    dot3StatsExcessiveCollisions object, or the
                    dot3StatsCarrierSenseErrors object.

                    The precise meaning of the count represented by
                    an instance of this object is implementation-
                    specific.  In particular, an instance of this
                    object may represent a count of transmission
                    errors on a particular interface that are not
                    otherwise counted.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 5 minutes if
                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a
                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsInternalMacTransmitErrors object for
                    10 Gb/s or faster interfaces.

                    Discontinuities in the value of this counter can

                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsInternalMacTransmitErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsInternalMacTransmitErrors_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
dot3StatsInternalMacTransmitErrors_get(dot3StatsTable_rowreq_ctx *
                                       rowreq_ctx,
                                       u_long *
                                       dot3StatsInternalMacTransmitErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsInternalMacTransmitErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsInternalMacTransmitErrors_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsInternalMacTransmitErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsCarrierSenseErrors
 * dot3StatsCarrierSenseErrors is subid 11 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.11
 * Description:
The number of times that the carrier sense
                    condition was lost or never asserted when
                    attempting to transmit a frame on a particular
                    interface.

                    The count represented by an instance of this
                    object is incremented at most once per
                    transmission attempt, even if the carrier sense
                    condition fluctuates during a transmission
                    attempt.

                    This counter does not increment when the
                    interface is operating in full-duplex mode.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsCarrierSenseErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsCarrierSenseErrors_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
dot3StatsCarrierSenseErrors_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                                u_long *
                                dot3StatsCarrierSenseErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsCarrierSenseErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsCarrierSenseErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsCarrierSenseErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsFrameTooLongs
 * dot3StatsFrameTooLongs is subid 13 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.13
 * Description:
A count of frames received on a particular
                    interface that exceed the maximum permitted
                    frame size.

                    The count represented by an instance of this
                    object is incremented when the frameTooLong
                    status is returned by the MAC service to the
                    LLC (or other MAC user). Received frames for
                    which multiple error conditions pertain are,
                    according to the conventions of IEEE 802.3
                    Layer Management, counted exclusively according
                    to the error status presented to the LLC.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 80 minutes if
                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a
                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsFrameTooLongs object for 10 Gb/s
                    or faster interfaces.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsFrameTooLongs data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsFrameTooLongs_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
dot3StatsFrameTooLongs_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                           u_long * dot3StatsFrameTooLongs_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsFrameTooLongs_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsFrameTooLongs_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsFrameTooLongs_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsInternalMacReceiveErrors
 * dot3StatsInternalMacReceiveErrors is subid 16 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.16
 * Description:
A count of frames for which reception on a
                    particular interface fails due to an internal
                    MAC sublayer receive error. A frame is only
                    counted by an instance of this object if it is
                    not counted by the corresponding instance of
                    either the dot3StatsFrameTooLongs object, the
                    dot3StatsAlignmentErrors object, or the
                    dot3StatsFCSErrors object.

                    The precise meaning of the count represented by
                    an instance of this object is implementation-
                    specific.  In particular, an instance of this
                    object may represent a count of receive errors
                    on a particular interface that are not
                    otherwise counted.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 5 minutes if

                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a
                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsInternalMacReceiveErrors object for
                    10 Gb/s or faster interfaces.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsInternalMacReceiveErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsInternalMacReceiveErrors_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
dot3StatsInternalMacReceiveErrors_get(dot3StatsTable_rowreq_ctx *
                                      rowreq_ctx,
                                      u_long *
                                      dot3StatsInternalMacReceiveErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsInternalMacReceiveErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsInternalMacReceiveErrors_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsInternalMacReceiveErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsEtherChipSet
 * dot3StatsEtherChipSet is subid 17 of dot3StatsEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.17
 * Description:
******** THIS OBJECT IS DEPRECATED ********

                    This object contains an OBJECT IDENTIFIER
                    which identifies the chipset used to
                    realize the interface. Ethernet-like
                    interfaces are typically built out of
                    several different chips. The MIB implementor
                    is presented with a decision of which chip
                    to identify via this object. The implementor
                    should identify the chip which is usually
                    called the Medium Access Control chip.
                    If no such chip is easily identifiable,
                    the implementor should identify the chip
                    which actually gathers the transmit
                    and receive statistics and error
                    indications. This would allow a
                    manager station to correlate the
                    statistics and the chip generating
                    them, giving it the ability to take
                    into account any known anomalies
                    in the chip.

                    This object has been deprecated.  Implementation
                    feedback indicates that it is of limited use for
                    debugging network problems in the field, and
                    the administrative overhead involved in
                    maintaining a registry of chipset OIDs is not
                    justified.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * 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 dot3StatsEtherChipSet data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsEtherChipSet_val_ptr_ptr
 *        Pointer to storage for a oid variable
 * @param dot3StatsEtherChipSet_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by dot3StatsEtherChipSet.
 *        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 (*dot3StatsEtherChipSet_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update dot3StatsEtherChipSet_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
dot3StatsEtherChipSet_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                          oid ** dot3StatsEtherChipSet_val_ptr_ptr,
                          size_t *dot3StatsEtherChipSet_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != dot3StatsEtherChipSet_val_ptr_ptr)
                   && (NULL != *dot3StatsEtherChipSet_val_ptr_ptr));
    netsnmp_assert(NULL != dot3StatsEtherChipSet_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsEtherChipSet_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsEtherChipSet_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsSymbolErrors
 * dot3StatsSymbolErrors is subid 18 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.18
 * Description:
For an interface operating at 100 Mb/s, the
                    number of times there was an invalid data symbol
                    when a valid carrier was present.

                    For an interface operating in half-duplex mode
                    at 1000 Mb/s, the number of times the receiving
                    media is non-idle (a carrier event) for a period
                    of time equal to or greater than slotTime, and
                    during which there was at least one occurrence
                    of an event that causes the PHY to indicate
                    'Data reception error' or 'carrier extend error'
                    on the GMII.

                    For an interface operating in full-duplex mode
                    at 1000 Mb/s, the number of times the receiving
                    media is non-idle (a carrier event) for a period
                    of time equal to or greater than minFrameSize,
                    and during which there was at least one
                    occurrence of an event that causes the PHY to
                    indicate 'Data reception error' on the GMII.

                    For an interface operating at 10 Gb/s, the
                    number of times the receiving media is non-idle
                    (a carrier event) for a period of time equal to
                    or greater than minFrameSize, and during which
                    there was at least one occurrence of an event
                    that causes the PHY to indicate 'Receive Error'
                    on the XGMII.

                    The count represented by an instance of this
                    object is incremented at most once per carrier
                    event, even if multiple symbol errors occur
                    during the carrier event.  This count does
                    not increment if a collision is present.

                    This counter does not increment when the
                    interface is operating at 10 Mb/s.

                    For interfaces operating at 10 Gb/s, this
                    counter can roll over in less than 5 minutes if
                    it is incrementing at its maximum rate.  Since
                    that amount of time could be less than a

                    management station's poll cycle time, in order
                    to avoid a loss of information, a management
                    station is advised to poll the
                    dot3HCStatsSymbolErrors object for 10 Gb/s
                    or faster interfaces.

                    Discontinuities in the value of this counter can
                    occur at re-initialization of the management
                    system, and at other times as indicated by the
                    value of ifCounterDiscontinuityTime.
 *
 * 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 dot3StatsSymbolErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsSymbolErrors_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
dot3StatsSymbolErrors_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                          u_long * dot3StatsSymbolErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsSymbolErrors_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsSymbolErrors_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsSymbolErrors_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsDuplexStatus
 * dot3StatsDuplexStatus is subid 19 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.19
 * Description:
The current mode of operation of the MAC
                    entity.  'unknown' indicates that the current
                    duplex mode could not be determined.

                    Management control of the duplex mode is
                    accomplished through the MAU MIB.  When
                    an interface does not support autonegotiation,
                    or when autonegotiation is not enabled, the
                    duplex mode is controlled using
                    ifMauDefaultType.  When autonegotiation is
                    supported and enabled, duplex mode is controlled
                    using ifMauAutoNegAdvertisedBits.  In either
                    case, the currently operating duplex mode is
                    reflected both in this object and in ifMauType.

                    Note that this object provides redundant
                    information with ifMauType.  Normally, redundant
                    objects are discouraged.  However, in this
                    instance, it allows a management application to
                    determine the duplex status of an interface
                    without having to know every possible value of
                    ifMauType.  This was felt to be sufficiently
                    valuable to justify the redundancy.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 3/8. Values:  unknown(1), halfDuplex(2), fullDuplex(3)
 *
 * Its syntax is INTEGER (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 dot3StatsDuplexStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsDuplexStatus_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
dot3StatsDuplexStatus_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                          u_long * dot3StatsDuplexStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsDuplexStatus_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsDuplexStatus_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsDuplexStatus_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsRateControlAbility
 * dot3StatsRateControlAbility is subid 20 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.20
 * Description:
'true' for interfaces operating at speeds above
                    1000 Mb/s that support Rate Control through
                    lowering the average data rate of the MAC
                    sublayer, with frame granularity, and 'false'
                    otherwise.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (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 dot3StatsRateControlAbility data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsRateControlAbility_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
dot3StatsRateControlAbility_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                                u_long *
                                dot3StatsRateControlAbility_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsRateControlAbility_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsRateControlAbility_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsRateControlAbility_get */

/*---------------------------------------------------------------------
 * EtherLike-MIB::dot3StatsEntry.dot3StatsRateControlStatus
 * dot3StatsRateControlStatus is subid 21 of dot3StatsEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.10.7.2.1.21
 * Description:
The current Rate Control mode of operation of
                    the MAC sublayer of this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 3/8. Values:  rateControlOff(1), rateControlOn(2), unknown(3)
 *
 * Its syntax is INTEGER (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 dot3StatsRateControlStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param dot3StatsRateControlStatus_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
dot3StatsRateControlStatus_get(dot3StatsTable_rowreq_ctx * rowreq_ctx,
                               u_long * dot3StatsRateControlStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != dot3StatsRateControlStatus_val_ptr);


    DEBUGMSGTL(("verbose:dot3StatsTable:dot3StatsRateControlStatus_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* dot3StatsRateControlStatus_get */



/** @} */
